ftjam-2.5.2/0000755000424500003730000000000010441011175012405 5ustar dturnermhpsysftjam-2.5.2/builds/0000755000424500003730000000000010441011176013670 5ustar dturnermhpsysftjam-2.5.2/builds/unix/0000755000424500003730000000000010441011176014653 5ustar dturnermhpsysftjam-2.5.2/builds/unix/mkinstalldirs0000755000424500003730000000370410441006277017473 0ustar dturnermhpsys#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # End: # mkinstalldirs ends here ftjam-2.5.2/builds/unix/Makefile.in0000744000424500003730000000331510441006277016731 0ustar dturnermhpsys# Makefile to build Jam on Unix with the default compiler # (i.e. "cc" or "$CC" when defined) # # To use it, you must be in the top Jam source directory, # and call # # make # # the program "jam" will be created in the new # directory named "bin.unix" # CC = @CC@ TARGET = -o jam0 CFLAGS = @CFLAGS@ @XX_CFLAGS@ all: jam0 chmod a+w jambase.c ./jam0 include common.mk ############################################################################ # # The following is very specific and deals with installation # it implements "make install" and "make uninstall" for the # Jam executable. # # Note that for now, no documentation is installed with the executable # BUILD_DIR := bin.unix prefix := @prefix@ exec_prefix := @exec_prefix@ libdir := @libdir@ bindir := @bindir@ includedir := @includedir@ datadir := @datadir@ version_info := @version_info@ DELETE := @RMF@ DELDIR := @RMDIR@ # The Jam executable name. This is 'jam' on Unix, except Cygwin where # it will be "jam.exe". Yuckk.. # JAMEXE := jam@SUFEXE@ INSTALL := @INSTALL@ INSTALL_PROGRAM := @INSTALL_PROGRAM@ MKINSTALLDIRS := builds/unix/mkinstalldirs .PHONY: install uninstall check clean distclean # Unix installation and deinstallation targets. # Package managers can use the DESTDIR variable to force another # installation prefix # install: jam0 $(MKINSTALLDIRS) $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) $(BUILD_DIR)/$(JAMEXE) $(DESTDIR)$(bindir)/$(JAMEXE) uninstall: -$(DELETE) $(DESTDIR)$(bindir)/$(JAMEXE) clean: -$(DELETE) $(BUILD_DIR)/* -$(DELETE) jam0@SUFEXE@ distclean: clean -$(DELETE) config.log config.status Makefile check: @echo There is no validation suite for this package. ftjam-2.5.2/builds/unix/patchlevel.h.in0000744000424500003730000000027010441006300017551 0ustar dturnermhpsys/* Keep JAMVERSYM in sync with VERSION. */ /* It can be accessed as $(JAMVERSION) in the Jamfile. */ #define VERSION "@jam_version@" #define JAMVERSYM "JAMVERSION=@jam_version@" ftjam-2.5.2/builds/unix/configure.ac0000744000424500003730000000321710441006300017136 0ustar dturnermhpsysdnl This file is part of the FreeType Jam project. dnl See http://www.freetype.org/jam/ for more details dnl dnl Process this file with autoconf to produce a configure script. dnl AC_INIT AC_CONFIG_SRCDIR([Makefile.in]) dnl release version number dnl jam_version='2.5.2' AC_SUBST(jam_version) dnl checks for system type AC_CANONICAL_TARGET([]) dnl checks for programs AC_PROG_CC AC_PROG_CPP dnl get Compiler flags right. SUFEXE= XX_CFLAGS= case "$host" in *-cygwin*) CFLAGS= SUFEXE=.exe XX_CFLAGS="-D__cygwin__" ;; *-dec-osf*) CFLAGS= XX_CFLAGS="-std1 -g3" ;; esac AC_SUBST(XX_CFLAGS) AC_SUBST(SUFEXE) AC_CHECK_PROG(RMF, rm, rm -f) AC_CHECK_PROG(RMDIR, rmdir, rmdir) dnl Since this file will be finally moved to another directory we make dnl the path of the install script absolute. This small code snippet has dnl been taken from automake's `ylwrap' script. AC_PROG_INSTALL case "$INSTALL" in /*) ;; */*) INSTALL="`pwd`/$INSTALL" ;; esac AC_SUBST(CFLAGS) AC_SUBST(LDFLAGS) dnl we need to expand $bindir directly, instead of the default dnl '${exec_prefix}/bin', so perform a little Autoconf magic dnl this is really disgusting !! AC_DEFUN([AC_EXPAND_DIR], [$1=$2 $1=`( test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" eval echo \""[$]$1"\" )` ]) AC_EXPAND_DIR(my_bindir, $bindir) AC_SUBST(my_bindir) dnl create the Unix-specific Makefile and version information dnl AC_CONFIG_FILES([../../Makefile:Makefile.in ../../patchlevel.h:patchlevel.h.in ../../Jamrules:Jamrules.in]) AC_OUTPUT dnl end of configure.ac ftjam-2.5.2/builds/unix/Jamrules.in0000744000424500003730000000007510441006300016761 0ustar dturnermhpsys# final binary installation directory BINDIR = @my_bindir@ ; ftjam-2.5.2/builds/unix/config.guess0000744000424500003730000012025610441006301017171 0ustar dturnermhpsys#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003 Free Software Foundation, Inc. timestamp='2003-01-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; macppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mipseb-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:MicroBSD:*:*) echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE} exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. eval $set_cc_for_build cat <$dummy.s .data \$Lformat: .byte 37,100,45,37,120,10,0 # "%d-%x\n" .text .globl main .align 4 .ent main main: .frame \$30,16,\$26,0 ldgp \$29,0(\$27) .prologue 1 .long 0x47e03d80 # implver \$0 lda \$2,-1 .long 0x47e20c21 # amask \$2,\$1 lda \$16,\$Lformat mov \$0,\$17 not \$1,\$18 jsr \$26,printf ldgp \$29,0(\$26) mov 0,\$16 jsr \$26,exit .end main EOF $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null if test "$?" = 0 ; then case `$dummy` in 0-0) UNAME_MACHINE="alpha" ;; 1-0) UNAME_MACHINE="alphaev5" ;; 1-1) UNAME_MACHINE="alphaev56" ;; 1-101) UNAME_MACHINE="alphapca56" ;; 2-303) UNAME_MACHINE="alphaev6" ;; 2-307) UNAME_MACHINE="alphaev67" ;; 2-1307) UNAME_MACHINE="alphaev68" ;; 3-1307) UNAME_MACHINE="alphaev7" ;; esac fi echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; DRS?6000:UNIX_SV:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7 && exit 0 ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c \ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && exit 0 echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then # avoid double evaluation of $set_cc_for_build test -n "$CC_FOR_BUILD" || eval $set_cc_for_build if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; *:UNICOS/mp:*:*) echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) # Determine whether the default compiler uses glibc. eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #if __GLIBC__ >= 2 LIBC=gnu #else LIBC= #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; x86:Interix*:3*) echo i586-pc-interix3 exit 0 ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit 0 ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit 0 ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit 0 ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit 0 ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit 0 ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit 0 ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit 0 ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit 0 ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit 0 ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i*86:*:5:[78]*) case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit 0 ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) case `uname -p` in *86) UNAME_PROCESSOR=i686 ;; powerpc) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit 0 ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit 0 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit 0 ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit 0 ;; *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ftjam-2.5.2/builds/unix/config.sub0000744000424500003730000007210310441006301016631 0ustar dturnermhpsys#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003 Free Software Foundation, Inc. timestamp='2003-01-03' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k \ | m32r | m68000 | m68k | m88k | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | msp430 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ | clipper-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* \ | m32r-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | msp430-* \ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; mmix*) basic_machine=mmix-knuth os=-mmixware ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nv1) basic_machine=nv1-cray os=-unicosmp ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i686-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic4x | c4x*) basic_machine=tic4x-unknown os=-coff ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -microbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ftjam-2.5.2/builds/unix/install-sh0000755000424500003730000001645310441006301016662 0ustar dturnermhpsys#!/bin/sh # install - install a program, script, or datafile # This originally came from X11R5 (mit/util/scripts/install.sh). scriptversion=2003-01-17.15 # Copyright 1991 by the Massachusetts Institute of Technology # (FSF changes in the public domain.) # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename= transform_arg= instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= usage="Usage: $0 [OPTION]... SRCFILE DSTFILE or: $0 -d DIR1 DIR2... In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. In the second, create the directory path DIR. Options: -b=TRANSFORMBASENAME -c copy source (using $cpprog) instead of moving (using $mvprog). -d create directories instead of installing files. -g GROUP $chgrp installed files to GROUP. -m MODE $chmod installed files to MODE. -o USER $chown installed files to USER. -s strip installed files (using $stripprog). -t=TRANSFORM --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit 0;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; --version) echo "$0 $scriptversion"; exit 0;; *) if test -z "$src"; then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if test -z "$src"; then echo "$0: no input file specified." >&2 exit 1 fi if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then instcmd=: chmodcmd= else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst"; then echo "$0: no destination specified." >&2 exit 1 fi # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then dst=$dst/`basename "$src"` fi fi ## this sed command emulates the dirname command dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # (this part is taken from Noah Friedman's mkinstalldirs script.) # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift test -d "$pathcomp" || $mkdirprog "$pathcomp" pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $instcmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else # If we're going to rename the final executable, determine the name now. if test -z "$transformarg"; then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename \ | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename. test -z "$dstfile" && dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/#inst.$$# rmtmp=$dstdir/#rm.$$# # Trap to clean up those temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now remove or move aside any old file at destination location. We # try this two ways since rm can't unlink itself on some systems and # the destination file might be busy for other reasons. In this case, # the final cleanup might fail but the new file should still install # successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: ftjam-2.5.2/builds/unix/configure0000755000424500003730000032600310441007105016563 0ustar dturnermhpsys#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="Makefile.in" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS jam_version build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP XX_CFLAGS SUFEXE RMF RMDIR INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA my_bindir LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. 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' 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 ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # 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_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$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 ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) 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 | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$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 | -n) 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_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } 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 "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # 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_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` 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 "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # 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 <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # 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 # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # 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 "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu jam_version='2.5.2' 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 elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Make sure we can run config.sub. $ac_config_sub sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 echo "$as_me: error: cannot run $ac_config_sub" >&2;} { (exit 1); exit 1; }; } echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6 if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_build_alias=$build_alias test -z "$ac_cv_build_alias" && ac_cv_build_alias=`$ac_config_guess` test -z "$ac_cv_build_alias" && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6 build=$ac_cv_build build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6 if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_host_alias=$host_alias test -z "$ac_cv_host_alias" && ac_cv_host_alias=$ac_cv_build_alias ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6 host=$ac_cv_host host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$as_me:$LINENO: checking target system type" >&5 echo $ECHO_N "checking target system type... $ECHO_C" >&6 if test "${ac_cv_target+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_target_alias=$target_alias test "x$ac_cv_target_alias" = "x" && ac_cv_target_alias=$ac_cv_host_alias ac_cv_target=`$ac_config_sub $ac_cv_target_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_target" >&5 echo "${ECHO_T}$ac_cv_target" >&6 target=$ac_cv_target target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi 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 "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done 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 $# != 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 ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&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 "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu SUFEXE= XX_CFLAGS= case "$host" in *-cygwin*) CFLAGS= SUFEXE=.exe XX_CFLAGS="-D__cygwin__" ;; *-dec-osf*) CFLAGS= XX_CFLAGS="-std1 -g3" ;; esac # Extract the first word of "rm", so it can be a program name with args. set dummy rm; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RMF+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RMF"; then ac_cv_prog_RMF="$RMF" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RMF="rm -f" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RMF=$ac_cv_prog_RMF if test -n "$RMF"; then echo "$as_me:$LINENO: result: $RMF" >&5 echo "${ECHO_T}$RMF" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi # Extract the first word of "rmdir", so it can be a program name with args. set dummy rmdir; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RMDIR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RMDIR"; then ac_cv_prog_RMDIR="$RMDIR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RMDIR="rmdir" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RMDIR=$ac_cv_prog_RMDIR if test -n "$RMDIR"; then echo "$as_me:$LINENO: result: $RMDIR" >&5 echo "${ECHO_T}$RMDIR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi # 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 # AmigaOS /C/install, which installs bootblocks on floppy discs # 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" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /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 for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done 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 "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&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}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' case "$INSTALL" in /*) ;; */*) INSTALL="`pwd`/$INSTALL" ;; esac my_bindir=$bindir my_bindir=`( test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" eval echo \""$my_bindir"\" )` ac_config_files="$ac_config_files ../../Makefile:Makefile.in ../../patchlevel.h:patchlevel.h.in ../../Jamrules:Jamrules.in" cat >confcache <<\_ACEOF # 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, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # 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 \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "../../Makefile" ) CONFIG_FILES="$CONFIG_FILES ../../Makefile:Makefile.in" ;; "../../patchlevel.h" ) CONFIG_FILES="$CONFIG_FILES ../../patchlevel.h:patchlevel.h.in" ;; "../../Jamrules" ) CONFIG_FILES="$CONFIG_FILES ../../Jamrules:Jamrules.in" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@jam_version@,$jam_version,;t t s,@build@,$build,;t t s,@build_cpu@,$build_cpu,;t t s,@build_vendor@,$build_vendor,;t t s,@build_os@,$build_os,;t t s,@host@,$host,;t t s,@host_cpu@,$host_cpu,;t t s,@host_vendor@,$host_vendor,;t t s,@host_os@,$host_os,;t t s,@target@,$target,;t t s,@target_cpu@,$target_cpu,;t t s,@target_vendor@,$target_vendor,;t t s,@target_os@,$target_os,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@CPP@,$CPP,;t t s,@XX_CFLAGS@,$XX_CFLAGS,;t t s,@SUFEXE@,$SUFEXE,;t t s,@RMF@,$RMF,;t t s,@RMDIR@,$RMDIR,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@my_bindir@,$my_bindir,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # 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_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # 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" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi ftjam-2.5.2/builds/win32-borlandc.mk0000744000424500003730000000066610441006303016752 0ustar dturnermhpsys# Makefile to build Jam with Borland C on Win32 systems # # To use it, you must be in the top Jam source directory, # have the Borland C++ compiler in your current path, and # call: # # make -fbuilds\win32-borlandc.mk # # the program "jam.exe" will be created in the new # directory named "bin.ntx86" # CC = bcc32 TARGET = -ejam0 CFLAGS = /DNT -w- -q all: jam0 attrib -r jambase.c jam0 !include common.mk ftjam-2.5.2/builds/win32-gcc.mk0000744000424500003730000000067410441006303015721 0ustar dturnermhpsys# Makefile to build Jam with Mingw GCC on Win32 systems # # To use it, you must be in the top Jam source directory, # have GCC compiler in your current path, and call: # # set JAM_TOOLSET=MINGW # make -f builds/win32-gcc.mk # # the program "jam.exe" will be created in the new # directory named "bin.ntx86" # CC = gcc TARGET = -o jam0.exe CFLAGS = -DNT all: jam0 attrib -r jambase.c jam0 include common.mk ftjam-2.5.2/builds/win32-cygwin.mk0000744000424500003730000000125210441006303016456 0ustar dturnermhpsys# Makefile to build Jam with Cygwin on Win32 systems # # To use it, you must be in the top Jam source directory, # have GCC compiler in your current path, and call: # # make -f builds/win32-cygwin.mk # # the program "jam.exe" will be created in the new # directory named "bin.cygwinx86" # # note that the resulting executable will only be usable # under Cygwin, since it will output Unix commands. I.e. # it will _not_ use JAM_TOOLSET and won't be able to compile # with Mingw, Visual C++, Borland C++ and other native # Win32 compilers # CC = gcc TARGET = -o jam0.exe CFLAGS = -D__cygwin__ all: jam0 attrib -r jambase.c jam0 include common.mk ftjam-2.5.2/builds/win32-visualc.mk0000744000424500003730000000071610441006304016631 0ustar dturnermhpsys# Makefile to build jam with Visual C on Win32 systems # # To use it, you must be in the top Jam source directory, # have the compiler in your path, and call: # # nmake -f builds\win32-visualc.mk # # the program "jam.exe" will be created in a new directory # named "bin.ntx86" # CC = cl /nologo CFLAGS = -DNT TARGET = /Fejam0 LINKLIBS = oldnames.lib kernel32.lib libc.lib all: jam0 attrib -r jambase.c jam0 !include common.mk ftjam-2.5.2/builds/win32-dmars.mk0000744000424500003730000000076510441006304016275 0ustar dturnermhpsys# Makefile to build jam with Digital Mars C/C++ on Win32 systems # # To use it, you must be in the top Jam source directory, # have the compiler in your path, and call: # # set JAM_TOOLSET=DIGITALMARS # make -f builds\win32-dmars.mk # # the program "jam.exe" will be created in a new directory # named "bin.ntx86" # CC = dmc CFLAGS = -DNT TARGET = -o jam0.exe #LINKLIBS = oldnames.lib kernel32.lib libc.lib all: jam0 attrib -r jambase.c jam0 include common.mk ftjam-2.5.2/variable.c0000744000424500003730000001557210441006330014346 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * variable.c - handle jam multi-element variables * * External routines: * * var_defines() - load a bunch of variable=value settings * var_string() - expand a string with variables in it * var_get() - get value of a user defined symbol * var_set() - set a variable in jam's user defined symbol table * var_swap() - swap a variable's value with the given one * var_done() - free variable tables * * Internal routines: * * var_enter() - make new var symbol table entry, returning var ptr * var_dump() - dump a variable to stdout * * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 08/23/94 (seiwald) - Support for '+=' (append to variable) * 01/22/95 (seiwald) - split environment variables at blanks or :'s * 05/10/95 (seiwald) - split path variables at SPLITPATH (not :) * 09/11/00 (seiwald) - defunct var_list() removed * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "lists.h" # include "parse.h" # include "variable.h" # include "expand.h" # include "hash.h" # include "newstr.h" static struct hash *varhash = 0; /* * VARIABLE - a user defined multi-value variable */ typedef struct _variable VARIABLE ; struct _variable { const char *symbol; LIST *value; } ; static VARIABLE *var_enter( const char *symbol ); static void var_dump( const char *symbol, LIST *value, const char *what ); /* * var_defines() - load a bunch of variable=value settings * * If variable name ends in PATH, split value at :'s. * Otherwise, split at blanks. */ void var_defines( const char **e ) { for( ; *e; e++ ) { const char *val; /* Just say "no": windows defines this in the env, */ /* but we don't want it to override our notion of OS. */ if( !strcmp( *e, "OS=Windows_NT" ) ) continue; /* Just say "no": on Unix, variables can contain function * definitions. their value begins with "()" */ if( ( val = strchr( *e, '=' ) ) && val[1] == '(' && val[2] == ')' ) continue; # ifdef OS_MAC /* On the mac (MPW), the var=val is actually var\0val */ /* Think different. */ if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) ) # else if( val = strchr( *e, '=' ) ) # endif { LIST *l = L0; const char *pp, *p; # ifdef OS_MAC char split = ','; # else char split = ' '; # endif char buf[ MAXSYM ]; /* Split *PATH at :'s, not spaces */ if( val - 4 >= *e ) { if( !strncmp( val - 4, "PATH", 4 ) || !strncmp( val - 4, "Path", 4 ) || !strncmp( val - 4, "path", 4 ) ) split = SPLITPATH; } /* Do the split */ for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 ) { int len = p - pp; if ( len >= sizeof(buf) ) len = sizeof(buf)-1; strncpy( buf, pp, len ); buf[ len ] = '\0'; l = list_new( l, buf, 0 ); } l = list_new( l, pp, 0 ); /* Get name */ strncpy( buf, *e, val - *e ); buf[ val - *e ] = '\0'; var_set( buf, l, VAR_SET ); } } } /* * var_string() - expand a string with variables in it * * Copies in to out; doesn't modify targets & sources. */ int var_string( const char *in, char *out, int outsize, LOL *lol ) { char *out0 = out; char *oute = out + outsize - 1; while( *in ) { char *lastword; int dollar = 0; /* Copy white space */ while( isspace( *in ) ) { if( out >= oute ) return -1; *out++ = *in++; } lastword = out; /* Copy non-white space, watching for variables */ while( *in && !isspace( *in ) ) { if( out >= oute ) return -1; if( in[0] == '$' && in[1] == '(' ) dollar++; *out++ = *in++; } /* If a variable encountered, expand it and and embed the */ /* space-separated members of the list in the output. */ if( dollar ) { LIST *l = var_expand( L0, lastword, out, lol, 0 ); out = lastword; while( l ) { int so = strlen( l->string ); if( out + so >= oute ) return -1; strcpy( out, l->string ); out += so; /* Separate with space */ if( l = list_next( l ) ) *out++ = ' '; } list_free( l ); } } if( out >= oute ) return -1; *out++ = '\0'; return out - out0; } /* * var_get() - get value of a user defined symbol * * Returns NULL if symbol unset. */ LIST * var_get( const char *symbol ) { VARIABLE var, *v = &var; v->symbol = symbol; if( varhash && hashcheck( varhash, (HASHDATA **)&v ) ) { if( DEBUG_VARGET ) var_dump( v->symbol, v->value, "get" ); return v->value; } return 0; } /* * var_set() - set a variable in jam's user defined symbol table * * 'flag' controls the relationship between new and old values of * the variable: SET replaces the old with the new; APPEND appends * the new to the old; DEFAULT only uses the new if the variable * was previously unset. * * Copies symbol. Takes ownership of value. */ void var_set( const char *symbol, LIST *value, int flag ) { VARIABLE *v = var_enter( symbol ); if( DEBUG_VARSET ) var_dump( symbol, value, "set" ); switch( flag ) { case VAR_SET: /* Replace value */ list_free( v->value ); v->value = value; break; case VAR_APPEND: /* Append value */ v->value = list_append( v->value, value ); break; case VAR_DEFAULT: /* Set only if unset */ if( !v->value ) v->value = value; else list_free( value ); break; } } /* * var_swap() - swap a variable's value with the given one */ LIST * var_swap( const char *symbol, LIST *value ) { VARIABLE *v = var_enter( symbol ); LIST *oldvalue = v->value; if( DEBUG_VARSET ) var_dump( symbol, value, "set" ); v->value = value; return oldvalue; } /* * var_enter() - make new var symbol table entry, returning var ptr */ static VARIABLE * var_enter( const char *symbol ) { VARIABLE var, *v = &var; if( !varhash ) varhash = hashinit( sizeof( VARIABLE ), "variables" ); v->symbol = symbol; v->value = 0; if( hashenter( varhash, (HASHDATA **)&v ) ) v->symbol = newstr( symbol ); /* never freed */ return v; } /* * var_dump() - dump a variable to stdout */ static void var_dump( const char *symbol, LIST *value, const char *what ) { printf( "%s %s = ", what, symbol ); list_print( value ); printf( "\n" ); } /* * var_done() - free variable tables */ void var_done() { hashdone( varhash ); } ftjam-2.5.2/jamgramtab.h0000744000424500003730000000204310441006320014657 0ustar dturnermhpsys { "<", _LANGLE_t }, { "<=", _LANGLE_EQUALS_t }, { "=", _EQUALS_t }, { ">", _RANGLE_t }, { ">=", _RANGLE_EQUALS_t }, { "|", _BAR_t }, { "||", _BARBAR_t }, { ";", _SEMIC_t }, { ":", _COLON_t }, { "!", _BANG_t }, { "!=", _BANG_EQUALS_t }, { "?=", _QUESTION_EQUALS_t }, { "(", _LPAREN_t }, { ")", _RPAREN_t }, { "[", _LBRACKET_t }, { "]", _RBRACKET_t }, { "{", _LBRACE_t }, { "}", _RBRACE_t }, { "&", _AMPER_t }, { "&&", _AMPERAMPER_t }, { "+=", _PLUS_EQUALS_t }, { "actions", ACTIONS_t }, { "bind", BIND_t }, { "break", BREAK_t }, { "case", CASE_t }, { "continue", CONTINUE_t }, { "default", DEFAULT_t }, { "else", ELSE_t }, { "existing", EXISTING_t }, { "for", FOR_t }, { "if", IF_t }, { "ignore", IGNORE_t }, { "in", IN_t }, { "include", INCLUDE_t }, { "local", LOCAL_t }, { "maxline", MAXLINE_t }, { "on", ON_t }, { "piecemeal", PIECEMEAL_t }, { "quietly", QUIETLY_t }, { "return", RETURN_t }, { "rule", RULE_t }, { "switch", SWITCH_t }, { "together", TOGETHER_t }, { "updated", UPDATED_t }, { "while", WHILE_t }, ftjam-2.5.2/execvms.c0000744000424500003730000000674710441006321014237 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * execvms.c - execute a shell script, ala VMS * * The approach is this: * * If the command is a single line, and shorter than WRTLEN (what we * believe to be the maximum line length), we just system() it. * * If the command is multi-line, or longer than WRTLEN, we write the * command block to a temp file, splitting long lines (using "-" at * the end of the line to indicate contiuation), and then source that * temp file. We use special logic to make sure we don't continue in * the middle of a quoted string. * * 05/04/94 (seiwald) - async multiprocess interface; noop on VMS * 12/20/96 (seiwald) - rewritten to handle multi-line commands well * 01/14/96 (seiwald) - don't put -'s between "'s * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C */ # include "jam.h" # include "lists.h" # include "execcmd.h" # ifdef OS_VMS #include #include #include #include #include #include #include #include #define WRTLEN 240 #define MIN( a, b ) ((a) < (b) ? (a) : (b)) /* 1 for the @ and 4 for the .com */ char tempnambuf[ L_tmpnam + 1 + 4 ] = {0}; void execcmd( char *string, void (*func)( void *closure, int status ), void *closure, LIST *shell ) { char *s, *e, *p; int rstat = EXEC_CMD_OK; int status; /* See if string is more than one line */ /* discounting leading/trailing white space */ for( s = string; *s && isspace( *s ); s++ ) ; e = p = strchr( s, '\n' ); while( p && isspace( *p ) ) ++p; /* If multi line or long, write to com file. */ /* Otherwise, exec directly. */ if( p && *p || e - s > WRTLEN ) { FILE *f; /* Create temp file invocation "@sys$scratch:tempfile.com" */ if( !*tempnambuf ) { tempnambuf[0] = '@'; (void)tmpnam( tempnambuf + 1 ); strcat( tempnambuf, ".com" ); } /* Open tempfile */ if( !( f = fopen( tempnambuf + 1, "w" ) ) ) { printf( "can't open command file\n" ); (*func)( closure, EXEC_CMD_FAIL ); return; } /* For each line of the string */ while( *string ) { char *s = strchr( string, '\n' ); int len = s ? s + 1 - string : strlen( string ); fputc( '$', f ); /* For each chunk of a line that needs to be split */ while( len > 0 ) { char *q = string; char *qe = string + MIN( len, WRTLEN ); char *qq = q; int quote = 0; /* Look for matching "'s */ for( ; q < qe; q++ ) if( *q == '"' && ( quote = !quote ) ) qq = q; /* Back up to opening quote, if in one */ if( quote ) q = qq; fwrite( string, ( q - string ), 1, f ); len -= ( q - string ); string = q; if( len ) { fputc( '-', f ); fputc( '\n', f ); } } } fclose( f ); status = system( tempnambuf ) & 0x07; unlink( tempnambuf + 1 ); } else { /* Execute single line command */ /* Strip trailing newline before execing */ if( e ) *e = 0; status = system( s ) & 0x07; } /* Fail for error or fatal error */ /* OK on OK, warning, or info exit */ if( status == 2 || status == 4 ) rstat = EXEC_CMD_FAIL; (*func)( closure, rstat ); } int execwait() { return 0; } # endif /* VMS */ ftjam-2.5.2/Build.mpw0000744000424500003730000000647110441006321014177 0ustar dturnermhpsys# This line must be set manually to the CodeWarrior Pro 5 installation. # Good luck! set CW "malyn_apps:CodeWarrior Pro 5:MetroWerks CodeWarrior" set -e MWCincludes "{CW}:MacOS Support:Universal:Interfaces:CIncludes,{CW}:MacOS Support:OpenTransport:Open Tpt Client Developer:Includes:CIncludes,{CW}:MacOS Support:Headers:Apple MPW,{CW}:MSL:MSL_C:MSL_Common:Include,{CW}:MSL:MSL_C++:MSL_Common:Include,{CW}:MSL:MSL_C:MSL_MacOS:Include" mwcppc -o :bin.mac:command.o -nomapcr -w off command.c mwcppc -o :bin.mac:compile.o -nomapcr -w off compile.c mwcppc -o :bin.mac:execmac.o -nomapcr -w off execmac.c mwcppc -o :bin.mac:filemac.o -nomapcr -w off filemac.c mwcppc -o :bin.mac:pathmac.o -nomapcr -w off pathmac.c mwcppc -o :bin.mac:jamgram.o -nomapcr -w off jamgram.c mwcppc -o :bin.mac:expand.o -nomapcr -w off expand.c mwcppc -o :bin.mac:glob.o -nomapcr -w off glob.c mwcppc -o :bin.mac:hash.o -nomapcr -w off hash.c mwcppc -o :bin.mac:headers.o -nomapcr -w off headers.c mwcppc -o :bin.mac:lists.o -nomapcr -w off lists.c mwcppc -o :bin.mac:make.o -nomapcr -w off make.c mwcppc -o :bin.mac:make1.o -nomapcr -w off make1.c mwcppc -o :bin.mac:newstr.o -nomapcr -w off newstr.c mwcppc -o :bin.mac:option.o -nomapcr -w off option.c mwcppc -o :bin.mac:parse.o -nomapcr -w off parse.c mwcppc -o :bin.mac:regexp.o -nomapcr -w off regexp.c mwcppc -o :bin.mac:rules.o -nomapcr -w off rules.c mwcppc -o :bin.mac:scan.o -nomapcr -w off scan.c mwcppc -o :bin.mac:search.o -nomapcr -w off search.c mwcppc -o :bin.mac:timestamp.o -nomapcr -w off timestamp.c mwcppc -o :bin.mac:variable.o -nomapcr -w off variable.c mwlinkppc -library -o :bin.mac:libjam.lib :bin.mac:command.o :bin.mac:compile.o :bin.mac:execmac.o :bin.mac:filemac.o :bin.mac:pathmac.o :bin.mac:jamgram.o :bin.mac:expand.o :bin.mac:glob.o :bin.mac:hash.o :bin.mac:headers.o :bin.mac:lists.o :bin.mac:make.o :bin.mac:make1.o :bin.mac:newstr.o :bin.mac:option.o :bin.mac:parse.o :bin.mac:regexp.o :bin.mac:rules.o :bin.mac:scan.o :bin.mac:search.o :bin.mac:timestamp.o :bin.mac:variable.o mwcppc -o :bin.mac:mkjambase.o -nomapcr -w off mkjambase.c mwlinkppc -o :bin.mac:mkjambase -mpwtool -warn :bin.mac:mkjambase.o "{CW}:MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" "{CW}:MacOS Support:Universal:Libraries:StubLibraries:ThreadsLib" "{CW}:MacOS Support:Universal:Libraries:StubLibraries:Mathlib" "{CW}:MacOS Support:Libraries:Apple MPW PPC:PPCToolLibs.o" "{CW}:MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" "{CW}:MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib" mwcppc -o :bin.mac:jam.o -nomapcr -w off jam.c :bin.mac:mkjambase jambase.c Jambase mwcppc -o :bin.mac:jambase.o -nomapcr -w off jambase.c mwlinkppc -o :bin.mac:jam -mpwtool -warn :bin.mac:jam.o :bin.mac:jambase.o :bin.mac:libjam.lib "{CW}:MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" "{CW}:MacOS Support:Universal:Libraries:StubLibraries:ThreadsLib" "{CW}:MacOS Support:Universal:Libraries:StubLibraries:Mathlib" "{CW}:MacOS Support:Libraries:Apple MPW PPC:PPCToolLibs.o" "{CW}:MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" "{CW}:MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib" ftjam-2.5.2/filent.c0000744000424500003730000001625710441006321014043 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * filent.c - scan directories and archives on NT * * External routines: * * file_dirscan() - scan a directory for files * file_time() - get timestamp of file, if not done by file_dirscan() * file_archscan() - scan an archive for files * * File_dirscan() and file_archscan() call back a caller provided function * for each file found. A flag to this callback function lets file_dirscan() * and file_archscan() indicate that a timestamp is being provided with the * file. If file_dirscan() or file_archscan() do not provide the file's * timestamp, interested parties may later call file_time(). * * 07/10/95 (taylor) Findfirst() returns the first file on NT. * 05/03/96 (seiwald) split apart into pathnt.c * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C * 10/03/00 (anton) - Porting for Borland C++ 5.5 * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan * 11/04/02 (seiwald) - const-ing for string literals * 01/23/03 (seiwald) - long long handles for NT IA64 */ # include "jam.h" # include "filesys.h" # include "pathsys.h" # ifdef OS_NT # ifdef __BORLANDC__ # if __BORLANDC__ < 0x550 # include # include # endif # undef PATHNAME /* cpp namespace collision */ # define _finddata_t ffblk # endif # include # include /* * file_dirscan() - scan a directory for files */ # ifdef _M_IA64 # define FINDTYPE long long # else # define FINDTYPE long # endif void file_dirscan( const char *dir, scanback func, void *closure ) { PATHNAME f; char filespec[ MAXJPATH ]; char filename[ MAXJPATH ]; FINDTYPE handle; int ret; struct _finddata_t finfo[1]; /* First enter directory itself */ memset( (char *)&f, '\0', sizeof( f ) ); f.f_dir.ptr = dir; f.f_dir.len = strlen(dir); dir = *dir ? dir : "."; /* Special case \ or d:\ : enter it */ if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' ) (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' ) (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); /* Now enter contents of directory */ sprintf( filespec, "%s/*", dir ); if( DEBUG_BINDSCAN ) printf( "scan directory %s\n", dir ); # if defined(__BORLANDC__) && __BORLANDC__ < 0x550 if ( ret = findfirst( filespec, finfo, FA_NORMAL | FA_DIREC ) ) return; while( !ret ) { time_t time_write = finfo->ff_fdate; time_write = (time_write << 16) | finfo->ff_ftime; f.f_base.ptr = finfo->ff_name; f.f_base.len = strlen( finfo->ff_name ); path_build( &f, filename ); (*func)( closure, filename, 1 /* stat()'ed */, time_write ); ret = findnext( finfo ); } # else handle = _findfirst( filespec, finfo ); if( ret = ( handle == (FINDTYPE)(-1) ) ) return; while( !ret ) { f.f_base.ptr = finfo->name; f.f_base.len = strlen( finfo->name ); path_build( &f, filename, 0 ); (*func)( closure, filename, 1 /* stat()'ed */, finfo->time_write ); ret = _findnext( handle, finfo ); } _findclose( handle ); # endif } /* * file_time() - get timestamp of file, if not done by file_dirscan() */ int file_time( const char *filename, time_t *time ) { /* On NT this is called only for C:/ */ struct stat statbuf; if( stat( filename, &statbuf ) < 0 ) return -1; *time = statbuf.st_mtime; return 0; } /* * file_archscan() - scan an archive for files */ /* Straight from SunOS */ #define ARMAG "!\n" #define SARMAG 8 #define ARFMAG "`\n" struct ar_hdr { char ar_name[16]; char ar_date[12]; char ar_uid[6]; char ar_gid[6]; char ar_mode[8]; char ar_size[10]; char ar_fmag[2]; }; # define SARFMAG 2 # define SARHDR sizeof( struct ar_hdr ) void file_archscan( const char *archive, scanback func, void *closure ) { struct ar_hdr ar_hdr; char *string_table = 0; long string_table_len = 0; char buf[ MAXJPATH ]; long offset; int fd; if( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 ) return; if( read( fd, buf, SARMAG ) != SARMAG || strncmp( ARMAG, buf, SARMAG ) ) { close( fd ); return; } offset = SARMAG; if( DEBUG_BINDSCAN ) printf( "scan archive %s\n", archive ); while( read( fd, &ar_hdr, SARHDR ) == SARHDR && !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) ) { long lar_date; long lar_size; char *name = 0; char *endname; char *c; sscanf( ar_hdr.ar_date, "%ld", &lar_date ); sscanf( ar_hdr.ar_size, "%ld", &lar_size ); lar_size = ( lar_size + 1 ) & ~1; if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] == '/' ) { /* this is the "string table" entry of the symbol table, ** which holds strings of filenames that are longer than ** 15 characters (ie. don't fit into a ar_name */ string_table = malloc(lar_size); if (read(fd, string_table, lar_size) != lar_size) printf("error reading string table\n"); string_table_len = lar_size; goto Next; } else if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] != ' ') { /* Long filenames are recognized by "/nnnn" where nnnn is ** the offset of the string in the string table represented ** in ASCII decimals. ** ** however, the name end with 0 or '/', depending on ** the librarian used to generate them (0 for Mingw, * '/' for Visual C++) */ long off = atoi( ar_hdr.ar_name+1 ); if ( off < 0 || off > string_table_len ) goto Next; name = string_table + off; for ( ; off < string_table_len; off++ ) { int c = string_table[off]; if ( c == 0 || c == '/' ) break; } endname = string_table + off; } else { /* normal name */ long off; name = ar_hdr.ar_name; for ( off = 0; off < sizeof( ar_hdr.ar_name ); off++ ) { if ( name[off] == '/' || name[off] == 0 ) /* not strictly required, but safe */ break; } endname = name + off; } /* strip trailing space, slashes, and backslashes */ while( endname > name ) { int c = endname[-1]; if ( c != ' ' && c != '\\' && c != '/' ) break; endname--; } /* strip leading directory names, since they're present in * files generated by the Microsoft Librarian */ { char* p = name; for ( ; p < endname; p++ ) { if ( *p == '\\' ) name = p+1; } } /* don't count empty entries */ if ( name >= endname ) goto Next; /* create name */ sprintf( buf, "%s(%.*s)", archive, endname-name, name ); (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date ); Next: offset += SARHDR + lar_size; lseek( fd, offset, 0 ); } close( fd ); } # endif /* NT */ ftjam-2.5.2/hash.c0000744000424500003730000001266210441006322013502 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * hash.c - simple in-memory hashing routines * * External routines: * * hashinit() - initialize a hash table, returning a handle * hashitem() - find a record in the table, and optionally enter a new one * hashdone() - free a hash table, given its handle * * Internal routines: * * hashrehash() - resize and rebuild hp->tab, the hash table * * 4/29/93 - ensure ITEM's are aligned * 11/04/02 (seiwald) - const-ing for string literals * 01/31/02 (seiwald) - keyval now unsigned (cray-ziness) */ # include "jam.h" # include "hash.h" /* Header attached to all data items entered into a hash table. */ struct hashhdr { struct item *next; unsigned int keyval; /* for quick comparisons */ } ; /* This structure overlays the one handed to hashenter(). */ /* It's actual size is given to hashinit(). */ struct hashdata { char *key; /* rest of user data */ } ; typedef struct item { struct hashhdr hdr; struct hashdata data; } ITEM ; # define MAX_LISTS 32 struct hash { /* * the hash table, just an array of item pointers */ struct { int nel; ITEM **base; } tab; int bloat; /* tab.nel / items.nel */ int inel; /* initial number of elements */ /* * the array of records, maintained by these routines * essentially a microallocator */ struct { int more; /* how many more ITEMs fit in lists[ list ] */ char *next; /* where to put more ITEMs in lists[ list ] */ int datalen; /* length of records in this hash table */ int size; /* sizeof( ITEM ) + aligned datalen */ int nel; /* total ITEMs held by all lists[] */ int list; /* index into lists[] */ struct { int nel; /* total ITEMs held by this list */ char *base; /* base of ITEMs array */ } lists[ MAX_LISTS ]; } items; const char *name; /* just for hashstats() */ } ; static void hashrehash( struct hash *hp ); static void hashstat( struct hash *hp ); /* * hashitem() - find a record in the table, and optionally enter a new one */ int hashitem( register struct hash *hp, HASHDATA **data, int enter ) { ITEM **base; register ITEM *i; unsigned char *b = (unsigned char *)(*data)->key; unsigned int keyval; if( enter && !hp->items.more ) hashrehash( hp ); if( !enter && !hp->items.nel ) return 0; keyval = *b; while( *b ) keyval = keyval * 2147059363 + *b++; base = hp->tab.base + ( keyval % hp->tab.nel ); for( i = *base; i; i = i->hdr.next ) if( keyval == i->hdr.keyval && !strcmp( i->data.key, (*data)->key ) ) { *data = &i->data; return !0; } if( enter ) { i = (ITEM *)hp->items.next; hp->items.next += hp->items.size; hp->items.more--; memcpy( (char *)&i->data, (char *)*data, hp->items.datalen ); i->hdr.keyval = keyval; i->hdr.next = *base; *base = i; *data = &i->data; } return 0; } /* * hashrehash() - resize and rebuild hp->tab, the hash table */ static void hashrehash( register struct hash *hp ) { int i = ++hp->items.list; hp->items.more = i ? 2 * hp->items.nel : hp->inel; hp->items.next = (char *)malloc( hp->items.more * hp->items.size ); hp->items.lists[i].nel = hp->items.more; hp->items.lists[i].base = hp->items.next; hp->items.nel += hp->items.more; if( hp->tab.base ) free( (char *)hp->tab.base ); hp->tab.nel = hp->items.nel * hp->bloat; hp->tab.base = (ITEM **)malloc( hp->tab.nel * sizeof(ITEM **) ); memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) ); for( i = 0; i < hp->items.list; i++ ) { int nel = hp->items.lists[i].nel; char *next = hp->items.lists[i].base; for( ; nel--; next += hp->items.size ) { register ITEM *i = (ITEM *)next; ITEM **ip = hp->tab.base + i->hdr.keyval % hp->tab.nel; i->hdr.next = *ip; *ip = i; } } } /* --- */ # define ALIGNED(x) ( ( x + sizeof( ITEM ) - 1 ) & ~( sizeof( ITEM ) - 1 ) ) /* * hashinit() - initialize a hash table, returning a handle */ struct hash * hashinit( int datalen, const char *name ) { struct hash *hp = (struct hash *)malloc( sizeof( *hp ) ); hp->bloat = 3; hp->tab.nel = 0; hp->tab.base = (ITEM **)0; hp->items.more = 0; hp->items.datalen = datalen; hp->items.size = sizeof( struct hashhdr ) + ALIGNED( datalen ); hp->items.list = -1; hp->items.nel = 0; hp->inel = 11; hp->name = name; return hp; } /* * hashdone() - free a hash table, given its handle */ void hashdone( struct hash *hp ) { int i; if( !hp ) return; if( DEBUG_MEM ) hashstat( hp ); if( hp->tab.base ) free( (char *)hp->tab.base ); for( i = 0; i <= hp->items.list; i++ ) free( hp->items.lists[i].base ); free( (char *)hp ); } /* ---- */ static void hashstat( struct hash *hp ) { ITEM **tab = hp->tab.base; int nel = hp->tab.nel; int count = 0; int sets = 0; int run = ( tab[ nel - 1 ] != (ITEM *)0 ); int i, here; for( i = nel; i > 0; i-- ) { if( here = ( *tab++ != (ITEM *)0 ) ) count++; if( here && !run ) sets++; run = here; } printf( "%s table: %d+%d+%d (%dK+%dK) items+table+hash, %f density\n", hp->name, count, hp->items.nel, hp->tab.nel, hp->items.nel * hp->items.size / 1024, hp->tab.nel * sizeof( ITEM ** ) / 1024, (float)count / (float)sets ); } ftjam-2.5.2/Jambase.html0000744000424500003730000006462210441006322014646 0ustar dturnermhpsys Jambase Reference
Jam

Jambase Reference

Jambase is a base set of Jam rules which provide roughly make(1)-like functionality for jam, the Jam executable program. This document, which started out as the Jambase(5) man page, is a reference guide to the rules, pseudotargets, and variables defined in Jambase for use in Jamfiles.

For further information see:

Jam documentation and source are available from the Perforce Public Depot. For detailed information about any of the rules summarized below, see the Jambase file itself.


Jambase Rules

As obj.o : source.s ;

Assemble the file source.s. Called by the Object rule.
Bulk directory : sources ;
Copies sources into directory.
Cc object : source ;
Compile the file source into object, using the C compiler $(CC), its flags $(CCFLAGS) and $(OPTIM), and the header file directories $(HDRS). Called by the Object rule.
C++ obj.o : source.cc ;
Compile the C++ source file source.cc. Called by the Object rule.
Chmod target ;
(Unix and VMS only.) Change file permissions on target to target-specific $(MODE) value set by Link, File, Install*, and Shell rules.
Clean clean : targets ;
Removes existing targets when clean is built. clean is not a dependency of all, and must be built explicitly for targets to be removed.
FDefines defines ;
Expands a list of definitions into a list of compiler (or preprocessor) switches (such as -Dsymbol=val on Unix) to pass the definitions.
File target : source ;
Copies source into target.
FIncludes dirs ;
Expands a list of directories into a list of compiler (or preprocessor) switches (such as -Idir on Unix) to add the directories to the header inclusion search path.
Fortran obj.o : source.f ;
Compile the Fortran source file source.f. Called by the Object rule.
FQuote files ;
Returns each of files suitably quoted so as to hide shell metacharacters (such as whitespace and filename matching wildcards) from the shell.

GenFile target : image sources ;

Runs the command "image target sources" to create target from sources and image. (where image is an executable built by the Main rule.)
HardLink target : source ;
Makes target a hard link to source, if it isn't one already. (Unix only.)
HdrRule source : headers ;
Arranges the proper dependencies when the file source includes the files headers through the "#include" C preprocessor directive.

This rule is not intended to be called explicitly. It is called automatically during header scanning on sources handled by the Object rule (e.g., sources in Main or Library rules).

InstallBin dir : sources ;
Copy sources into dir with mode $(EXEMODE).
InstallLib dir : sources ;
Copy sources into dir with mode $(FILEMODE).
InstallMan dir : sources ;
Copy sources into the appropriate subdirectory of dir with mode $(FILEMODE). The subdirectory is mans, where s is the suffix of each of sources.
InstallShell dir : sources ;
Copy sources into dir with mode $(SHELLMODE).
Lex source.c : source.l ;
Process the lex(1) source file source.l and rename the lex.yy.c to source.c. Called by the Object rule.
Library library : sources ;
Compiles sources and archives them into library. The intermediate objects are deleted. Calls Objects and LibraryFromObjects.

If Library is invoked with no suffix on library, the $(SUFLIB) suffix is used.

LibraryFromObjects library : objects ;
Archives objects into library. The objects are then deleted.

If library has no suffix, the $(SUFLIB) suffix is used.

Link image : objects ;
Links image from objects and sets permissions on image to $(EXEMODE). Image must be actual filename; suffix is not supplied. Called by Main.
LinkLibraries image : libraries ;
Makes image depend on libraries and includes them during the linking.

Image may be referenced without a suffix in this rule invocation; LinkLibraries supplies the suffix.

Main image : sources ;
Compiles sources and links them into image. Calls Objects and MainFromObjects.

Image may be referenced without a suffix in this rule invocation; Main supplies the suffix.

MainFromObjects image : objects ;
Links objects into image. Dependency of exe. MainFromObjects supplies the suffix on image filename.
MakeLocate target : dir ;
Creates dir and causes target to be built into dir.
MkDir dir ;
Creates dir and its parent directories.
Object object : source ;
Compiles a single source file source into object. The Main and Library rules use this rule to compile source files.

Causes source to be scanned for "#include" directives and calls HdrRule to make all included files dependedencies of object.

Calls one of the following rules to do the actual compiling, depending on the suffix of source:

		     *.c:   Cc 
		     *.cc:  C++ 
		     *.cpp: C++
		     *.C:   C++ 
		     *.l:   Lex 
		     *.y:   Yacc
		     *.*:   UserObject
ObjectC++Flags source : flags ;
ObjectCcFlags source : flags ;
Add flags to the source-specific value of $(CCFLAGS) or $(C++FLAGS) when compiling source. Any file suffix on source is ignored.
ObjectDefines object : defines ;
Adds preprocessor symbol definitions to the (gristed) target-specific $(CCDEFS) for the object.
ObjectHdrs source : dirs ;
Add dirs to the source-specific value of $(HDRS) when scanning and compiling source. Any file suffix on source is ignored.
Objects sources ;
For each source file in sources, calls Object to compile the source file into a similarly named object file.
RmTemps targets : sources ;
Marks sources as temporary with the TEMPORARY rule, and deletes sources once targets are built. Must be the last rule invoked on targets. Used internally by LibraryFromObjects rule.
Setuid images ;
Sets the setuid bit on each of images after linking. (Unix only.)
SoftLink target : source ;
Makes target a symbolic link to source, if it isn't one already. (Unix only.)
SubDir TOP d1 ... dn ;
Sets up housekeeping for the source files located in $(TOP)/d1/.../dn:
  • Reads in rules file associated with TOP, if it hasn't already been read.
  • Initializes variables for search paths, output directories, compiler flags, and grist, using d1 ... dn tokens.

TOP is the name of a variable; d1 thru dn are elements of a directory path.

SubDirC++Flags flags ;
SubDirCcFlags flags ;
Adds flags to the compiler flags for source files in SubDir's directory.
SubDirHdrs d1 ... dn ;
Adds the path d1/.../dn/ to the header search paths for source files in SubDir's directory. d1 through dn are elements of a directory path.
SubInclude VAR d1 ... dn ;
Reads the Jamfile in $(VAR)/d1/.../dn/.
Shell image : source ;
Copies source into the executable sh(1) script image. Ensures that the first line of the script is $(SHELLHEADER) (default #!/bin/sh).
Undefines images : symbols ;
Adds flags to mark symbols as undefined on link command for images. Images may be referenced unsuffixed; the Undefines rule supplies the suffix.
UserObject object : source ;
This rule is called by Object for source files with unknown suffixes, and should be defined in Jamrules with a user-provided rule to handle the source file types not handled by the Object rule. The Jambase UserObject rule merely issues a complaint when it encounters source with files suffixes it does not recognize.
Yacc source.c : source.y ;
Process the yacc(1) file source.y and renamed the resulting y.tab.c and y.tab.h to source.c. Produces a y.tab.h and renames it to source.h. Called by the Object rule.


Jambase Pseudotargets

There are two kinds of Jam targets: file targets and pseudotargets. File targets are objects that can be found in the filesystem. Pseudotargets are symbolic, and usually represent other targets. Most Jambase rules that define file targets also define pseudotargets which are dependent on types of file targets. The Jambase pseudotargets are:

exe Executables linked by the Main or MainFromObjects rules
lib Libraries created by the Library or LibraryFromObjects rules
obj Compiled objects used to create Main or Library targets
dirs Directories where target files are written
file Files copied by File and Bulk rules
shell Files copied by Shell rule
clean Removal of built targets (except files copied by Install* rules)
install Files copied by Install* rules
uninstall Removal of targets copied by Install* rules

In addition, Jambase makes the jam default target "all" depend on "exe", "lib", "obj", "files", and "shell".


Jambase Variables

Most of the following variables have default values for each platform; refer to the Jambase file to see what those defaults are.

ALL_LOCATE_TARGET

Alternative location of built targets. By default, Jambase rules locate built targets in the source tree. By setting $(ALL_LOCATE_TARGET) in Jamrules, you can cause jam to write built targets to a location outside the source tree.
AR
The archive command used to update Library and LibraryFromObjects targets.
AS
The assembler for As rule targets.
ASFLAGS
Flags handed to the assembler for As.
AWK
The name of awk interpreter, used when copying a shell script for the Shell rule.
BCCROOT
Selects Borland compile and link actions on NT.
BINDIR
Not longer used. (I.e., used only for backward compatibility with the obsolete INSTALLBIN rule.)
CC
C compiler used for Cc rule targets.
CCFLAGS
Compile flags for Cc rule targets. The Cc rule sets target-specific $(CCFLAGS) values on its targets.
C++
C++ compiler used for C++ rule targets.
C++FLAGS
Compile flags for C++ rule targets. The C++ rule sets target-specific $(C++FLAGS) values on its targets.
CHMOD
Program (usually chmod(1)) used to set file permissions for Chmod rule.
CP
The file copy program, used by File and Install* rules.
CRELIB
If set, causes the Library rule to invoke the CreLib rule on the target library before attempting to archive any members, so that the library can be created if needed.
CW
On Macintosh, the root of the Code Warrior Pro 5 directory.
DEFINES
Preprocessor symbol definitions for Cc and C++ rule targets. The Cc and C++ rules set target-specific $(CCDEFS) values on their targets, based on $(DEFINES). (The "indirection" here is required to support compilers, like VMS, with baroque command line syntax for setting symbols).
DOT
The operating system-specific name for the current directory.
DOTDOT
The operating system-specific name for the parent directory.
EXEMODE
Permissions for executables linked with Link, Main, and MainFromObjects, on platforms with a Chmod action.
FILEMODE
Permissions for files copied by File or Bulk, on platforms with a Chmod action.
FORTRAN
The Fortran compiler used by Fortran rule.
FORTRANFLAGS
Fortran compiler flags for Fortran rule targets.
GROUP
(Unix only.) The group owner for Install* rule targets.
HDRGRIST
If set, used by the HdrRule to distinguish header files with the same name in diffrent directories.
HDRPATTERN
A regular expression pattern that matches C preprocessor "#include" directives in source files and returns the name of the included file.
HDRRULE
Name of the rule to invoke with the results of header file scanning. Default is "HdrRule".

This is a jam-special variable. If both HDRRULE and HDRSCAN are set on a target, that target will be scanned for lines matching $(HDRSCAN), and $(HDDRULE) will be invoked on included files found in the matching $(HDRSCAN) lines.

HDRS
Directories to be searched for header files. This is used by the Object rule to:
  • set up search paths for finding files returned by header scans
  • add -I flags on compile commands
(See STDHDRS.)
HDRSCAN
Regular expression pattern to use for header file scanning. The Object rule sets this to $(HDRPATTERN). This is a jam-special variable; see HDRRULE.
HDRSEARCH
Used by the HdrRule to fix the list of directories where header files can be found for a given source file.
INSTALLGRIST
Used by the Install* rules to grist paths to installed files; defaults to "installed".
JAMFILE
Default is "Jamfile"; the name of the user-written rules file found in each source directory.
JAMRULES
Default is "Jamrules"; the name of a rule definition file to be read in at the first SubDir rule invocation.
KEEPOBJS
If set, tells the LibraryFromObjects rule not to delete object files once they are archived.
LEX
The lex(1) command and flags.
LIBDIR
Not longer used. (I.e., used only for backward compatibility with the obsolete INSTALLLIB rule.)
LINK
The linker. Defaults to $(CC).
LINKFLAGS
Flags handed to the linker. Defaults to $(CCFLAGS).
LINKLIBS
List of external libraries to link with. The target image does not depend on these libraries.
LN
The hard link command for HardLink rule.
LOCATE_SOURCE
Used to set the location of generated source files. The Yacc, Lex, and GenFile rules set LOCATE on their targets to $(LOCATE_SOURCE). $(LOCATE_SOURCE) is initialized by the SubDir rule to the source directory itself. (Also, see ALL_LOCATE_TARGET.)
LOCATE_TARGET
Used to set the location of built binary targets. The Object rule, and hence the Main and Library rules, set LOCATE on their targets to $(LOCATE_TARGET). $(LOCATE_TARGET) is initialized by the SubDir rule to the source directory itself. (See ALL_LOCATE_TARGET.)
MANDIR
Not longer used. (I.e., used only for backward compatibility with the obsolete INSTALLMAN rule.)
MKDIR
The 'create directory' command used for the MkDir rule.
MODE
The target-specific file mode (permissions) for targets of the Shell, Setuid, Link, and Install* rules. Used by the Chmod action; hence relevant to NT and VMS only.
MSVC
Selects Microsoft Visual C 16-bit compile & link actions on NT.
MSVCNT
Selects Microsoft Visual C NT 5.0 and earlier compile & link actions on NT.
MSVCDIR
Selects Microsoft Visual C NT 6.0 and later compile & link actions on NT. These are identical to versions 5.0 and earlier -- it just seems Microsoft changed the name of the variable.
MV
The file rename command and options.
NEEDLIBS
The list of libraries used when linking an executable. Used by the Link rule.
NOARSCAN
If set, indicates that library members' timestamps can't be found, and prevents the individual objects from being deleted, so that their timestamps can be used instead.
NOARUPDATE
If set, indicates that libraries can't be updated, but only created whole.
OPTIM
The C compiler flag for optimization, used by Cc and C++ rules.
OSFULL
The concatenation of $(OS)$(OSVER)$(OSPLAT), used when jam builds itself to determine the target binary directory. $(OS) and $(OSPLAT) are determined by jam at its compile time (in jam.h). $(OSVER) can optionally be set by the user.
OWNER
The owner of installed files. Used by Install* rules.
RANLIB
The name of the ranlib command. If set, causes the Ranlib action to be applied after the Archive action to targets of the Library rule.
RELOCATE
If set, tells the Cc rule to move the output object file to its target directory because the cc command has a broken -o option.
RM
The command and options to remove a file.
SEARCH_SOURCE
The directory to find sources listed with Main, Library, Object, Bulk, File, Shell, InstallBin, InstallLib, and InstallMan rules. This works by setting the jam-special variable SEARCH to the value of $(SEARCH_SOURCE) for each of the rules' sources. The SubDir rule initializes SEARCH_SOURCE for each directory.
SHELLHEADER
A string inserted to the first line of every file created by the Shell rule.
SHELLMODE
Permissions for files installed by Shell rule.
SOURCE_GRIST
Set by the SubDir to a value derived from the directory name, and used by Objects and related rules as 'grist' to perturb file names.
STDHDRS
Directories where headers can be found without resorting to using the flag to the C compiler. The $(STDHDRS) directories are used to find headers during scanning, but are not passed to the compiler commands as -I paths.
SUBDIR
The path from the current directory to the directory last named by the SubDir rule.
TOP
The path from the current directory to the directory that has the Jamrules file. Used by the SubDir rule.
SUFEXE
The suffix for executable files, if none provided. Used by the Main rule.
SUFLIB
The suffix for libraries. Used by the Library and related rules.
SUFOBJ
The suffix for object files. Used by the Objects and related rules.
UNDEFFLAG
The flag prefixed to each symbol for the Undefines rule (i.e., the compiler flag for undefined symbols).
WATCOM
Selects Watcom compile and link actions on OS2.
YACC
The yacc(1) command.
YACCFILES
The base filename generated by yacc(1).
YACCFLAGS
The yacc(1) command flags.
YACCGEN
The suffix used on generated yacc(1) output.


Back to top.

Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
Comments to info@perforce.com
Last updated: Dec 31, 2000
$Id: //public/jam/src/Jambase.html#10 $ ftjam-2.5.2/execnt.c0000744000424500003730000003425610441006322014050 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ # include "jam.h" # include "lists.h" # include "execcmd.h" # include # ifdef USE_EXECNT # define WIN32_LEAN_AND_MEAN # include /* do the ugly deed */ # include # if !defined( __BORLANDC__ ) && !defined( OS_OS2 ) # define wait my_wait static int my_wait( int *status ); # endif /* * execnt.c - execute a shell command on Windows NT and Windows 95/98 * * If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp(). * The default is: * * /bin/sh -c % [ on UNIX/AmigaOS ] * cmd.exe /c % [ on Windows NT ] * * Each word must be an individual element in a jam variable value. * * In $(JAMSHELL), % expands to the command string and ! expands to * the slot number (starting at 1) for multiprocess (-j) invocations. * If $(JAMSHELL) doesn't include a %, it is tacked on as the last * argument. * * Don't just set JAMSHELL to /bin/sh or cmd.exe - it won't work! * * External routines: * execcmd() - launch an async command execution * execwait() - wait and drive at most one execution completion * * Internal routines: * onintr() - bump intr to note command interruption * * 04/08/94 (seiwald) - Coherent/386 support added. * 05/04/94 (seiwald) - async multiprocess interface * 01/22/95 (seiwald) - $(JAMSHELL) support * 06/02/97 (gsar) - full async multiprocess support for Win32 */ static int intr = 0; static int cmdsrunning = 0; static void (*istat)( int ); static int is_nt_351 = 0; static int is_win95 = 1; static int is_win95_defined = 0; static struct { int pid; /* on win32, a real process handle */ void (*func)( void *closure, int status ); void *closure; char *tempfile; } cmdtab[ MAXJOBS ] = {{0}}; static void set_is_win95( void ) { OSVERSIONINFO os_info; os_info.dwOSVersionInfoSize = sizeof(os_info); os_info.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; GetVersionEx( &os_info ); is_win95 = (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); is_win95_defined = 1; /* now, test wether we're running Windows 3.51 */ /* this is later used to limit the system call command length */ if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) is_nt_351 = os_info.dwMajorVersion == 3; } static char** string_to_args( const char* string, int* pcount ) { int total = strlen( string ); int in_quote = 0, num_args; char* line; char* p; char** arg; char** args; *pcount = 0; /* do not copy trailing newlines, if any */ { int i; for ( i = total-1; i > 0; i-- ) { if ( string[i] != '\n' && string[i] != '\r' ) break; total --; } } /* first of all, copy the input string */ line = (char*)malloc( total+2 ); if (!line) return 0; memcpy( line+1, string, total ); line[0] = 0; line[total+1] = 0; in_quote = 0; for ( p = line+1; p[0]; p++ ) { switch (p[0]) { case '"': in_quote = !in_quote; break; case ' ': case '\t': if (!in_quote) p[0] = 0; default: ; } } /* now count the arguments.. */ for ( p = line; p < line+total+1; p++ ) if ( !p[0] && p[1] ) num_args++; /* allocate the args array */ args = (char**)malloc( num_args*sizeof(char*)+2 ); if (!args) { free( line ); return 0; } arg = args+1; for ( p = line; p < line+total+1; p++ ) if ( !p[0] && p[1] ) { arg[0] = p+1; arg++; } arg[0] = 0; *pcount = num_args; args[0] = line; return args+1; } static void free_args( char** args ) { free( args[-1] ); free( args-1 ); } /* process a "del" or "erase" command under Windows 95/98 */ static int process_del( char* command ) { char** arg; char* p = command, *q; int wildcard = 0, result = 0; /* first of all, skip the command itself */ if ( p[0] == 'd' ) p += 3; /* assumes "del..;" */ else if ( p[0] == 'e' ) p += 5; /* assumes "erase.." */ else return 1; /* invalid command */ /* process all targets independently */ for (;;) { /* skip leading spaces */ while ( *p && isspace(*p) ) p++; /* exit if we encounter an end of string */ if (!*p) return 0; /* ignore toggles/flags */ if (*p == '/') { p++; while ( *p && isalnum(*p) ) p++; } else { int in_quote = 0; int wildcard = 0; int go_on = 1; q = p; while (go_on) { switch (*p) { case '"': in_quote = !in_quote; break; case '?': case '*': if (!in_quote) wildcard = 1; break; case '\0': if (in_quote) return 1; /* fall-through */ case ' ': case '\t': if (!in_quote) { int len = p - q; int result; char* line; /* q..p-1 contains the delete argument */ if ( len <= 0 ) return 1; line = (char*)malloc( len+4+1 ); if (!line) return 1; strncpy( line, "del ", 4 ); strncpy( line+4, q, len ); line[len+4] = '\0'; if ( wildcard ) result = system( line ); else result = !DeleteFile( line+4 ); free( line ); if (result) return 1; go_on = 0; } default: ; } p++; } /* while (go_on) */ } } } /* * onintr() - bump intr to note command interruption */ void onintr( int disp ) { intr++; printf( "...interrupted\n" ); } /* * execcmd() - launch an async command execution */ void execcmd( char *string, void (*func)( void *closure, int status ), void *closure, LIST *shell ) { int pid; int slot; int max_line; char *argv[ MAXARGC + 1 ]; /* +1 for NULL */ char *p; if ( !is_win95_defined ) set_is_win95(); /* Find a slot in the running commands table for this one. */ if ( is_win95 ) { /* only synchronous spans are supported on Windows 95/98 */ slot = 0; } else { for( slot = 0; slot < MAXJOBS; slot++ ) if( !cmdtab[ slot ].pid ) break; } if( slot == MAXJOBS ) { printf( "no slots for child!\n" ); exit( EXITBAD ); } if( !cmdtab[ slot ].tempfile ) { char *tempdir; if( !( tempdir = getenv( "TEMP" ) ) && !( tempdir = getenv( "TMP" ) ) ) tempdir = "\\temp"; cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 14 ); sprintf( cmdtab[ slot ].tempfile, "%s\\jamtmp%02d.bat", tempdir, slot ); } /* Trim leading, ending white space */ while( isspace( *string ) ) ++string; p = strchr( string, '\n' ); while( p && isspace( *p ) ) ++p; /* on Windows NT 3.51, the maximul line length is 996 bytes !! */ /* while it's much bigger NT 4 and 2k */ max_line = is_nt_351 ? 996 : MAXLINE; /* If multi line, or too long, or JAMSHELL is set, write to bat file. */ /* Otherwise, exec directly. */ /* Frankly, if it is a single long line I don't think the */ /* command interpreter will do any better -- it will fail. */ if( p && *p || strlen( string ) > max_line || shell ) { FILE *f; /* Write command to bat file. */ f = fopen( cmdtab[ slot ].tempfile, "w" ); fputs( string, f ); fclose( f ); string = cmdtab[ slot ].tempfile; } /* Forumulate argv */ /* If shell was defined, be prepared for % and ! subs. */ /* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */ if( shell ) { int i; char jobno[4]; int gotpercent = 0; sprintf( jobno, "%d", slot + 1 ); for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) ) { switch( shell->string[0] ) { case '%': argv[i] = string; gotpercent++; break; case '!': argv[i] = jobno; break; default: argv[i] = shell->string; } if( DEBUG_EXECCMD ) printf( "argv[%d] = '%s'\n", i, argv[i] ); } if( !gotpercent ) argv[i++] = string; argv[i] = 0; } else { /* don't worry, this is ignored on Win95/98, see later.. */ argv[0] = "cmd.exe"; argv[1] = "/Q/C"; /* anything more is non-portable */ argv[2] = string; argv[3] = 0; } /* Catch interrupts whenever commands are running. */ if( !cmdsrunning++ ) istat = signal( SIGINT, onintr ); /* Start the command */ /* on Win95, we only do a synchronous call */ if ( is_win95 ) { static const char* hard_coded[] = { "del", "erase", "copy", "mkdir", "rmdir", "cls", "dir", "ren", "rename", "move", 0 }; const char** keyword; int len, spawn = 1; int result; for ( keyword = hard_coded; keyword[0]; keyword++ ) { len = strlen( keyword[0] ); if ( strnicmp( string, keyword[0], len ) == 0 && !isalnum(string[len]) ) { /* this is one of the hard coded symbols, use 'system' to run */ /* them.. except for "del"/"erase" */ if ( keyword - hard_coded < 2 ) result = process_del( string ); else result = system( string ); spawn = 0; break; } } if (spawn) { char** args; int num_args; /* convert the string into an array of arguments */ /* we need to take care of double quotes !! */ args = string_to_args( string, &num_args ); if ( args ) { #if 0 char** arg; fprintf( stderr, "%s: ", args[0] ); arg = args+1; while ( arg[0] ) { fprintf( stderr, " {%s}", arg[0] ); arg++; } fprintf( stderr, "\n" ); #endif result = spawnvp( P_WAIT, args[0], args ); free_args( args ); } else result = 1; } func( closure, result ? EXEC_CMD_FAIL : EXEC_CMD_OK ); return; } /* the rest is for Windows NT only */ if( ( pid = spawnvp( P_NOWAIT, argv[0], argv ) ) == -1 ) { perror( "spawn" ); exit( EXITBAD ); } /* Save the operation for execwait() to find. */ cmdtab[ slot ].pid = pid; cmdtab[ slot ].func = func; cmdtab[ slot ].closure = closure; /* Wait until we're under the limit of concurrent commands. */ /* Don't trust globs.jobs alone. */ while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs ) if( !execwait() ) break; } /* * execwait() - wait and drive at most one execution completion */ int execwait() { int i; int status, w; int rstat; /* Handle naive make1() which doesn't know if cmds are running. */ if( !cmdsrunning ) return 0; if ( is_win95 ) return 0; /* Pick up process pid and status */ while( ( w = wait( &status ) ) == -1 && errno == EINTR ) ; if( w == -1 ) { printf( "child process(es) lost!\n" ); perror("wait"); exit( EXITBAD ); } /* Find the process in the cmdtab. */ for( i = 0; i < MAXJOBS; i++ ) if( w == cmdtab[ i ].pid ) break; if( i == MAXJOBS ) { printf( "waif child found!\n" ); exit( EXITBAD ); } /* Drive the completion */ if( !--cmdsrunning ) signal( SIGINT, istat ); if( intr ) rstat = EXEC_CMD_INTR; else if( w == -1 || status != 0 ) rstat = EXEC_CMD_FAIL; else rstat = EXEC_CMD_OK; cmdtab[ i ].pid = 0; (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat ); return 1; } # if !defined( __BORLANDC__ ) static int my_wait( int *status ) { int i, num_active = 0; DWORD exitcode, waitcode; static HANDLE *active_handles = 0; if (!active_handles) active_handles = (HANDLE *)malloc(globs.jobs * sizeof(HANDLE) ); /* first see if any non-waited-for processes are dead, * and return if so. */ for ( i = 0; i < globs.jobs; i++ ) { if ( cmdtab[i].pid ) { if ( GetExitCodeProcess((HANDLE)cmdtab[i].pid, &exitcode) ) { if ( exitcode == STILL_ACTIVE ) active_handles[num_active++] = (HANDLE)cmdtab[i].pid; else { CloseHandle((HANDLE)cmdtab[i].pid); *status = (int)((exitcode & 0xff) << 8); return cmdtab[i].pid; } } else goto FAILED; } } /* if a child exists, wait for it to die */ if ( !num_active ) { errno = ECHILD; return -1; } waitcode = WaitForMultipleObjects( num_active, active_handles, FALSE, INFINITE ); if ( waitcode != WAIT_FAILED ) { if ( waitcode >= WAIT_ABANDONED_0 && waitcode < WAIT_ABANDONED_0 + num_active ) i = waitcode - WAIT_ABANDONED_0; else i = waitcode - WAIT_OBJECT_0; if ( GetExitCodeProcess(active_handles[i], &exitcode) ) { CloseHandle(active_handles[i]); *status = (int)((exitcode & 0xff) << 8); return (int)active_handles[i]; } } FAILED: errno = GetLastError(); return -1; } # endif /* !__BORLANDC__ */ # endif /* USE_EXECNT */ ftjam-2.5.2/yyacc0000755000424500003730000000261110441006322013441 0ustar dturnermhpsys#!/bin/sh # yyacc - yacc wrapper # # Allows tokens to be written as `literal` and then automatically # substituted with #defined tokens. # # Usage: # yyacc file.y filetab.h file.yy # # inputs: # file.yy yacc grammar with ` literals # # outputs: # file.y yacc grammar # filetab.h array of string <-> token mappings # # 03-13-93 - Documented and p moved in sed command (for some reason, # s/x/y/p doesn't work). # 10-12-93 - Take basename as second argument. # 12-31-96 - reversed order of args to be compatible with GenFile rule # 03/19/02 (seiwald) - suffix symbols with _t to avoid conflicts # outy=${1?} outh=${2?} in=${3?} out=`basename $in .yy` T=/tmp/yy$$ trap 'rm -f $T.*' 0 sed ' : 1 /`/{ h s/[^`]*`\([^`]*\)`.*/\1/ p g s/[^`]*`[^`]*`// b 1 } d ' $in | sort -u | sed ' h y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ s/:/_COLON/ s/!/_BANG/ s/&&/_AMPERAMPER/ s/&/_AMPER/ s/+/_PLUS/ s/||/_BARBAR/ s/|/_BAR/ s/;/_SEMIC/ s/-/_MINUS/ s//_RANGLE/ s/\./_PERIOD/ s/?/_QUESTION/ s/=/_EQUALS/ s/,/_COMMA/ s/\[/_LBRACKET/ s/]/_RBRACKET/ s/{/_LBRACE/ s/}/_RBRACE/ s/(/_LPAREN/ s/)/_RPAREN/ s/.*/&_t/ G s/\n/ / ' > $T.1 sed ' s:^\(.*\) \(.*\)$:s/`\2`/\1/g: s:\.:\\.:g s:\[:\\[:g ' $T.1 > $T.s rm -f $outy $outh ( sed 's:^\(.*\) \(.*\)$:%token \1:' $T.1 sed -f $T.s $in ) > $outy ( sed 's:^\(.*\) \(.*\)$: { "\2", \1 },:' $T.1 ) > $outh ftjam-2.5.2/hash.h0000744000424500003730000000105710441006323013504 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * hash.h - simple in-memory hashing routines * * 11/04/02 (seiwald) - const-ing for string literals */ typedef struct hashdata HASHDATA; struct hash * hashinit( int datalen, const char *name ); int hashitem( struct hash *hp, HASHDATA **data, int enter ); void hashdone( struct hash *hp ); # define hashenter( hp, data ) !hashitem( hp, data, !0 ) # define hashcheck( hp, data ) hashitem( hp, data, 0 ) ftjam-2.5.2/Makefile0000744000424500003730000000331510441006323014047 0ustar dturnermhpsys# Makefile to build Jam on Unix with the default compiler # (i.e. "cc" or "$CC" when defined) # # To use it, you must be in the top Jam source directory, # and call # # make # # the program "jam" will be created in the new # directory named "bin.unix" # CC = gcc TARGET = -o jam0 CFLAGS = -g -O2 all: jam0 chmod a+w jambase.c ./jam0 include common.mk ############################################################################ # # The following is very specific and deals with installation # it implements "make install" and "make uninstall" for the # Jam executable. # # Note that for now, no documentation is installed with the executable # BUILD_DIR := bin.unix prefix := /usr/local exec_prefix := ${prefix} libdir := ${exec_prefix}/lib bindir := ${exec_prefix}/bin includedir := ${prefix}/include datadir := ${prefix}/share version_info := @version_info@ DELETE := rm -f DELDIR := rmdir # The Jam executable name. This is 'jam' on Unix, except Cygwin where # it will be "jam.exe". Yuckk.. # JAMEXE := jam INSTALL := /usr/bin/install -c INSTALL_PROGRAM := ${INSTALL} MKINSTALLDIRS := builds/unix/mkinstalldirs .PHONY: install uninstall check clean distclean # Unix installation and deinstallation targets. # Package managers can use the DESTDIR variable to force another # installation prefix # install: jam0 $(MKINSTALLDIRS) $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) $(BUILD_DIR)/$(JAMEXE) $(DESTDIR)$(bindir)/$(JAMEXE) uninstall: -$(DELETE) $(DESTDIR)$(bindir)/$(JAMEXE) clean: -$(DELETE) $(BUILD_DIR)/* -$(DELETE) jam0 distclean: clean -$(DELETE) config.log config.status Makefile check: @echo There is no validation suite for this package. ftjam-2.5.2/jamgram.yy0000744000424500003730000002134110441006323014407 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * jamgram.yy - jam grammar * * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 06/01/94 (seiwald) - new 'actions existing' does existing sources * 08/23/94 (seiwald) - Support for '+=' (append to variable) * 08/31/94 (seiwald) - Allow ?= as alias for "default =". * 09/15/94 (seiwald) - if conditionals take only single arguments, so * that 'if foo == bar' gives syntax error (use =). * 02/11/95 (seiwald) - when scanning arguments to rules, only treat * punctuation keywords as keywords. All arg lists * are terminated with punctuation keywords. * 09/11/00 (seiwald) - Support for function calls; rules return LIST *. * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() * 01/24/01 (seiwald) - 'while' statement * 03/23/01 (seiwald) - "[ on target rule ]" support * 02/27/02 (seiwald) - un-break "expr : arg in list" syntax * 03/02/02 (seiwald) - rules can be invoked via variable names * 03/12/02 (seiwald) - set YYMAXDEPTH for big, right-recursive rules * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx * 06/21/02 (seiwald) - support for named parameters * 10/22/02 (seiwald) - working return/break/continue statements */ %token ARG STRING %left `||` `|` %left `&&` `&` %left `=` `!=` `in` %left `<` `<=` `>` `>=` %left `!` %{ #include "jam.h" #include "lists.h" #include "variable.h" #include "parse.h" #include "scan.h" #include "compile.h" #include "newstr.h" #include "rules.h" # define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ # define F0 (LIST *(*)(PARSE *, LOL *, int *))0 # define P0 (PARSE *)0 # define S0 (char *)0 # define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) # define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) # define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) # define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) # define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) # define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) # define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) # define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) # define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) # define pon( l,r ) parse_make( compile_on,l,r,P0,S0,S0,0 ) # define prule( a,p ) parse_make( compile_rule,a,p,P0,S0,S0,0 ) # define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) # define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) # define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) # define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) # define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) %} %% run : /* empty */ /* do nothing */ | rules { parse_save( $1.parse ); } ; /* * block - zero or more rules * rules - one or more rules * rule - any one of jam's rules * right-recursive so rules execute in order. */ block : /* empty */ { $$.parse = pnull(); } | rules { $$.parse = $1.parse; } ; rules : rule { $$.parse = $1.parse; } | rule rules { $$.parse = prules( $1.parse, $2.parse ); } | `local` list `;` block { $$.parse = plocal( $2.parse, pnull(), $4.parse ); } | `local` list `=` list `;` block { $$.parse = plocal( $2.parse, $4.parse, $6.parse ); } ; rule : `{` block `}` { $$.parse = $2.parse; } | `include` list `;` { $$.parse = pincl( $2.parse ); } | arg lol `;` { $$.parse = prule( $1.parse, $2.parse ); } | arg assign list `;` { $$.parse = pset( $1.parse, $3.parse, $2.number ); } | arg `on` list assign list `;` { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } | `break` list `;` { $$.parse = pbreak( $2.parse, JMP_BREAK ); } | `continue` list `;` { $$.parse = pbreak( $2.parse, JMP_CONTINUE ); } | `return` list `;` { $$.parse = pbreak( $2.parse, JMP_RETURN ); } | `for` ARG `in` list `{` block `}` { $$.parse = pfor( $2.string, $4.parse, $6.parse ); } | `switch` list `{` cases `}` { $$.parse = pswitch( $2.parse, $4.parse ); } | `if` expr `{` block `}` { $$.parse = pif( $2.parse, $4.parse, pnull() ); } | `if` expr `{` block `}` `else` rule { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } | `while` expr `{` block `}` { $$.parse = pwhile( $2.parse, $4.parse ); } | `rule` ARG params `{` block `}` { $$.parse = psetc( $2.string, $3.parse, $5.parse ); } | `on` arg rule { $$.parse = pon( $2.parse, $3.parse ); } | `actions` eflags ARG bindlist `{` { yymode( SCAN_STRING ); } STRING { yymode( SCAN_NORMAL ); } `}` { $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); } ; /* * assign - = or += */ assign : `=` { $$.number = VAR_SET; } | `+=` { $$.number = VAR_APPEND; } | `?=` { $$.number = VAR_DEFAULT; } | `default` `=` { $$.number = VAR_DEFAULT; } ; /* * expr - an expression for if */ expr : arg { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); } | expr `=` expr { $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); } | expr `!=` expr { $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); } | expr `<` expr { $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); } | expr `<=` expr { $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); } | expr `>` expr { $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); } | expr `>=` expr { $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); } | expr `&` expr { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } | expr `&&` expr { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } | expr `|` expr { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } | expr `||` expr { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } | arg `in` list { $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); } | `!` expr { $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); } | `(` expr `)` { $$.parse = $2.parse; } ; /* * cases - action elements inside a 'switch' * case - a single action element inside a 'switch' * right-recursive rule so cases can be examined in order. */ cases : /* empty */ { $$.parse = P0; } | case cases { $$.parse = pnode( $1.parse, $2.parse ); } ; case : `case` ARG `:` block { $$.parse = psnode( $2.string, $4.parse ); } ; /* * params - optional parameter names to rule definition * right-recursive rule so that params can be added in order. */ params : /* empty */ { $$.parse = P0; } | ARG `:` params { $$.parse = psnode( $1.string, $3.parse ); } | ARG { $$.parse = psnode( $1.string, P0 ); } ; /* * lol - list of lists * right-recursive rule so that lists can be added in order. */ lol : list { $$.parse = pnode( P0, $1.parse ); } | list `:` lol { $$.parse = pnode( $3.parse, $1.parse ); } ; /* * list - zero or more args in a LIST * listp - list (in puncutation only mode) * arg - one ARG or function call */ list : listp { $$.parse = $1.parse; yymode( SCAN_NORMAL ); } ; listp : /* empty */ { $$.parse = pnull(); yymode( SCAN_PUNCT ); } | listp arg { $$.parse = pappend( $1.parse, $2.parse ); } ; arg : ARG { $$.parse = plist( $1.string ); } | `[` { yymode( SCAN_NORMAL ); } func `]` { $$.parse = $3.parse; } ; /* * func - a function call (inside []) * This needs to be split cleanly out of 'rule' */ func : arg lol { $$.parse = prule( $1.parse, $2.parse ); } | `on` arg arg lol { $$.parse = pon( $2.parse, prule( $3.parse, $4.parse ) ); } | `on` arg `return` list { $$.parse = pon( $2.parse, $4.parse ); } ; /* * eflags - zero or more modifiers to 'executes' * eflag - a single modifier to 'executes' */ eflags : /* empty */ { $$.number = 0; } | eflags eflag { $$.number = $1.number | $2.number; } ; eflag : `updated` { $$.number = RULE_UPDATED; } | `together` { $$.number = RULE_TOGETHER; } | `ignore` { $$.number = RULE_IGNORE; } | `quietly` { $$.number = RULE_QUIETLY; } | `piecemeal` { $$.number = RULE_PIECEMEAL; } | `existing` { $$.number = RULE_EXISTING; } | `maxline` ARG { $$.number = atoi( $2.string ) * RULE_MAXLINE; } ; /* * bindlist - list of variable to bind for an action */ bindlist : /* empty */ { $$.parse = pnull(); } | `bind` list { $$.parse = $2.parse; } ; ftjam-2.5.2/make1.c0000744000424500003730000004176010441006324013560 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * make1.c - execute command to bring targets up to date * * This module contains make1(), the entry point called by make() to * recursively decend the dependency graph executing update actions as * marked by make0(). * * External routines: * * make1() - execute commands to update a TARGET and all its dependents * * Internal routines, the recursive/asynchronous command executors: * * make1a() - recursively traverse target tree, calling make1b() * make1b() - dependents of target built, now build target with make1c() * make1c() - launch target's next command, call make1b() when done * make1d() - handle command execution completion and call back make1c() * * Internal support routines: * * make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc * make1list() - turn a list of targets into a LIST, for $(<) and $(>) * make1settings() - for vars that get bound, build up replacement lists * make1bind() - bind targets that weren't bound in dependency analysis * * 04/16/94 (seiwald) - Split from make.c. * 04/21/94 (seiwald) - Handle empty "updated" actions. * 05/04/94 (seiwald) - async multiprocess (-j) support * 06/01/94 (seiwald) - new 'actions existing' does existing sources * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. * 01/19/95 (seiwald) - distinguish between CANTFIND/CANTMAKE targets. * 01/22/94 (seiwald) - pass per-target JAMSHELL down to execcmd(). * 02/28/95 (seiwald) - Handle empty "existing" actions. * 03/10/95 (seiwald) - Fancy counts. * 02/07/01 (seiwald) - Fix jam -d0 return status. * 01/21/02 (seiwald) - new -q to quit quickly on build failure * 02/28/02 (seiwald) - don't delete 'actions updated' targets on failure * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx * 07/17/02 (seiwald) - TEMPORARY sources for headers now get built * 09/23/02 (seiwald) - "...using temp..." only displayed on -da now. * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 11/04/02 (seiwald) - const-ing for string literals * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends */ # include "jam.h" # include "lists.h" # include "parse.h" # include "variable.h" # include "rules.h" # include "search.h" # include "newstr.h" # include "make.h" # include "command.h" # include "execcmd.h" static void make1a( TARGET *t, TARGET *parent ); static void make1b( TARGET *t ); static void make1c( TARGET *t ); static void make1d( void *closure, int status ); static CMD *make1cmds( ACTIONS *a0 ); static LIST *make1list( LIST *l, TARGETS *targets, int flags ); static SETTINGS *make1settings( LIST *vars ); static void make1bind( TARGET *t, int warn ); /* Ugly static - it's too hard to carry it through the callbacks. */ static struct { int failed; int skipped; int total; int made; } counts[1] ; /* * make1() - execute commands to update a TARGET and all its dependents */ static int intr = 0; int make1( TARGET *t ) { memset( (char *)counts, 0, sizeof( *counts ) ); /* Recursively make the target and its dependents */ make1a( t, (TARGET *)0 ); /* Wait for any outstanding commands to finish running. */ while( execwait() ) ; /* Talk about it */ if( DEBUG_MAKE && counts->failed ) printf( "...failed updating %d target(s)...\n", counts->failed ); if( DEBUG_MAKE && counts->skipped ) printf( "...skipped %d target(s)...\n", counts->skipped ); if( DEBUG_MAKE && counts->made ) printf( "...updated %d target(s)...\n", counts->made ); return counts->total != counts->made; } /* * make1a() - recursively traverse target tree, calling make1b() */ static void make1a( TARGET *t, TARGET *parent ) { TARGETS *c; /* If the parent is the first to try to build this target */ /* or this target is in the make1c() quagmire, arrange for the */ /* parent to be notified when this target is built. */ if( parent ) switch( t->progress ) { case T_MAKE_INIT: case T_MAKE_ACTIVE: case T_MAKE_RUNNING: t->parents = targetentry( t->parents, parent ); parent->asynccnt++; } if( t->progress != T_MAKE_INIT ) return; /* Asynccnt counts the dependents preventing this target from */ /* proceeding to make1b() for actual building. We start off with */ /* a count of 1 to prevent anything from happening until we can */ /* call all dependents. This 1 is accounted for when we call */ /* make1b() ourselves, below. */ t->asynccnt = 1; /* Recurse on our dependents, manipulating progress to guard */ /* against circular dependency. */ t->progress = T_MAKE_ONSTACK; for( c = t->depends; c && !intr; c = c->next ) make1a( c->target, t ); t->progress = T_MAKE_ACTIVE; /* Now that all dependents have bumped asynccnt, we now allow */ /* decrement our reference to asynccnt. */ make1b( t ); } /* * make1b() - dependents of target built, now build target with make1c() */ static void make1b( TARGET *t ) { TARGETS *c; const char *failed = "dependents"; /* If any dependents are still outstanding, wait until they */ /* call make1b() to signal their completion. */ if( --t->asynccnt ) return; /* Now ready to build target 't'... if dependents built ok. */ /* Collect status from dependents */ for( c = t->depends; c; c = c->next ) if( c->target->status > t->status ) { failed = c->target->name; t->status = c->target->status; } /* If actions on deps have failed, bail. */ /* Otherwise, execute all actions to make target */ if( t->status == EXEC_CMD_FAIL && t->actions ) { ++counts->skipped; printf( "...skipped %s for lack of %s...\n", t->name, failed ); } if( t->status == EXEC_CMD_OK ) switch( t->fate ) { case T_FATE_INIT: case T_FATE_MAKING: /* shouldn't happen */ case T_FATE_STABLE: case T_FATE_NEWER: break; case T_FATE_CANTFIND: case T_FATE_CANTMAKE: t->status = EXEC_CMD_FAIL; break; case T_FATE_ISTMP: if( DEBUG_MAKEQ ) printf( "...using %s...\n", t->name ); break; case T_FATE_TOUCHED: case T_FATE_MISSING: case T_FATE_NEEDTMP: case T_FATE_OUTDATED: case T_FATE_UPDATE: /* Set "on target" vars, build actions, unset vars */ /* Set "progress" so that make1c() counts this target among */ /* the successes/failures. */ if( t->actions ) { ++counts->total; if( DEBUG_MAKE && !( counts->total % 100 ) ) printf( "...on %dth target...\n", counts->total ); pushsettings( t->settings ); t->cmds = (char *)make1cmds( t->actions ); popsettings( t->settings ); t->progress = T_MAKE_RUNNING; } break; } /* Call make1c() to begin the execution of the chain of commands */ /* needed to build target. If we're not going to build target */ /* (because of dependency failures or because no commands need to */ /* be run) the chain will be empty and make1c() will directly */ /* signal the completion of target. */ make1c( t ); } /* * make1c() - launch target's next command, call make1b() when done */ static void make1c( TARGET *t ) { CMD *cmd = (CMD *)t->cmds; /* If there are (more) commands to run to build this target */ /* (and we haven't hit an error running earlier comands) we */ /* launch the command with execcmd(). */ /* If there are no more commands to run, we collect the status */ /* from all the actions then report our completion to all the */ /* parents. */ if( cmd && t->status == EXEC_CMD_OK ) { if( DEBUG_MAKE ) if( DEBUG_MAKEQ || ! ( cmd->rule->flags & RULE_QUIETLY ) ) { printf( "%s ", cmd->rule->name ); list_print( lol_get( &cmd->args, 0 ) ); printf( "\n" ); } if( DEBUG_EXEC ) printf( "%s\n", cmd->buf ); if( globs.cmdout ) fprintf( globs.cmdout, "%s", cmd->buf ); if( globs.noexec ) { make1d( t, EXEC_CMD_OK ); } else { fflush( stdout ); execcmd( cmd->buf, make1d, t, cmd->shell ); } } else { TARGETS *c; ACTIONS *actions; /* Collect status from actions, and distribute it as well */ for( actions = t->actions; actions; actions = actions->next ) if( actions->action->status > t->status ) t->status = actions->action->status; for( actions = t->actions; actions; actions = actions->next ) if( t->status > actions->action->status ) actions->action->status = t->status; /* Tally success/failure for those we tried to update. */ if( t->progress == T_MAKE_RUNNING ) switch( t->status ) { case EXEC_CMD_OK: ++counts->made; break; case EXEC_CMD_FAIL: ++counts->failed; break; } /* Tell parents dependent has been built */ t->progress = T_MAKE_DONE; for( c = t->parents; c; c = c->next ) make1b( c->target ); } } /* * make1d() - handle command execution completion and call back make1c() */ static void make1d( void *closure, int status ) { TARGET *t = (TARGET *)closure; CMD *cmd = (CMD *)t->cmds; /* Execcmd() has completed. All we need to do is fiddle with the */ /* status and signal our completion so make1c() can run the next */ /* command. On interrupts, we bail heavily. */ if( status == EXEC_CMD_FAIL && ( cmd->rule->flags & RULE_IGNORE ) ) status = EXEC_CMD_OK; /* On interrupt, set intr so _everything_ fails */ if( status == EXEC_CMD_INTR ) ++intr; if( status == EXEC_CMD_FAIL && DEBUG_MAKE ) { /* Print command text on failure */ if( !DEBUG_EXEC ) printf( "%s\n", cmd->buf ); printf( "...failed %s ", cmd->rule->name ); list_print( lol_get( &cmd->args, 0 ) ); printf( "...\n" ); if( globs.quitquick ) ++intr; } /* If the command was interrupted or failed and the target */ /* is not "precious", remove the targets. */ /* Precious == 'actions updated' -- the target maintains state. */ if( status != EXEC_CMD_OK && !( cmd->rule->flags & RULE_UPDATED ) ) { LIST *targets = lol_get( &cmd->args, 0 ); for( ; targets; targets = list_next( targets ) ) if( !unlink( targets->string ) ) printf( "...removing %s\n", targets->string ); } /* Free this command and call make1c() to move onto next command. */ t->status = status; t->cmds = (char *)cmd_next( cmd ); cmd_free( cmd ); make1c( t ); } /* * make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc * * Essentially copies a chain of ACTIONs to a chain of CMDs, * grouping RULE_TOGETHER actions, splitting RULE_PIECEMEAL actions, * and handling RULE_UPDATED actions. The result is a chain of * CMDs which can be expanded by var_string() and executed with * execcmd(). */ static CMD * make1cmds( ACTIONS *a0 ) { CMD *cmds = 0; LIST *shell = var_get( "JAMSHELL" ); /* shell is per-target */ /* Step through actions */ /* Actions may be shared with other targets or grouped with */ /* RULE_TOGETHER, so actions already seen are skipped. */ for( ; a0; a0 = a0->next ) { RULE *rule = a0->action->rule; SETTINGS *boundvars; LIST *nt, *ns; ACTIONS *a1; CMD *cmd; int start, chunk, length, maxline; /* Only do rules with commands to execute. */ /* If this action has already been executed, use saved status */ if( !rule->actions || a0->action->running ) continue; a0->action->running = 1; /* Make LISTS of targets and sources */ /* If `execute together` has been specified for this rule, tack */ /* on sources from each instance of this rule for this target. */ nt = make1list( L0, a0->action->targets, 0 ); ns = make1list( L0, a0->action->sources, rule->flags ); if( rule->flags & RULE_TOGETHER ) for( a1 = a0->next; a1; a1 = a1->next ) if( a1->action->rule == rule && !a1->action->running ) { ns = make1list( ns, a1->action->sources, rule->flags ); a1->action->running = 1; } /* If doing only updated (or existing) sources, but none have */ /* been updated (or exist), skip this action. */ if( !ns && ( rule->flags & ( RULE_UPDATED | RULE_EXISTING ) ) ) { list_free( nt ); continue; } /* If we had 'actions xxx bind vars' we bind the vars now */ boundvars = make1settings( rule->bindlist ); pushsettings( boundvars ); /* * Build command, starting with all source args. * * If cmd_new returns 0, it's because the resulting command * length is > MAXLINE. In this case, we'll slowly reduce * the number of source arguments presented until it does * fit. This only applies to actions that allow PIECEMEAL * commands. * * While reducing slowly takes a bit of compute time to get * things just right, it's worth it to get as close to MAXLINE * as possible, because launching the commands we're executing * is likely to be much more compute intensive! * * Note we loop through at least once, for sourceless actions. * * Max line length is the action specific maxline or, if not * given or bigger than MAXLINE, MAXLINE. */ start = 0; chunk = length = list_length( ns ); maxline = rule->flags / RULE_MAXLINE; maxline = maxline && maxline < MAXLINE ? maxline : MAXLINE; do { /* Build cmd: cmd_new consumes its lists. */ CMD *cmd = cmd_new( rule, list_copy( L0, nt ), list_sublist( ns, start, chunk ), list_copy( L0, shell ), maxline ); if( cmd ) { /* It fit: chain it up. */ if( !cmds ) cmds = cmd; else cmds->tail->next = cmd; cmds->tail = cmd; start += chunk; } else if( ( rule->flags & RULE_PIECEMEAL ) && chunk > 1 ) { /* Reduce chunk size slowly. */ chunk = chunk * 9 / 10; } else { /* Too long and not splittable. */ printf( "%s actions too long (max %d)!\n", rule->name, maxline ); exit( EXITBAD ); } } while( start < length ); /* These were always copied when used. */ list_free( nt ); list_free( ns ); /* Free the variables whose values were bound by */ /* 'actions xxx bind vars' */ popsettings( boundvars ); freesettings( boundvars ); } return cmds; } /* * make1list() - turn a list of targets into a LIST, for $(<) and $(>) */ static LIST * make1list( LIST *l, TARGETS *targets, int flags ) { for( ; targets; targets = targets->next ) { TARGET *t = targets->target; /* Sources to 'actions existing' are never in the dependency */ /* graph (if they were, they'd get built and 'existing' would */ /* be superfluous, so throttle warning message about independent */ /* targets. */ if( t->binding == T_BIND_UNBOUND ) make1bind( t, !( flags & RULE_EXISTING ) ); if( ( flags & RULE_EXISTING ) && t->binding != T_BIND_EXISTS ) continue; if( ( flags & RULE_UPDATED ) && t->fate <= T_FATE_STABLE ) continue; /* Prohibit duplicates for RULE_TOGETHER */ if( flags & RULE_TOGETHER ) { LIST *m; for( m = l; m; m = m->next ) if( !strcmp( m->string, t->boundname ) ) break; if( m ) continue; } /* Build new list */ l = list_new( l, t->boundname, 1 ); } return l; } /* * make1settings() - for vars that get bound values, build up replacement lists */ static SETTINGS * make1settings( LIST *vars ) { SETTINGS *settings = 0; for( ; vars; vars = list_next( vars ) ) { LIST *l = var_get( vars->string ); LIST *nl = 0; for( ; l; l = list_next( l ) ) { TARGET *t = bindtarget( l->string ); /* Make sure the target is bound, warning if it is not in the */ /* dependency graph. */ if( t->binding == T_BIND_UNBOUND ) make1bind( t, 1 ); /* Build new list */ nl = list_new( nl, t->boundname, 1 ); } /* Add to settings chain */ settings = addsettings( settings, 0, vars->string, nl ); } return settings; } /* * make1bind() - bind targets that weren't bound in dependency analysis * * Spot the kludge! If a target is not in the dependency tree, it didn't * get bound by make0(), so we have to do it here. Ugly. */ static void make1bind( TARGET *t, int warn ) { if( t->flags & T_FLAG_NOTFILE ) return; /* Sources to 'actions existing' are never in the dependency */ /* graph (if they were, they'd get built and 'existing' would */ /* be superfluous, so throttle warning message about independent */ /* targets. */ if( warn ) printf( "warning: using independent target %s\n", t->name ); pushsettings( t->settings ); t->boundname = search( t->name, &t->time ); t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING; popsettings( t->settings ); } ftjam-2.5.2/fileos2.c0000744000424500003730000000617710441006324014130 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * fileos2.c - scan directories and archives on NT * * External routines: * * file_dirscan() - scan a directory for files * file_time() - get timestamp of file, if not done by file_dirscan() * file_archscan() - scan an archive for files * * File_dirscan() and file_archscan() call back a caller provided function * for each file found. A flag to this callback function lets file_dirscan() * and file_archscan() indicate that a timestamp is being provided with the * file. If file_dirscan() or file_archscan() do not provide the file's * timestamp, interested parties may later call file_time(). * * 07/10/95 (taylor) Findfirst() returns the first file on NT. * 05/03/96 (seiwald) split apart into pathnt.c * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C * 09/22/00 (seiwald) handle \ and c:\ specially: don't add extra / * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "filesys.h" # include "pathsys.h" # ifdef OS_OS2 # include # include /* * file_dirscan() - scan a directory for files */ void file_dirscan( const char *dir, scanback func, void *closure ) { PATHNAME f; char filespec[ MAXJPATH ]; char filename[ MAXJPATH ]; long handle; int ret; struct _find_t finfo[1]; /* First enter directory itself */ memset( (char *)&f, '\0', sizeof( f ) ); f.f_dir.ptr = dir; f.f_dir.len = strlen(dir); dir = *dir ? dir : "."; /* Special case \ or d:\ : enter it */ strcpy( filespec, dir ); if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' ) (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' ) (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); else strcat( filespec, "/" ); strcat( filespec, "*" ); /* Now enter contents of directory */ if( DEBUG_BINDSCAN ) printf( "scan directory %s\n", filespec ); /* Time info in dos find_t is not very useful. It consists */ /* of a separate date and time, and putting them together is */ /* not easy. So we leave that to a later stat() call. */ if( !_dos_findfirst( filespec, _A_NORMAL|_A_RDONLY|_A_SUBDIR, finfo ) ) { do { f.f_base.ptr = finfo->name; f.f_base.len = strlen( finfo->name ); path_build( &f, filename, 0 ); (*func)( closure, filename, 0 /* not stat()'ed */, (time_t)0 ); } while( !_dos_findnext( finfo ) ); } } /* * file_time() - get timestamp of file, if not done by file_dirscan() */ int file_time( const char *filename, time_t *time ) { /* This is called on OS2, not NT. */ /* NT fills in the time in the dirscan. */ struct stat statbuf; if( stat( filename, &statbuf ) < 0 ) return -1; *time = statbuf.st_mtime; return 0; } void file_archscan( const char *archive, scanback func, void *closure ) { } # endif /* OS2 */ ftjam-2.5.2/jam.c0000744000424500003730000002375710441006324013337 0ustar dturnermhpsys/* * /+\ * +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * \+/ * * This file is part of jam. * * License is hereby granted to use this software and distribute it * freely, as long as this copyright notice is retained and modifications * are clearly marked. * * ALL WARRANTIES ARE HEREBY DISCLAIMED. */ /* * jam.c - make redux * * See Jam.html for usage information. * * These comments document the code. * * The top half of the code is structured such: * * jam * / | \ * +---+ | \ * / | \ * jamgram option \ * / | \ \ * / | \ \ * / | \ | * scan | compile make * | | / | \ / | \ * | | / | \ / | \ * | | / | \ / | \ * jambase parse | rules search make1 * | | | \ * | | | \ * | | | \ * builtins timestamp command execute * | * | * | * filesys * * * The support routines are called by all of the above, but themselves * are layered thus: * * variable|expand * / | | | * / | | | * / | | | * lists | | pathsys * \ | | * \ | | * \ | | * newstr | * \ | * \ | * \ | * hash * * Roughly, the modules are: * * builtins.c - jam's built-in rules * command.c - maintain lists of commands * compile.c - compile parsed jam statements * execunix.c - execute a shell script on UNIX * execvms.c - execute a shell script, ala VMS * expand.c - expand a buffer, given variable values * file*.c - scan directories and archives on * * hash.c - simple in-memory hashing routines * headers.c - handle #includes in source files * jambase.c - compilable copy of Jambase * jamgram.y - jam grammar * lists.c - maintain lists of strings * make.c - bring a target up to date, once rules are in place * make1.c - execute command to bring targets up to date * newstr.c - string manipulation routines * option.c - command line option processing * parse.c - make and destroy parse trees as driven by the parser * path*.c - manipulate file names on * * hash.c - simple in-memory hashing routines * regexp.c - Henry Spencer's regexp * rules.c - access to RULEs, TARGETs, and ACTIONs * scan.c - the jam yacc scanner * search.c - find a target along $(SEARCH) or $(LOCATE) * timestamp.c - get the timestamp of a file or archive member * variable.c - handle jam multi-element variables * * 05/04/94 (seiwald) - async multiprocess (-j) support * 02/08/95 (seiwald) - -n implies -d2. * 02/22/95 (seiwald) - -v for version info. * 09/11/00 (seiwald) - PATCHLEVEL folded into VERSION. * 01/10/01 (seiwald) - pathsys.h split from filesys.h * 01/21/02 (seiwald) - new -q to quit quickly on build failure * 03/16/02 (seiwald) - support for -g (reorder builds by source time) * 09/19/02 (seiwald) - new -d displays * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "option.h" # include "patchlevel.h" /* These get various function declarations. */ # include "lists.h" # include "parse.h" # include "variable.h" # include "compile.h" # include "builtins.h" # include "rules.h" # include "newstr.h" # include "scan.h" # include "timestamp.h" # include "make.h" /* Macintosh is "special" */ # ifdef OS_MAC # include # endif /* And UNIX for this */ # ifdef unix # include # endif struct globs globs = { 0, /* noexec */ 1, /* jobs */ 0, /* quitquick */ 0, /* newestfirst */ # ifdef OS_MAC { 0 }, /* display - suppress actions output */ # else { 0, 1 }, /* display actions */ # endif 0 /* output commands, not run them */ } ; /* Symbols to be defined as true for use in Jambase */ static const char *othersyms[] = { OSMAJOR, OSMINOR, OSPLAT, JAMVERSYM, 0 } ; /* Known for sure: * mac needs arg_enviro * OS2 needs extern environ */ # ifdef OS_MAC # define use_environ arg_environ # ifdef MPW QDGlobals qd; # endif # endif # ifndef use_environ # define use_environ environ # if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT ) extern char **environ; # endif # endif int main( int argc, char **argv, char **arg_environ ) { int n, num_targets; const char *s; struct option optv[N_OPTS]; char* targets[N_TARGETS]; const char *all = "all"; int anyhow = 0; int status; # ifdef OS_MAC InitGraf(&qd.thePort); # endif argc--, argv++; if( ( num_targets = getoptions( argc, argv, "d:j:f:gs:t:ano:qv", optv, targets ) ) < 0 ) { printf( "\nusage: jam [ options ] targets...\n\n" ); printf( "-a Build all targets, even if they are current.\n" ); printf( "-dx Display (a)actions (c)causes (d)dependencies\n" ); printf( " (m)make tree (x)commands (0-9) debug levels.\n" ); printf( "-fx Read x instead of Jambase.\n" ); printf( "-g Build from newest sources first.\n" ); printf( "-jx Run up to x shell commands concurrently.\n" ); printf( "-n Don't actually execute the updating actions.\n" ); printf( "-ox Write the updating actions to file x.\n" ); printf( "-q Quit quickly as soon as a target fails.\n" ); printf( "-sx=y Set variable x=y, overriding environment.\n" ); printf( "-tx Rebuild x, even if it is up-to-date.\n" ); printf( "-v Print the version of jam and exit.\n\n" ); exit( EXITBAD ); } /* Version info. */ if( ( s = getoptval( optv, 'v', 0 ) ) ) { printf( "FT-Jam %s. %s. ", VERSION, OSMINOR ); printf( "(C) 1993-2003 Christopher Seiwald, see www.freetype.org/jam/\n" ); return EXITOK; } /* Pick up interesting options */ if( ( s = getoptval( optv, 'n', 0 ) ) ) globs.noexec++, DEBUG_MAKE = DEBUG_MAKEQ = DEBUG_EXEC = 1; if( ( s = getoptval( optv, 'q', 0 ) ) ) globs.quitquick = 1; if( ( s = getoptval( optv, 'a', 0 ) ) ) anyhow++; if( ( s = getoptval( optv, 'j', 0 ) ) ) globs.jobs = atoi( s ); if( ( s = getoptval( optv, 'g', 0 ) ) ) globs.newestfirst = 1; /* Turn on/off debugging */ for( n = 0; (s = getoptval( optv, 'd', n )) != 0; n++ ) { int i = atoi( s ); /* First -d, turn off defaults. */ if( !n ) DEBUG_MAKE = DEBUG_MAKEQ = DEBUG_EXEC = 0; /* n turns on levels 1-n */ /* +n turns on level n */ /* c turns on named display c */ if( i < 0 || i >= DEBUG_MAX ) { printf( "Invalid debug level '%s'.\n", s ); } else if( *s == '+' ) { globs.debug[i] = 1; } else if( i ) while( i ) { globs.debug[i--] = 1; } else while( *s ) switch( *s++ ) { case 'a': DEBUG_MAKE = DEBUG_MAKEQ = 1; break; case 'c': DEBUG_CAUSES = 1; break; case 'd': DEBUG_DEPENDS = 1; break; case 'm': DEBUG_MAKEPROG = 1; break; case 'x': DEBUG_EXEC = 1; break; case '0': break; default: printf( "Invalid debug flag '%c'.\n", s[-1] ); } } /* Set JAMDATE first */ { char buf[ 128 ]; time_t clock; time( &clock ); strcpy( buf, ctime( &clock ) ); /* Trim newline from date */ if( strlen( buf ) == 25 ) buf[ 24 ] = 0; var_set( "JAMDATE", list_new( L0, buf, 0 ), VAR_SET ); } /* And JAMUNAME */ # ifdef unix { struct utsname u; if( uname( &u ) >= 0 ) { LIST *l = L0; l = list_new( l, u.machine, 0 ); l = list_new( l, u.version, 0 ); l = list_new( l, u.release, 0 ); l = list_new( l, u.nodename, 0 ); l = list_new( l, u.sysname, 0 ); var_set( "JAMUNAME", l, VAR_SET ); } } # endif /* unix */ /* * Jam defined variables OS, OSPLAT */ var_defines( othersyms ); /* load up environment variables */ var_defines( (const char **)use_environ ); /* Load up variables set on command line. */ for( n = 0; (s = getoptval( optv, 's', n )) != 0; n++ ) { const char *symv[2]; symv[0] = s; symv[1] = 0; var_defines( symv ); } /* Initialize built-in rules */ load_builtins(); /* Parse ruleset */ for( n = 0; (s = getoptval( optv, 'f', n )) != 0; n++ ) parse_file( s ); if( !n ) parse_file( "+" ); status = yyanyerrors(); /* Manually touch -t targets */ for( n = 0; (s = getoptval( optv, 't', n )) != 0; n++ ) touchtarget( s ); /* If an output file is specified, set globs.cmdout to that */ if( (s = getoptval( optv, 'o', 0 )) != 0 ) { if( !( globs.cmdout = fopen( s, "w" ) ) ) { printf( "Failed to write to '%s'\n", s ); exit( EXITBAD ); } globs.noexec++; } /* Add JAMCMDARGS */ { LIST* l = L0; for ( n = 0; n < num_targets; n++ ) l = list_new( l, targets[n], 0 ); var_set( "JAMCMDARGS", l, VAR_SET ); } /* Now make target */ if( !num_targets ) status |= make( 1, &all, anyhow ); else status |= make( num_targets, (const char**)targets, anyhow ); /* Widely scattered cleanup */ var_done(); donerules(); donestamps(); donestr(); /* close cmdout */ if( globs.cmdout ) fclose( globs.cmdout ); return status ? EXITBAD : EXITOK; } ftjam-2.5.2/option.c0000744000424500003730000000617710441006325014076 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * option.c - command line option processing * * {o >o * \<>) "Process command line options as defined in . * Return the number of argv[] elements used up by options, * or -1 if an invalid option flag was given or an argument * was supplied for an option that does not require one." * * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "option.h" int getoptions( int argc, char **argv, const char *opts, option *optv, char** targets ) { int i, n; int optc = N_OPTS; memset( (char *)optv, '\0', sizeof( *optv ) * N_OPTS ); n = 0; for( i = 0; i < argc; i++ ) { char *arg; if ( argv[i][0] == '-' ) { if( !optc-- ) { printf( "too many options (%d max)\n", N_OPTS ); return -1; } for( arg = &argv[i][1]; *arg; arg++ ) { const char *f; for( f = opts; *f; f++ ) if( *f == *arg ) break; if( !*f ) { printf( "Invalid option: -%c\n", *arg ); return -1; } optv->flag = *f; if( f[1] != ':' ) { optv++->val = "true"; } else if( arg[1] ) { optv++->val = &arg[1]; break; } else if( ++i < argc ) { optv++->val = argv[i]; break; } else { printf( "option: -%c needs argument\n", *f ); return -1; } } } else { /* something like VARNAME=.... is treated as an implicit '-s' flag */ if ( argv[i][0] != '=' && strchr( argv[i],'=' ) ) { if ( !optc-- ) { printf( "too many options (%d max)\n", N_OPTS ); return -1; } optv->flag = 's'; optv++->val = argv[i]; } else { if ( n >= N_TARGETS ) { printf( "too many targets (%d max)\n", N_TARGETS ); return -1; } targets[n++] = argv[i]; } } } return n; } /* * Name: getoptval() - find an option given its character */ const char * getoptval( option *optv, char opt, int subopt ) { int i; for( i = 0; i < N_OPTS; i++, optv++ ) if( optv->flag == opt && !subopt-- ) return optv->val; return 0; } ftjam-2.5.2/RELNOTES0000744000424500003730000011512010441006325013565 0ustar dturnermhpsys=============================================================================== =============================================================================== Release notes for Jam 2.5 (aka Jam - make(1) redux) 1. Release info: Jam 2.5 August 19, 2004 VERSION 2.5 (n.b. Jam 2.5 is merely Jam 2.5rc3 of April 2003 with the rc3 moniker removed.) 2. Compatibility Jam 2.5 is upward compatible with Jam 2.4 The Jam 2.5 language is a superset of the 2.4 language; Jamfiles, Jambase, and other rulesets used in 2.4 can be used with the 2.5 language support. 3. Changes since 2.4. 3.1. Changes to Jam Language The 'return' statement now actually returns, and there are now break & continue statements for for & while loops. 3.2. Jambase Changes MkDir now grists directories with 'dir', so that directory targets can be distinguished from other targets. SubDir now allows multiple overlapping roots (top level directories): the first SubDir of a new root uses the CWD of jam to set that root; subsquent SubDirs use the current SUBDIR to set the new root. New FSubDirPath to compute a path (given SubDir arguments) and SubRules to include another root's Jamrules. Jamrules only included if present; no error issued if no Jamrules file. Using SubDir to include a subpart of an SubDir tree now works. Previously, you could only include the root of another SubDir tree. This example includes the ../server/support/Jamfile, without getting confused as to the current directory: SubDir ALL src builds ; SubInclude ALL src server support ; $(RMDIR) has been defined for NT and defaulted to $(RM) everwhere else. Not much tested. For Michael Champigny. GenFile actions (on UNIX) now put . in the PATH for the execution of the command, so that (at least) when jam builds itself . does not need to be in the global path. It is the rare case where a target bound in the current directory can't be used directly, so we fudge it by setting PATH. Undocumented support for SUBDIRRULES, user-provided rules to invoke at the end of the SubDir rule, and SUBDIRRESET, SUBDIR variables to reset (like SUBDIRC++FLAGS, SUBDIRHDRS, etc) for each new SubDir. 3.3 'jam' Changes (See Jam.html) The whole /MR of Jam's name has been dropped. It was intended to avoid trademark infringement of JYACC's JAM, but as far as we can tell (a) it wasn't enough to avoid infringement and (b) the trademark has lapsed anyhow. If header dependencies cause an object to be recompiled and the source file is a temporary, the temporary is now reconstructed. Previously, headers weren't considered when deciding when to reconstruct a temporary. -d has been reworked to make it easier to display more useful tracing information separate from the debugging gunk: -da - show all actions (formerly -d2) -dc - show 'causes' for rebuilding (new output) -dd - show dependencies (new output) -dm - show make graph (aka -d3) -dx - show executable text (formerly -d2) -dd is new, and more display options are anticipated. -n now implies -dax. The message "...using xxx..." now only shows up with -da. Jam.html was extensively updated, in an attempt at lucidity. 3.4. Jam internal code changes Removed spurious search() in 'on' statement handling, thanks (again) to Ingo Weinhold. Fix 'includes' support so that included files aren't treated as direct dependencies during the command execution phase. If an included file failed to build, make1() would bypass the including file. Now make0() appends each child's 'includes' onto its own 'depends' list, eliminating 'includes'-specific code in make0() and make1(). Rewrite of the past: updated all jam's source with comments to reflect changes since about 2.3, very early 2001. 4. Fixed bugs Fixed the description of the :E modifier in Jam.html. Setting target-specific variables while under the influence of the target's target-specific variables caused the _global_ values to be modified. This happened both during header file scanning (HdrRule is called when target-specific variables are in effect) and with the "on target statement" syntax. Now setting target-specific variables works again. Thanks to Matt Armstrong. Setting "var on target ?= value" now works as expected: if the variable is already set on the target, it is left unchanged. Previously, ?= was ignored and the variable was set anyway. Thanks to Chris Antos. Variable expansion in actions has always put an extra blank space after the last list element, but the expansion is described in the code as "space separated". Now the last blank is suppressed to match. From Miklos Fazekas. The temp file name used by jam for .bat files on NT now contains jam's pid, so that multiple jams can run on the same system (with the same $TEMP). Thanks to Steve Anichini. Several uninitialized memory accesses have been corrected in var_expand() and file_archscan(), thanks to Matt Armstrong. 5. Porting The Makefile now uses $(EXENAME) (./jam0 on UNIX, .\jam0.exe on NT) instead of just "jam0", so that . doesn't need to be in your PATH to bootstrap. MACOSX updates: use 'ar' instead of libtool, as libtool can't update a library and we archive too many things to do it in one go; add piles of code to file_archscan() to handle new BSD4.4 style "#1/nnnn" archive entry names, where the real entry name follows the header and nnnn is the length of the name. The jam code underwent a const-ing, to work with compilers that don't like "" being passed as a non-const char *. Compiling on solaris w/ sparc now sets OSPLAT to "sparc". Previously, it suppressed this, assuming (wrongly) that sparc was the only solaris platform. Thanks to Michael Champigny . Jambase no longer announces the compiler it is using on Windows. It doesn't announce anything else, so why? Jambase no longer refers to advapi32.lib on NT, as it isn't needed for linking jam itself and it seems to move from release to release (of MS Visual Studio). Makefile/Jambase: BEOS updates from "Ingo Weinhold" . The NoCare rule can be used to suppress error messages when an 'include' file can't be found. AIX "big" archives are now supported, thanks to suggestions from Randy Roesler. MSVCDIR now works as well as MSVCNT for the Microsoft Visual C compiler directory. It changed names in VC 6.0. Thanks to Matt Armstrong. Allow jam to build with BorlandC 5.5 For WinXP IA64; set MSVCNT to the root of the SDK and MSVCVer to Win64; change handle type to long long (too much to include windows.h?); bury IA64 in the library path in Jambase. Mac classic MPW Codewarrior 7 upgrades: minor compiling issues, new paths in Jambase for libraries and includes, and separate out GenFile1 that sets PATH for UNIX only, as it does't work under MPW (or anything other than with sh). Minor Cray porting: make hashitem()'s key value unsigned so we're guaranteed no integer overflows. Remove NT FQuote rule, as, \" is required to pass quotes on the command line. Remove temp .bat files created on NT. They used to all have the same name and get reused, but with 2.5 the names were salted with the PID and they would litter $TEMP. Now they get removed after being used. =============================================================================== =============================================================================== Release notes for Jam 2.4 (aka Jam - make(1) redux) 1. Release info: Jam 2.4 March, 21, 2002 VERSION 2.4 2. Compatibility Jam 2.4 is upward compatible with Jam 2.3 The Jam 2.4 language is a superset of the 2.3 language; Jamfiles, Jambase, and other rulesets used in 2.3 can be used with the 2.4 language support. 3. Changes since 2.3. 3.1. Changes to Jam Language The mechanism for calling rules that return values - "[ rule args ...]", (and 'return' in the rule body), is now a documented part of the language. Add "on ..." syntax, to invoke a rule under the influence of a target's specific variables. Add "[ on targ rule ... ]" to call a rule returning a value, under the influence of a target's specific variables. New 'Glob' builtin that returns a list of files, given a list of directories, and a list of filename patterns. New 'while expr { block }' construct. New :E=value modifier provides default value if variable unset. New :J=joinval modifier concatenates list elements into single element, separated by joinval. \ can now be used to escape a space (or any single whitespace character), so that you don't have to resort to quotes. New 'Match regexp : string' rule matches regexp against string and returns list of results. Rules can now be invoked indirectly, through variable names. If the variable expands to an empty list, no rule is run. If the variable expands to multiple entries, each rule is run with the same arguments. The result of the rule invocation is the concatenation of the results of the rules invoked. 'Echo' and 'Exit' now have aliases 'echo' and 'exit', since it is really hard to tell that these are built-in rules and not part of the language, like 'include'. Real rules continue to start with a capital. 3.2. Jambase Changes Support for YACCGEN, the suffix used on generated yacc output. Fix ups to have jam and p4 build with borland C 5.5, and minor win98 jam support for jam clean SubDirHdrs now takes directory names in the same format as SubInclude : one directory element per word. More portable support for specifying includes and #defines: New ASHDRS, CCHDRS, CCDEFS, DEFINES, ObjectDefines, FQuote, FIncludes, FDefines. Ordering of cc and c++ flags grossly rearranged. Jambase has been compacted by applying the new E: and J: expansion modifiers. New SoftLink rule, courtesy of David Lindes. It currently assumes you can pass a -s flag to $(LN). 3.3 'jam' Changes (See Jam.html) Added '-q' (quit quick) option; jam will exit promptly (as if it received an interrupt), as soon as any target fails. Added experimental '-g' (build newest sources first) option: all things being equal, normally targets are simply built in the order they appear in the Jamfiles. With this flag, targets with the newest sources are built first. From an idea by Arnt Gulbrandsen. Undocumented (outside this note). 3.4. Jam internal code changes jamgram.yy now defines YYMAXDEPTH to 10000, what it is on FreeBSD, for older yaccs that left it at 150 or so. This is needed for the right-recursion now used in the grammar. Optimize rule compilation, with right-recursion instead of left. Split jam's built-in rules out to builtins.c from compile.c, so that compile.c only deals with the language. Split jam's pathsys.h from filesys.h, since they are really two different pieces. evaluate_if(), which evaluated the condition tree for 'if' and returned an int, has been replaced with compile_eval(), which does essentially the same but returns a LIST. 4. Fixed bugs Missing TEMPORARY targets with multiple parents no longer spoil one parent's time with another. The parents' time is used for comparison with dependents, but no longer taken on as the target's own time. 'actions updated', not 'actions together', now protects targets from being deleted on failed/interrupted updates. Fixed broken $(v[1-]), which always returned an empty expansion. Thanks to Ian Godin . Defining a rule within another rule, and invoking the enclosing rule more than once, would result in giving the first rule a null definition. Fixed. $(d:P) now works properly on the mac, climbing up directories. Thanks to Miklos Fazekas . No longer (sometimes) treat \ as a directory separator on UNIX. It isn't supposed to be, but was due to bungled ifdefs. Applying just :U or :D (or :E, :J) mods no longer causes the variable value to be treated as a filename (parsed and rebuilt using the OS specific pathsys routines). Previously, if _any_ mods were present then the value was parsed and rebuilt as if a filename, and that could in certain cases munge the value. Only the file modifiers (:GDBSM) treat the value as a filename. Four rules makeCommon, makeGrist, makeString, makeSubDir from jam 2.2 missing in 2.3 have been re-added, with apologies to dtb@cisco.com. Return status more likely to be correct when using -d0, now that targets are could as being built even with no debugging output. Thanks to Miklos Fazekas . yyacc now suffixes all terminals it defines with _t, so that they don't conflict with other symbols (like RULE with the typedef in rules.h). Thanks to Michael Allard. InstallInto now handles multiple sources properly, rather than acting as if each installed target depended on all sources to be installed. $(INSTALLGRIST) is now the default grist for installed targets, rather than the hardcoded 'installed'. Thanks to Stephen Goodson. 5. Porting [MACINTOSH] Paths are now downshifted (internally) so as to handle its case insensitivity. Thanks to Miklos Fazekas . [NT] MS changed the macro for the IA64 Windows NT 64bit compiler. [CYGWIN] Cygwin jam porting: dance around bison and yyacc. Use bison's -y flag to use yacc's output file naming conventions, and don't use yyacc on systems whose SUFEXE is set. [VMS] The Jambase itself was not formatting the CCHDRS and CCDEFS properly: on VMS they can't be appended to, because multiple /define or /include directives don't work. Instead now CCHDRS and CCDEFS is reformatted from HDRS and DEFINES anytime those latter two change. This requires the recent change to jam to allow access to target-specific variables when setting other variables. [VMS] Remove exception call when file_dirscan() can't, for some reason, scan a directory. Use a better set of #ifdefs to determine if we're on a vax, rather than relying on the C compiler being a specific version: we're able to build with the C++ compiler now. [VMS] Port new jam to run with just cxx compiler. (The C compiler being a extra-cost item). [NT] Add entry for DevStudio when the settings are already in the system environment. [NT] default $(MV) to "move /y" in Jambase. [MINGW] Mingw port by Max Blagai. =============================================================================== =============================================================================== Release notes for Jam 2.3 (aka Jam - make(1) redux) 0. Bugs fixed since 2.3.1 PATCHLEVEL 2 - 3/12/2001 NOCARE changed back: it once again does not applies to targets with sources and/or actions. In 2.3 it was changed to apply to such targets, but that broke header file builds: files that are #included get marked with NOCARE, but if they have source or actions, they still should get built. 1. Release info: Jam 2.3 November 16, 2000 VERSION 2.3 PATCHLEVEL 1 2. Compatibility Jam 2.3 is upward compatible with Jam 2.2. The Jam 2.3 language is a superset of the 2.2 language; Jamfiles, Jambase, and other rulesets used in 2.2 can be used with the 2.3 language support. 3. Changes since 2.2 3.1. Changes to Jam Language Rules now can have values, which can expanded into a list with the new "[ rule args ... ]" syntax. A rule's value is the value of its last statement, though only the following statements have values: if (value of the leg chosen), switch (ditto), set (value of the resulting variable), return (its arguments). Note that 'return' doesn't actually return. This support is EXPERIEMENTAL and otherwise undocumented. (2.3.1) Because of the new way lists are processed, if a rule has no targets a warning message is no longer issued. NOCARE now applies to targets with sources and/or actions, rather than just those without. 3.2. Jambase Changes The HDRPATTERN variable now allows for leading blanks before the #include, to keep up with ANSI. By john@nanaon-sha.co.jp (John Belmonte) (2.2.3). HDRPATTERN has been adjusted to avoid mistaking cases like: # include /* could be */ MkDir now NOUPDATE's $(DOT), so that there are no dependencies on the current directory's timestamp. By john@nanaon-sha.co.jp (John Belmonte). The old mock functions like makeDirName, which assigned their results to the variable named as their first argument, have been replaced with real functions using the new [] syntax. E.g. "makeDirName foo : bar ola" is now "foo = [ fDirName bar ]" Install now always does a cp/chmod/etc, rather than using the system's install(1), which invariably seems broken. 3.3. Jam internal code changes $JAMUNAME is set on UNIX. (2.2.4). Jam ANSI-fied (2.3.0). jam.h now defines a bunch of symbols used by the other source files, so as minimize compiler- and platform-specific ifdefs. OSVER is no longer set by jam.h (it was only set for AIX). Jam does not depend on this variable at all, except to set $(OSFULL), which is used to determine jam's build directory. If the user needs to distinguish between various revs of OSs, he must set OSVER in the environment. 4. Fixed bugs Redefining a rule while it was executing could cause jam to crash. Reference counts are now used to prevent that, thanks to Matt Armstrong. Logic for computing chunk size when executing PIECEMEAL rules has been reworked to be a little more accurate, without danger of overflow, at the cost of being a little more compute intensive. Instead of computing an estimate chunksize in the (now gone) make1chunk(), make1cmds() now just goes full bore and tries to use all args. When that fails, it backs off by 10% of the source args until the command fits. It takes a little bit more compute time compared to the old logic, but when you're executing actions to build all of Shinola it's still pretty small in the scheme of things. The NT handle leak in execunix.c has been fixed, thanks to Gurusamy Sarathy. (2.2.1). 5. Porting Platforms newly supported or updated: AmigaOS (with gcc), courtesy of Alain Penders (2.2.2). Beos CYGWIN 1.1.4, courtesy of John Belmonte . IBM AS400 via Visual Age on NT (primitive) IBM OS/390 Unix System Services Linux SuSE on OS390 Linux Mips, ARM Lynx HPUX 11, IA64 Mac OS X Server, courtesy of Jeff_Sickel@sickel.com (2.2.5). Mac Rhapsody MPE IX 6.0 NetBSD QNX RTP (QNX 6.0) Siemens Sinix UNICOS VMS 6.2, 7.1 Windows NT IA64 5.1. NT Porting Notes Always create tmp .bat file for actions if JAMSHELL is set. That way, if JAMSHELL is a .bat file itself, it can handle single-command actions with more than 9 cmd line args. COMSPEC is no longer examined: cmd.exe is always used instead. Only cmd.exe can execute the Jambase rules anyhow. Jam can be built with Borland C++ 5.5. OS2 fixes: InstallBin now works. Filenames are now downshifted, so mixed case works better there, too. file_dirscan() can now scan the root ("c:\" or "\") directory, which it couldn't handle before. var_defines now ignores OS=Windows_NT, because it conflicts with Jam's setting of OS (to NT). 5.2. Mac OS 8/9 Notes The support for Mac is curious at best. It runs under MPW. It requires CodeWarrior Pro 5, but no longer requires GUSI. Use Build.mpw to bootstrap the build. The Mac specific definitions in the Jambase are not intended to be of general purpose, but are sufficient to have Jam build itself. =============================================================================== =============================================================================== Release Notes for Jam 2.2 1. Release info: Jam 2.2 October 22, 1997 VERSION 2.2 PATCHLEVEL 1 2. Compatibility Jam 2.2 is a roll-up of 'Jam - make(1) redux' release 2.1+. Most of the changes described below were available before this, in the jam.2.1.plus.tar ball. The Jam 2.2 language is a superset of the 2.1 language; Jamfiles, Jambase, and other rulesets used in 2.1 can be used with the 2.2 language support. See 'Jambase Changes', below, to see if your Jamfiles need any changes to work with the 2.2 Jambase. 3. Changes Since 2.1 New product name: Jam. (Executable program is still named 'jam'.) Documentation rewritten; HTML versions supplied. 3.1 Changes to Jam Language Rules may now have more fields than just $(<) and $(>). Local variables are now supported. The expression 'if $(A) in $(B)' is now supported. New variable modifiers :U and :L result in uppercased or lowercased values. New variable modifier :P reliably results in parent directory of either a file or directory. (Previously, :D was used, but on VMS :D of a directory name is just the directory name.) The :S variable modifier now results in the _last_ suffix if a filename has more than one dot (.) in it. New predefined $(JAMDATE) variable is initialized at runtime for simple date stamping. New predefined variables $(OSVER) and $(OSPLAT) are used to distinguish among operating system versions and hardware platforms, when possible. New 'bind' qualifier on action definitions allows variables other than $(<) and $(>) to be bound with SEARCH and LOCATE paths. Action buffer size is no longer limited by MAXCMD. Instead, each line in an action is limited by MAXLINE, defined for each OS, and the entire action size is limited by CMDBUF. 3.2 Jambase Changes (See Jamfile.html) Jambase has been reworked to incorporate new language features. A handful of new utility rules has been added: makeString, makeDirName, etc. New HDRGRIST variable in Jambase allows for headers with the same name to be distinguished. LOCATE_TARGET now has a new flavor, LOCATE_SOURCE, that is used by rules that generate source files (e.g., Yacc and Lex). Header file includes now happen in the proper order. The limit of 10 include files has been eliminated. The old "Install" rule is no longer available. Use InstallBin, InstallFile, InstallLib, InstallMan, or InstallShell instead. 3.3 'jam' Changes (See Jam.html) 'jam' can now be built as a stand-alone program, with Jambase compiled into the executable. An external or alternate Jambase can still be referenced explicitly with -f. On command failure, 'jam' now emits the text of the command that failed. This is a compromise between the normal -d1 behavior (where commands were never seen) and -d2 (where commands are always seen). 'jam' now exits non-zero if it doesn't have a total success. A parse error, sources that can't be found, and targets that can't be built all generate non-zero exit status. The debugging levels (-d flags) have been slightly redefined. The supplied Jamfile now builds 'jam' into a platform specific subdirectory. This lets you use the same source directory to build 'jam' for more than one platform. The supplied Jamfile does not rebuild generated source files by default. (They are supplied with the distribution.) See Jamfile for more information. 4. Fixed Bugs The 'include' bug has finally been fixed, so that include statements take effect exactly when they are executed, rather than after the current statement block. This also corrects the problem where an 'include' within an 'if' block would wind up including the file one token after the 'if' block's closing brace. Credit goes to Thomas Woods for suggesting that the parse tree generation and parse tree execution be paired in their own loop, rather than having the parser execute the tree directly. The setting and extracting of grist has been regularized: normally, if you set a component of a filename (using the :DBSMG= modifiers), you are supposed to include the delimiters that set off the component: that is, you say "$(x:S=.suffix)", including the ".". But with grist it was inconsistent between setting and getting: setting grist required no <>'s, while getting grist included them. Getting grist continues to return the <>'s, but now setting grist can either include them (the new way) or not (the old way). 'actions together' now suppresses duplicate sources from showing up in $(>). Accessing variables whose names contained ['s (as happens with MkDir on VMS) wasn't working, because it treated the [ as an array subscript. Now [ and ] are, like :, handled specially so that they can appear in variable values. The 'if' statement now compares all elements in expressions; previously, it only compared the first element of each list. If a command line in an action is longer than MAXLINE (formerly MAXCMD), 'jam' now issues an error and exits rather than dumping core. If a Jamfile ended without a trailing newline, jam dumped core. This has been fixed. 5. Porting See jam.h for the definitive list of supported platforms. Since 2.1, support has been added for: Macintosh MPW Alpha VMS Alpha NT NT PowerPC BeOS MVS OE UNIXWARE QNX SINIX (Nixdorf) OS/2 Interactive UNIX (ISC), courtesy of Matthew Newhook 5.1 NT Support Fixes The NT command executor now handles multiple line actions, by writing multi-line actions to a batch file and executing that. Targets are universally lowercased on NT. (Matthew Newhook) Concurrent process support is fully enabled for NT. (Gurusamy Sarathy ) Path handling: Jam now knows that the directory component of "D:\" is "D:\", just as on unix it knows that the directory component of "/" is "/". It also now successfully gets the timestamp for "D:\" or just plain "\". 5.2 VMS Support Fixes VMS support is much, much better now. The path name manipulation routines (in pathvms.c) were more or less rewritten, and they now handle the vagaries of combining directory and file names properly. Targets are universally lowercased on VMS. Multi-line command blocks on VMS are now executed in a single system() call rather than separate ones for each line, so that actions can be DCL scripts. =============================================================================== =============================================================================== Release notes for Jam 2.1. 1. Release info: Jam 2.1 February 1, 1996 VERSION 2.1 PATCHLEVEL 0 2. Porting Linux is now supported. FREEBSD is now supported. SCO ("M_XENIX") now supported. NCR now supported. NEXT support from karthy@dannug.dk (Karsten Thygesen) DECC support from zinser@axp614.gsi.de (Martin P.J. Zinser) I have changes for OS/2, but no way to test them. Volunteers? I have VMS multiprocess support, but no way to test it. Volunteers? 2.1. NT Support fixes. The NT support is considerably more real than it was in 2.0. Filent.c had its syntax error corrected, it no longer skips the first entry when scanning directories, and it handles string tables in archives (for long object file names). The Jambase was changed a bit to support the various C/C++ compilers on NT, although it has only been thorougly tested with MSVC20. You still need to set MSVCNT or BCCROOT to the root of the the compiler's directory tree, and you'll get an error if you don't set it (rather than getting a pile of mysterious errors). 2.2. Other porting fixes. SPLITPATH now set up for UNIX (:), NT (;), VMS (,) Jambase support for Solaris works better now: the location of AR is hardwired to /usr/ccs/bin/ar and it knowns "install" doesn't take -c. Solaris -- how the mighty have fallen. To handle Linux's wacko yacc, jamgram.h is now included after scan.h so that YYSTYPE is define. 3. Jambase Changes (see Jamfile.html) SubDir now computes the root directory for the source tree, if the variable naming the root directory isn't set in the environment. It counts the number of directory elements leading from the root to the current directory (as passed to SubDir) and uses that many "../"'s to identify the root. This means that to use SubDir you no longer have to have anything special set in the environment. InstallFile is now an alias for InstallLib. 'first' is now dependency of all pseudo-targets (all, files, exe, lib, shell), so that jamming any of these pseudo-targets also builds any dependencies of 'first'. The File rule definition in the Jambase was missing an &. The File rule now calls the Clean rule, so that installed files get cleaned. 4. Jam changes (see Jam.html) Variables may now be set on the command line with -svar=value. Targets marked with NOUPDATE are now immune to the -a (anyhow) flag. Previously, the MkDir rule would try to recreate directories that already exist when jam was invoked with -a. A new variable, $(JAMVERSION), joins the small list of built-in variables. It it set to the release of jam, currently "2.1". If an actions fails, jam now deletes the target(s). It won't delete libraries or other targets that are composites. This is now consistent with jam's behavior on interrupts (it deletes the targets). Jam had a nasty bug when setting multiple variables to the same value: if the first two variable names were the same, the variable value got trashed. This also affected "on target" variables if the first two targets were the same. For example: FOO on bar.c bar.c foo.c = a b c ; This would mangle the value of FOO for bar.c and foo.c. This has been fixed. Jam would generate bogus numbers when reporting the number of targets updated after an interrupt. It now is more careful about counting. The debugging flag -d has been extended. In addition to supporting -dx (turn on debugging for all levels up to x) there is also now -d+x (turn on debugging at only level x). The default output level is -d1 (-or d2 if -n is given); this can be turned off with -d0. The debug levels are listed in jam.1 and jam.h. The parsing debug output now uses indenting to indicate when one rule invokes another. =============================================================================== =============================================================================== Release notes for Jam 2.0. 1. Release info: Jam 2.0 March 10, 1994 VERSION 2.0 PATCHLEVEL 5 2. Porting Windows/NT is now (crudely) supported, courtesy of Brett Taylor and Laura Wingerd. COHERENT/386 is now supported, courtesy of Fred Smith. Solaris archive string table for long archive names is now supported, thanks to Mike Matrigali. 3. Compatibility Jam 2.0 syntax is a superset of Jam 1.0 syntax, and thus it can interpret a Jam 1.0 Jambase. The Jam 2.0 Jambase is a superset of the Jam 1.0 Jambase, and thus it can include a Jamfile written for Jam 1.0. 4. Changes from Jam 1.0 to Jam 2.0 4.1. Documentation changes New Jamfile.5 manual page, with lots of examples and easy reading. It replaces both the old "Examples" file as well as the old Jambase.5 manual page. jam.1 edited by Stephen W. Liddle and Diane Holt. 4.2. Jambase Changes (see Jamfile.5) 4.2.1. New rules: There are new rules to make handling subdirectories easier: SubDir, SubInclude, SubDirCcFlags, SubDirHdrs. There are new rules to handle file-specific CCFLAGS and HDRS: ObjectCcFlags and ObjectHdrs. Misc new rules: HardLink, InstallShell, MkDir. New rule "clean" that deletes exactly what jam has built, and "uninstall" that deletes exactly what was installed. New rules for handling suffixes .s, .f, .cc, .cpp, .C. 4.2.2. Old rules: The InstallBin, Lib, Man, and the new Shell rules now take the destination directory as the target and the files to be copied as sources. These rules formerly took the files to be copied as targets, and used built-in destination directories of $(BINDIR), $(LIBDIR), $(MANDIR), and $(BINDIR). The InstallBin, Lib, Man, and Shell rules use the install(1) program now, instead of doing their own copying. The Cc rule now uses -o when possible, rather than moving the result. Some platforms (Pyramid?) have a broken -o. Jambase rules taking libraries, objects, and executables now all ignore the suffixes provided and use the one defined in the Jambase for the platform. Stupid yyacc support moved out of Jambase, as jam is its only likely user. Jambase now purturbs library sources with a "grist" of SOURCE_GRIST. 4.2.3. Misc: The names of the default rules defined in Jambase have been lowercased and un-abbreviated, to be more imake(1) like. The Jambase has been reorganized and sorted, with VMS and NT support moved in from their own files. The Jambase has been relocated on UNIX from /usr/local/lib/jam to /usr/local/lib. 4.3. Jam changes (see jam.1) 4.3.1. Flags: New -a (anyhow) flag: means build everything. New -j flag: run jobs in parallel. Old -t now rebuilds the touched target, rather that just the target's parents. -n now implies -d2, so that you see what's happening. The debug level can be subsequently overridden. New -v to dump version. 4.3.2. Rules: New ALWAYS rule behaves like -t: always builds target. New EXIT rule makes it possible to raise a fatal error. New LEAVES rule which say target depends only on the update times of the leaf sources. New NOUPDATE rule says built targets only if they don't exist. NOTIME has been renamed NOTFILE, to more accurately reflect its meaning (it says a target is not to be bound to a file). 4.3.3. Variables: New special variable JAMSHELL: argv template for command execution shell. Variables, both normal and target-specific, can have their value appended with the syntax "var += value" or "var on target += value". "?=" is now synonymous with "default =". Imported enviroment variable values are now split at blanks (:'s if the variable name ends in PATH), so that they become proper list values. 4.3.4. Misc: Files to be sourced with "include" are now bound first, so $(SEARCH) and $(LOCATE) affect them. They still can't be built, though. New modifier on "actions": "existing" causes $(>) to expand only those files that currently exist. 4.3.5. Bug fixes: When scanning tokens known to be argument lists (such as the arguments to rule invocations and variable assignment), the parser now tells the scanner to ignore alphabetic keywords, as all such lists terminate with punctuation keywords (like : or ;). This way, alphabetic keywords don't need to be quoted when they appear as arguments. The scanner has been fixed to handle oversized tokens, unterminated quotes, unterminated action blocks, and tokens abutting EOF (i.e. a token with no white space before EOF). The progress report "...on xth target..." used to count all targets, rather than just those with updating actions. Since the original pronouncement of targets to be udpated included only those with updating actions, the progress report has been changed to match. 'If' conditionals now must be single arguments. Previously, they could be zero or more arguments, which didn't make much sense, and made things like 'foo == bar' true. The comparison operator is '=', and '==' just looked like the second of three arguments in the unary "non-empty argument list" conditional. Header files indirectly including themselves were mistakenly reported as being dependent on themselves. Recursing through header file dependencies is now done after determining the fate of the target. The variable expansion support was expanding $(X)$(UNDEF) as if it were $(X). It now expands to an empty list, like it should. The UNIX version of file_build() didn't handle "dir/.suffix" right. Now it does. The VMS command buffer was assumed to be as large as 1024 bytes, which isn't the case everywhere as it is related to some weird quota. It has been lowered to 256. $(>) and $(<) wouldn't expand in action blocks if the targets were marked with NOTIME. Now they expand properly. Malloc() return values are now checked. The variable expansion routine var_expand() is now a little faster, by taking a few often needed shortcuts. The VMS version of file_build() used the wrong length when re-rooting file names that already had directory compoents. This was fixed. Various tracing adjustments were made. 5. Limitations/Known Bugs The new Windows/NT support has only been marginally tested. It is dependent on certain variables being set depending on which compiler you are using. You'll need to look in the file Jambase and see what variables are expected to be set. The VMS support has been tested, courtesy of the DEC guest machine, but has not been hammered fully in release 2.0. It was used quite a bit in Jam 1.0. Jam clean when there is nothing to clean claims it is updating a target. Because the include statement works by pushing a new file in the input stream of the scanner rather than recursively invoking the parser on the new file, multiple include statements in a rule's procedure causes the files to be included in reverse order. If the include statement appears inside an if block, the parser's attempt to find the else will cause the text of the included file to appear after the first token following the statement block. This is rarely what is intended. In a rule's actions, only $(<) and $(>) refer to the bound file names: all other variable references get the unbound names. This is a pain for $(NEEDLIBS), because it means that library path can't be bound using $(SEARCH) and $(LOCATE). With the -j flag, errors from failed commands can get staggeringly mixed up. Also, because targets tend to get built in a quickest-first ordering, dependency information must be quite exact. Finally, beware of parallelizing commands that drop fixed-named files into the current directory, like yacc(1) does. A poorly set $(JAMSHELL) is likely to result in silent failure. ftjam-2.5.2/jam.h0000744000424500003730000002626010441006325013335 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * jam.h - includes and globals for jam * * 04/08/94 (seiwald) - Coherent/386 support added. * 04/21/94 (seiwald) - DGUX is __DGUX__, not just __DGUX. * 05/04/94 (seiwald) - new globs.jobs (-j jobs) * 11/01/94 (wingerd) - let us define path of Jambase at compile time. * 12/30/94 (wingerd) - changed command buffer size for NT (MS-DOS shell). * 02/22/95 (seiwald) - Jambase now in /usr/local/lib. * 04/30/95 (seiwald) - FreeBSD added. Live Free or Die. * 05/10/95 (seiwald) - SPLITPATH character set up here. * 08/20/95 (seiwald) - added LINUX. * 08/21/95 (seiwald) - added NCR. * 10/23/95 (seiwald) - added SCO. * 01/03/96 (seiwald) - SINIX (nixdorf) added. * 03/13/96 (seiwald) - Jambase now compiled in; remove JAMBASE variable. * 04/29/96 (seiwald) - AIX now has 31 and 42 OSVERs. * 11/21/96 (peterk) - added BeOS with MW CW mwcc * 12/21/96 (seiwald) - OSPLAT now defined for NT. * 07/19/99 (sickel) - Mac OS X Server and Client support added * 02/22/01 (seiwald) - downshift paths on case-insensitive macintosh * 03/23/01 (seiwald) - VMS C++ changes. * 10/29/01 (brett) - More IA64 ifdefs for MS. * 02/18/00 (belmonte)- Support for Cygwin. * 09/12/00 (seiwald) - OSSYMS split to OSMAJOR/OSMINOR/OSPLAT * 12/29/00 (seiwald) - OSVER dropped. * 01/21/02 (seiwald) - new -q to quit quickly on build failure * 03/16/02 (seiwald) - support for -g (reorder builds by source time) * 03/20/02 (seiwald) - MINGW porting from Max Blagai * 08/16/02 (seiwald) - BEOS porting from Ingo Weinhold * 09/19/02 (seiwald) - new -d displays * 11/05/02 (seiwald) - OSPLAT now set to sparc on solaris. */ /* * VMS, OPENVMS */ # ifdef VMS # define unlink remove # include # include # include # include # include # include # include # include # include # include # define OSMINOR "OS=VMS" # define OSMAJOR "VMS=true" # define OS_VMS # define MAXLINE 1024 /* longest 'together' actions */ # define SPLITPATH ',' # define EXITOK 1 # define EXITBAD 0 # define DOWNSHIFT_PATHS /* Do any of these work? */ # if defined( VAX ) || defined( __VAX ) || defined( vax ) # define OSPLAT "OSPLAT=VAX" # endif # endif /* * Windows NT */ # ifdef NT # include # include # include # include # include # include # include # include # include # define OSMAJOR "NT=true" # define OSMINOR "OS=NT" # define OS_NT # define SPLITPATH ';' # define MAXLINE 2046 /* longest 'together' actions */ # define USE_EXECUNIX # define USE_PATHUNIX # define PATH_DELIM '\\' # define DOWNSHIFT_PATHS /* AS400 cross-compile from NT */ # ifdef AS400 # undef OSMINOR # undef OSMAJOR # define OSMAJOR "AS400=true" # define OSMINOR "OS=AS400" # define OS_AS400 # endif # endif /* * Windows MingW32 */ # ifdef MINGW # include # include # include # include # include # include # include # include # include # define OSMAJOR "MINGW=true" # define OSMINOR "OS=MINGW" # define OS_NT # define SPLITPATH ';' # define MAXLINE 996 /* longest 'together' actions */ # define USE_EXECUNIX # define USE_PATHUNIX # define PATH_DELIM '\\' # define DOWNSHIFT_PATHS # endif /* * OS2 */ # ifdef __OS2__ # include # include # include # include # include # include # include # include # define OSMAJOR "OS2=true" # define OSMINOR "OS=OS2" # define OS_OS2 # define SPLITPATH ';' # define MAXLINE 996 /* longest 'together' actions */ # define USE_EXECUNIX # define USE_PATHUNIX # define PATH_DELIM '\\' # define DOWNSHIFT_PATHS # endif /* * Macintosh MPW */ # ifdef macintosh # include # include # include # include # include # define OSMAJOR "MAC=true" # define OSMINOR "OS=MAC" # define OS_MAC # define SPLITPATH ',' # define DOWNSHIFT_PATHS # endif /* * God fearing UNIX */ # ifndef OSMINOR # define OSMAJOR "UNIX=true" # define USE_EXECUNIX # define USE_FILEUNIX # define USE_PATHUNIX # define PATH_DELIM '/' # ifdef _AIX # define unix # define OSMINOR "OS=AIX" # define OS_AIX # define NO_VFORK # endif # ifdef AMIGA # define OSMINOR "OS=AMIGA" # define OS_AMIGA # endif # ifdef __BEOS__ # define unix # define OSMINOR "OS=BEOS" # define OS_BEOS # define NO_VFORK # endif # ifdef __bsdi__ # define OSMINOR "OS=BSDI" # define OS_BSDI # endif # if defined (COHERENT) && defined (_I386) # define OSMINOR "OS=COHERENT" # define OS_COHERENT # define NO_VFORK # endif # ifdef __cygwin__ # define OSMINOR "OS=CYGWIN" # define OS_CYGWIN # endif # ifdef __FreeBSD__ # define OSMINOR "OS=FREEBSD" # define OS_FREEBSD # endif # ifdef __DGUX__ # define OSMINOR "OS=DGUX" # define OS_DGUX # endif # ifdef __hpux # define OSMINOR "OS=HPUX" # define OS_HPUX # endif # ifdef __OPENNT # define unix # define OSMINOR "OS=INTERIX" # define OS_INTERIX # define NO_VFORK # endif # ifdef __sgi # define OSMINOR "OS=IRIX" # define OS_IRIX # define NO_VFORK # endif # ifdef __ISC # define OSMINOR "OS=ISC" # define OS_ISC # define NO_VFORK # endif # ifdef linux # define OSMINOR "OS=LINUX" # define OS_LINUX # endif # ifdef __Lynx__ # define OSMINOR "OS=LYNX" # define OS_LYNX # define NO_VFORK # define unix # endif # ifdef __MACHTEN__ # define OSMINOR "OS=MACHTEN" # define OS_MACHTEN # endif # ifdef mpeix # define unix # define OSMINOR "OS=MPEIX" # define OS_MPEIX # define NO_VFORK # endif # ifdef __MVS__ # define unix # define OSMINOR "OS=MVS" # define OS_MVS # endif # ifdef _ATT4 # define OSMINOR "OS=NCR" # define OS_NCR # endif # ifdef __NetBSD__ # define unix # define OSMINOR "OS=NETBSD" # define OS_NETBSD # define NO_VFORK # endif # ifdef __QNX__ # ifdef __QNXNTO__ # define OSMINOR "OS=QNXNTO" # define OS_QNXNTO # else # define unix # define OSMINOR "OS=QNX" # define OS_QNX # define NO_VFORK # define MAXLINE 996 # endif # endif # ifdef NeXT # ifdef __APPLE__ # define OSMINOR "OS=RHAPSODY" # define OS_RHAPSODY # else # define OSMINOR "OS=NEXT" # define OS_NEXT # endif # endif # ifdef __APPLE__ # define unix # define OSMINOR "OS=MACOSX" # define OS_MACOSX # endif # ifdef __osf__ # define OSMINOR "OS=OSF" # define OS_OSF # endif # ifdef _SEQUENT_ # define OSMINOR "OS=PTX" # define OS_PTX # endif # ifdef M_XENIX # define OSMINOR "OS=SCO" # define OS_SCO # define NO_VFORK # endif # ifdef sinix # define unix # define OSMINOR "OS=SINIX" # define OS_SINIX # endif # ifdef sun # if defined(__svr4__) || defined(__SVR4) # define OSMINOR "OS=SOLARIS" # define OS_SOLARIS # else # define OSMINOR "OS=SUNOS" # define OS_SUNOS # endif # endif # ifdef ultrix # define OSMINOR "OS=ULTRIX" # define OS_ULTRIX # endif # ifdef _UNICOS # define OSMINOR "OS=UNICOS" # define OS_UNICOS # endif # if defined(__USLC__) && !defined(M_XENIX) # define OSMINOR "OS=UNIXWARE" # define OS_UNIXWARE # endif # ifndef OSMINOR # define OSMINOR "OS=UNKNOWN" # endif /* All the UNIX includes */ # include # include # ifndef OS_MPEIX # include # endif # include # include # include # include # include # include # ifndef OS_QNX # include # endif # ifndef OS_ULTRIX # include # endif # if !defined(OS_BSDI) && \ !defined(OS_FREEBSD) && \ !defined(OS_NEXT) && \ !defined(OS_MACHTEN) && \ !defined(OS_MACOSX) && \ !defined(OS_RHAPSODY) && \ !defined(OS_MVS) # include # endif # endif /* * OSPLAT definitions - suppressed when it's a one-of-a-kind */ # if defined( _M_PPC ) || \ defined( PPC ) || \ defined( ppc ) || \ defined( __powerpc__ ) || \ defined( __POWERPC__ ) || \ defined( __ppc__ ) # define OSPLAT "OSPLAT=PPC" # endif # if defined( _ALPHA_ ) || \ defined( __alpha__ ) # define OSPLAT "OSPLAT=AXP" # endif # if defined( _i386_ ) || \ defined( __i386__ ) || \ defined( _M_IX86 ) # if !defined( OS_FREEBSD ) && \ !defined( OS_OS2 ) && \ !defined( OS_AS400 ) # define OSPLAT "OSPLAT=X86" # endif # endif # ifdef __sparc__ # if !defined( OS_SUNOS ) # define OSPLAT "OSPLAT=SPARC" # endif # endif # ifdef __mips__ # if !defined( OS_SGI ) # define OSPLAT "OSPLAT=MIPS" # endif # endif # ifdef __arm__ # define OSPLAT "OSPLAT=ARM" # endif # if defined( __ia64__ ) || \ defined( __IA64__ ) || \ defined( _M_IA64 ) # define OSPLAT "OSPLAT=IA64" # endif # ifdef __s390__ # define OSPLAT "OSPLAT=390" # endif # ifndef OSPLAT # define OSPLAT "" # endif /* * Jam implementation misc. */ # ifndef MAXLINE # define MAXLINE 10240 /* longest 'together' actions' */ # endif # ifndef EXITOK # define EXITOK 0 # define EXITBAD 1 # endif # ifndef SPLITPATH # define SPLITPATH ':' # endif /* You probably don't need to muck with these. */ # define MAXSYM 1024 /* longest symbol in the environment */ # define MAXJPATH 1024 /* longest filename */ # define MAXJOBS 64 /* silently enforce -j limit */ # define MAXARGC 32 /* words in $(JAMSHELL) */ /* Jam private definitions below. */ # define DEBUG_MAX 15 struct globs { int noexec; int jobs; int quitquick; int newestfirst; /* build newest sources first */ char debug[DEBUG_MAX]; FILE *cmdout; /* print cmds, not run them */ } ; extern struct globs globs; # define DEBUG_MAKE ( globs.debug[ 1 ] ) /* -da show actions when executed */ # define DEBUG_MAKEPROG ( globs.debug[ 3 ] ) /* -dm show progress of make0 */ # define DEBUG_EXECCMD ( globs.debug[ 4 ] ) /* show execcmds()'s work */ # define DEBUG_COMPILE ( globs.debug[ 5 ] ) /* show rule invocations */ # define DEBUG_HEADER ( globs.debug[ 6 ] ) /* show result of header scan */ # define DEBUG_BINDSCAN ( globs.debug[ 6 ] ) /* show result of dir scan */ # define DEBUG_SEARCH ( globs.debug[ 6 ] ) /* show attempts at binding */ # define DEBUG_VARSET ( globs.debug[ 7 ] ) /* show variable settings */ # define DEBUG_VARGET ( globs.debug[ 8 ] ) /* show variable fetches */ # define DEBUG_VAREXP ( globs.debug[ 8 ] ) /* show variable expansions */ # define DEBUG_IF ( globs.debug[ 8 ] ) /* show 'if' calculations */ # define DEBUG_LISTS ( globs.debug[ 9 ] ) /* show list manipulation */ # define DEBUG_SCAN ( globs.debug[ 9 ] ) /* show scanner tokens */ # define DEBUG_MEM ( globs.debug[ 9 ] ) /* show memory use */ # define DEBUG_MAKEQ ( globs.debug[ 11 ] ) /* -da show even quiet actions */ # define DEBUG_EXEC ( globs.debug[ 12 ] ) /* -dx show text of actions */ # define DEBUG_DEPENDS ( globs.debug[ 13 ] ) /* -dd show dependency graph */ # define DEBUG_CAUSES ( globs.debug[ 14 ] ) /* -dc show dependency graph */ ftjam-2.5.2/pathmac.c0000744000424500003730000001476610441006326014207 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * pathunix.c - manipulate file names on UNIX, NT, OS2 * * External routines: * * path_parse() - split a file name into dir/base/suffix/member * path_build() - build a filename given dir/base/suffix/member * path_parent() - make a PATHNAME point to its parent dir * * File_parse() and path_build() just manipuate a string and a structure; * they do not make system calls. * * 04/08/94 (seiwald) - Coherent/386 support added. * 12/26/93 (seiwald) - handle dir/.suffix properly in path_build() * 12/19/94 (mikem) - solaris string table insanity support * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way. * 02/14/95 (seiwald) - parse and build /xxx properly * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we * should expect hdr searches to come up with strings * like "thing/thing.h". So we need to test for "/" as * well as "\" when parsing pathnames. * 03/16/95 (seiwald) - fixed accursed typo on line 69. * 05/03/96 (seiwald) - split from filent.c, fileunix.c * 12/20/96 (seiwald) - when looking for the rightmost . in a file name, * don't include the archive member name. * 01/10/01 (seiwald) - path_parse now strips the trailing : from the * directory name, unless the directory name is all * :'s, so that $(d:P) works. * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "pathsys.h" # ifdef OS_MAC # define DELIM ':' /* * path_parse() - split a file name into dir/base/suffix/member */ void path_parse( const char *file, PATHNAME *f ) { const char *p, *q; const char *end; memset( (char *)f, 0, sizeof( *f ) ); /* Look for */ if( file[0] == '<' && ( p = strchr( file, '>' ) ) ) { f->f_grist.ptr = file; f->f_grist.len = p - file; file = p + 1; } /* Look for dir: */ if( p = strrchr( file, DELIM ) ) { f->f_dir.ptr = file; f->f_dir.len = p - file; file = p + 1; /* All :'s? Include last : as part of directory name */ while( p > f->f_dir.ptr && *--p == DELIM ) ; if( p == f->f_dir.ptr ) f->f_dir.len++; } end = file + strlen( file ); /* Look for (member) */ if( ( p = strchr( file, '(' ) ) && end[-1] == ')' ) { f->f_member.ptr = p + 1; f->f_member.len = end - p - 2; end = p; } /* Look for .suffix */ /* This would be memrchr() */ p = 0; q = file; while( q = memchr( q, '.', end - q ) ) p = q++; if( p ) { f->f_suffix.ptr = p; f->f_suffix.len = end - p; end = p; } /* Leaves base */ f->f_base.ptr = file; f->f_base.len = end - file; } /* * path_build() - build a filename given dir/base/suffix/member */ # define DIR_EMPTY 0 /* "" */ # define DIR_DOT 1 /* : */ # define DIR_DOTDOT 2 /* :: */ # define DIR_ABS 3 /* dira:dirb: */ # define DIR_REL 4 /* :dira:dirb: */ # define G_DIR 0 /* take dir */ # define G_ROOT 1 /* take root */ # define G_CAT 2 /* prepend root to dir */ # define G_DTDR 3 /* :: of rel dir */ # define G_DDDD 4 /* make it ::: (../..) */ # define G_MT 5 /* leave it empty */ char grid[5][5] = { /* EMPTY DOT DOTDOT ABS REL */ /* EMPTY */ { G_MT, G_DIR, G_DIR, G_DIR, G_DIR }, /* DOT */ { G_ROOT, G_DIR, G_DIR, G_DIR, G_DIR }, /* DOTDOT */ { G_ROOT, G_ROOT, G_DDDD, G_DIR, G_DTDR }, /* ABS */ { G_ROOT, G_ROOT, G_ROOT, G_DIR, G_CAT }, /* REL */ { G_ROOT, G_ROOT, G_ROOT, G_DIR, G_CAT } } ; static int file_flags( const char *ptr, int len ) { if( !len ) return DIR_EMPTY; if( len == 1 && ptr[0] == DELIM ) return DIR_DOT; if( len == 2 && ptr[0] == DELIM && ptr[1] == DELIM ) return DIR_DOTDOT; if( ptr[0] == DELIM ) return DIR_REL; return DIR_ABS; } void path_build( PATHNAME *f, char *file, int binding ) { char *ofile = file; int dflag, rflag, act; if( DEBUG_SEARCH ) { printf("build file: "); if( f->f_root.len ) printf( "root = '%.*s' ", f->f_root.len, f->f_root.ptr ); if( f->f_dir.len ) printf( "dir = '%.*s' ", f->f_dir.len, f->f_dir.ptr ); if( f->f_base.len ) printf( "base = '%.*s' ", f->f_base.len, f->f_base.ptr ); } /* Start with the grist. If the current grist isn't */ /* surrounded by <>'s, add them. */ if( f->f_grist.len ) { if( f->f_grist.ptr[0] != '<' ) *file++ = '<'; memcpy( file, f->f_grist.ptr, f->f_grist.len ); file += f->f_grist.len; if( file[-1] != '>' ) *file++ = '>'; } /* Combine root & directory, according to the grid. */ dflag = file_flags( f->f_dir.ptr, f->f_dir.len ); rflag = file_flags( f->f_root.ptr, f->f_root.len ); switch( act = grid[ rflag ][ dflag ] ) { case G_DTDR: /* :: of rel dir */ *file++ = DELIM; /* fall through */ case G_DIR: /* take dir */ memcpy( file, f->f_dir.ptr, f->f_dir.len ); file += f->f_dir.len; break; case G_ROOT: /* take root */ memcpy( file, f->f_root.ptr, f->f_root.len ); file += f->f_root.len; break; case G_CAT: /* prepend root to dir */ memcpy( file, f->f_root.ptr, f->f_root.len ); file += f->f_root.len; if( file[-1] == DELIM ) --file; memcpy( file, f->f_dir.ptr, f->f_dir.len ); file += f->f_dir.len; break; case G_DDDD: /* make it ::: (../..) */ strcpy( file, ":::" ); file += 3; break; } /* Put : between dir and file (if none already) */ if( act != G_MT && file[-1] != DELIM && ( f->f_base.len || f->f_suffix.len ) ) { *file++ = DELIM; } if( f->f_base.len ) { memcpy( file, f->f_base.ptr, f->f_base.len ); file += f->f_base.len; } if( f->f_suffix.len ) { memcpy( file, f->f_suffix.ptr, f->f_suffix.len ); file += f->f_suffix.len; } if( f->f_member.len ) { *file++ = '('; memcpy( file, f->f_member.ptr, f->f_member.len ); file += f->f_member.len; *file++ = ')'; } *file = 0; if( DEBUG_SEARCH ) printf(" -> '%s'\n", ofile); } /* * path_parent() - make a PATHNAME point to its parent dir */ void path_parent( PATHNAME *f ) { /* just set everything else to nothing */ f->f_base.ptr = f->f_suffix.ptr = f->f_member.ptr = ""; f->f_base.len = f->f_suffix.len = f->f_member.len = 0; } # endif /* OS_MAC */ ftjam-2.5.2/option.h0000744000424500003730000000117410441006326014074 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * option.h - command line option processing * * {o >o * \ -) "Command line option." * * 11/04/02 (seiwald) - const-ing for string literals */ typedef struct option { char flag; /* filled in by getoption() */ const char *val; /* set to random address if true */ } option; # define N_OPTS 256 # define N_TARGETS 256 int getoptions( int argc, char **argv, const char *opts, option *optv, char** targets ); const char * getoptval( option *optv, char opt, int subopt ); ftjam-2.5.2/execcmd.h0000744000424500003730000000067410441006326014200 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * execcmd.h - execute a shell script * * 05/04/94 (seiwald) - async multiprocess interface */ void execcmd( char *string, void (*func)( void *closure, int status ), void *closure, LIST *shell ); int execwait(); # define EXEC_CMD_OK 0 # define EXEC_CMD_FAIL 1 # define EXEC_CMD_INTR 2 ftjam-2.5.2/Jambase0000744000424500003730000026072210441006327013707 0ustar dturnermhpsys# # /+\ # +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. # \+/ # # This file is part of Jam - see jam.c for Copyright information. # # # JAMBASE - jam 2.5 ruleset providing make(1)-like functionality # # Supports UNIX, NT, and VMS. # # 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST # 04/18/94 (seiwald) - use '?=' when setting OS specific vars # 04/21/94 (seiwald) - do RmTemps together # 05/05/94 (seiwald) - all supported C compilers support -o: relegate # RELOCATE as an option; set Ranlib to "" to disable it # 06/01/94 (seiwald) - new 'actions existing' to do existing sources # 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS # 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS # 09/19/94 (seiwald) - LinkLibraries and Undefs now append # - Rule names downshifted. # 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile. # 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files. # 01/08/95 (seiwald) - Shell now handled with awk, not sed # 01/09/95 (seiwald) - Install* now take dest directory as target # 01/10/95 (seiwald) - All entries sorted. # 01/10/95 (seiwald) - NT support moved in, with LauraW's help. # 01/10/95 (seiwald) - VMS support moved in. # 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added. # 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE. # 02/08/95 (seiwald) - SubDir works on VMS. # 02/14/95 (seiwald) - MkDir and entourage. # 04/30/95 (seiwald) - Use install -c flag so that it copies, not moves. # 07/10/95 (taylor) - Support for Microsoft C++. # 11/21/96 (peterk) - Support for BeOS # 07/19/99 (sickel) - Support for Mac OS X Server (and maybe client) # 02/18/00 (belmonte)- Support for Cygwin. # Special targets defined in this file: # # all - parent of first, shell, files, lib, exe # first - first dependent of 'all', for potential initialization # shell - parent of all Shell targets # files - parent of all File targets # lib - parent of all Library targets # exe - parent of all Main targets # dirs - parent of all MkDir targets # clean - removes all Shell, File, Library, and Main targets # uninstall - removes all Install targets # # Rules defined by this file: # # as obj.o : source.s ; .s -> .o # Bulk dir : files ; populate directory with many files # Cc obj.o : source.c ; .c -> .o # C++ obj.o : source.cc ; .cc -> .o # Clean clean : sources ; remove sources with 'jam clean' # File dest : source ; copy file # Fortran obj.o : source.f ; .f -> .o # GenFile source.c : program args ; make custom file # HardLink target : source ; make link from source to target # HdrRule source : headers ; handle #includes # InstallInto dir : sources ; install any files # InstallBin dir : sources ; install binaries # InstallLib dir : sources ; install files # InstallFile dir : sources ; install files # InstallMan dir : sources ; install man pages # InstallShell dir : sources ; install shell scripts # Lex source.c : source.l ; .l -> .c # Library lib : source ; archive library from compiled sources # LibraryFromObjects lib : objects ; archive library from objects # LinkLibraries images : libraries ; bag libraries onto Mains # Main image : source ; link executable from compiled sources # MainFromObjects image : objects ; link executable from objects # MkDir dir ; make a directory, if not there # Object object : source ; compile object from source # ObjectCcFlags source : flags ; add compiler flags for object # ObjectC++Flags source : flags ; add compiler flags for object # ObjectHdrs source : dirs ; add include directories for object # Objects sources ; compile sources # RmTemps target : sources ; remove temp sources after target made # Setuid images ; mark executables Setuid # SoftLink target : source ; make symlink from source to target # SubDir TOP d1 d2 ... ; start a subdirectory Jamfile # SubDirCcFlags flags ; add compiler flags until next SubDir # SubDirC++Flags flags ; add compiler flags until next SubDir # SubDirHdrs d1 d2 ... ; add include dir until next SubDir # SubInclude TOP d1 d2 ... ; include a subdirectory Jamfile # Shell exe : source ; make a shell executable # Undefines images : symbols ; save undef's for linking # UserObject object : source ; handle unknown suffixes for Object # Yacc source.c : source.y ; .y -> .c # # Utility rules that have no side effects (not supported): # # FAppendSuffix f1 f2 ... : $(SUF) ; return $(<) with suffixes # FDirName d1 d2 ... ; return path from root to dir # FGrist d1 d2 ... ; return d1!d2!... # FGristFiles value ; return $(value:G=$(SOURCE_GRIST)) # FGristSourceFiles value ; return $(value:G=$(SOURCE_GRIST)) # FStripCommon v1 : v2 ; strip common initial parts of v1 v2 # FReverse a1 a2 ... ; return ... a2 a1 # FRelPath d1 : d2 ; return rel path from d1 to d2 # FSubDir d1 d2 ... ; return path to root # # Brief review of the jam language: # # Statements: # rule RULE - statements to process a rule # actions RULE - system commands to carry out target update # # Modifiers on actions: # together - multiple instances of same rule on target get executed # once with their sources ($(>)) concatenated # updated - refers to updated sources ($(>)) only # ignore - ignore return status of command # quietly - don't trace its execution unless verbose # piecemeal - iterate command each time with a small subset of $(>) # existing - refers to currently existing sources ($(>)) only # bind vars - subject to binding before expanding in actions # # Special rules: # Always - always build a target # Depends - builds the dependency graph # Echo - blurt out targets on stdout # Exit - blurt out targets and exit # Includes - marks sources as headers for target (a codependency) # NoCare - don't panic if the target can't be built # NoUpdate - create the target if needed but never update it # NotFile - ignore the timestamp of the target (it's not a file) # Temporary - target need not be present if sources haven't changed # # Special variables set by jam: # $(<) - targets of a rule (to the left of the :) # $(>) - sources of a rule (to the right of the :) # $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC) # $(OS) - name of OS - varies wildly # $(JAMVERSION) - version number (2.5) # # Special variables used by jam: # SEARCH - where to find something (used during binding and actions) # LOCATE - where to plop something not found with SEARCH # HDRRULE - rule to call to handle include files # HDRSCAN - egrep regex to extract include files # # Special targets: # all - default if none given on command line # # for perforce use -- jambase version JAMBASEDATE = 2004.10.07 ; # Initialize variables # # # OS specific variable settings # if $(NT) { # the list of supported toolsets on Windows NT and Windows 95/98 # local SUPPORTED_TOOLSETS = BORLANDC VISUALC VISUALC16 INTELC WATCOM MINGW LCC DIGITALMARS PELLESC ; # if the JAM_TOOLSET environment variable is defined, check that it is # one of our supported values # if $(JAM_TOOLSET) { if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS) { Echo "The JAM_TOOLSET environment variable is defined but its value" ; Echo "is invalid, please use one of the following:" ; Echo ; for t in $(SUPPORTED_TOOLSETS) { Echo " " $(t) ; } Exit ; } } # if JAM_TOOLSET is empty, we'll try to detect the toolset from other # environment variables to remain backwards compatible with Jam 2.5 # if ! $(JAM_TOOLSET) { if $(BCCROOT) { JAM_TOOLSET = BORLANDC ; BORLANDC = $(BCCROOT) ; } else if $(MSVC) { JAM_TOOLSET = VISUALC16 ; VISUALC16 = $(MSVC) ; } else if $(MSVCNT) { JAM_TOOLSET = VISUALC ; VISUALC = $(MSVCNT) ; } else if $(MINGW) { # MINGW is defined when trying to compile FT-Jam with # classic Jam # JAM_TOOLSET = MINGW ; } else { Echo "Jam cannot be run because you didn't indicate which compilation toolset" ; Echo "to use. To do so, define the JAM_TOOLSET environment variable with" ; Echo "one of the following values:" ; Echo ; Echo " Value Toolset Description" ; Echo ; Echo " BORLANDC Borland C++" ; Echo " VISUALC Microsoft Visual C++" ; Echo " VISUALC16 Microsoft Visual C++ 16 bit" ; Echo " INTELC Intel C/C++" ; Echo " WATCOM Watcom C/C++" ; Echo " MINGW MinGW (gcc)" ; Echo " LCC Win32-LCC" ; Echo " DIGITALMARS Digital Mars C/C++" ; Echo " PELLESC Pelles C" ; Echo ; Echo "The corresponding compiler must be in your path" ; Echo ; Echo " e.g.: set JAM_TOOLSET=VISUALC" ; Exit ; } } MV ?= move /y ; CP ?= copy ; RM ?= del /f/q ; RMDIR ?= rmdir /s/q ; SLASH ?= \\ ; SUFLIB ?= .lib ; SUFOBJ ?= .obj ; SUFEXE ?= .exe ; SUFLIBSHR ?= .dll ; if $(JAM_TOOLSET) = BORLANDC { Echo "Compiler is Borland C++" ; AR ?= tlib /C /P64 ; CC ?= bcc32 ; CCFLAGS ?= -w- -q -DWIN -tWR -tWM -tWC ; C++ ?= $(CC) ; C++FLAGS ?= $(CCFLAGS) -P ; LINK ?= $(CC) ; ILINK ?= ilink32 -q ; IMPLIB ?= implib ; LINKFLAGS ?= $(CCFLAGS) ; STDLIBPATH ?= $(BORLANDC)\\lib ; STDHDRS ?= $(BORLANDC)\\include ; NOARSCAN ?= true ; ILINKLIBS ?= C0D32.OBJ CW32.LIB IMPORT32.LIB ; PICFLAGS ?= -tWD ; } else if $(JAM_TOOLSET) = VISUALC16 { Echo "Compiler is Microsoft Visual C++ 16 bit" ; AR ?= lib /nologo ; CC ?= cl /nologo ; CCFLAGS ?= /D "\"WIN\"" ; C++ ?= $(CC) ; C++FLAGS ?= $(CCFLAGS) ; LINK ?= $(CC) ; LINKFLAGS ?= $(CCFLAGS) ; LINKLIBS ?= $(MSVC)\\lib\\mlibce.lib $(MSVC)\\lib\\oldnames.lib ; LINKLIBS ?= ; NOARSCAN ?= true ; OPTIM ?= "" ; STDHDRS ?= $(VISUALC16)\\include ; UNDEFFLAG ?= "/u _" ; } else if $(JAM_TOOLSET) = VISUALC { # Visual C++ 6.0 uses MSVCDIR MSVCNT ?= $(MSVCDIR) ; # bury IA64 in the path for the SDK local I ; if $(OSPLAT) = IA64 { I = ia64\\ ; } else { I = "" ; } AR ?= lib ; AS ?= masm386 ; CC ?= cl /nologo ; CCFLAGS ?= "" ; C++ ?= $(CC) ; C++FLAGS ?= $(CCFLAGS) ; LINK ?= link /nologo ; LINKFLAGS ?= "" ; LINKLIBS ?= $(MSVCNT)\\lib\\$(I)libc.lib $(MSVCNT)\\lib\\$(I)oldnames.lib $(MSVCNT)\\lib\\$(I)kernel32.lib ; OPTIM ?= "" ; STDHDRS ?= $(VISUALC)\\include ; UNDEFFLAG ?= "/u _" ; } else if $(JAM_TOOLSET) = INTELC { Echo "Compiler is Intel C/C++" ; if ! $(VISUALC) { Echo "As a special exception, when using the Intel C++ compiler, you need" ; Echo "to define the VISUALC environment variable to indicate the location" ; Echo "of your Visual C++ installation. Aborting.." ; Exit ; } AR ?= lib ; AS ?= masm386 ; CC ?= icl /nologo ; CCFLAGS ?= "" ; C++ ?= $(CC) ; C++FLAGS ?= $(CCFLAGS) ; LINK ?= link /nologo ; LINKFLAGS ?= "" ; LINKLIBS ?= $(VISUALC)\\lib\\advapi32.lib $(VISUALC)\\lib\\libc.lib $(VISUALC)\\lib\\oldnames.lib $(VISUALC)\\lib\\kernel32.lib ; OPTIM ?= "" ; STDHDRS ?= $(INTELC)\include $(VISUALC)\\include ; UNDEFFLAG ?= "/u _" ; } else if $(JAM_TOOLSET) = WATCOM { Echo "Compiler is Watcom C/C++" ; AR ?= wlib ; CC ?= wcc386 ; CCFLAGS ?= /zq /DWIN32 /I$(WATCOM)\\h ; # zq=quiet C++ ?= wpp386 ; C++FLAGS ?= $(CCFLAGS) ; CP ?= copy ; DOT ?= . ; DOTDOT ?= .. ; LINK ?= wcl386 ; LINKFLAGS ?= /zq ; # zq=quiet LINKLIBS ?= ; MV ?= move ; NOARSCAN ?= true ; OPTIM ?= ; RM ?= del /f ; SLASH ?= \\ ; STDHDRS ?= $(WATCOM)\\h $(WATCOM)\\h\\nt ; SUFEXE ?= .exe ; SUFLIB ?= .lib ; SUFOBJ ?= .obj ; UNDEFFLAG ?= "/u _" ; PICFLAGS = -s ; # disable stack checks } else if $(JAM_TOOLSET) = MINGW { Echo "Compiler is GCC with Mingw" ; AR ?= ar -ru ; CC ?= gcc ; CCFLAGS ?= "" ; C++ ?= $(CC) ; C++FLAGS ?= $(CCFLAGS) ; LINK ?= $(CC) ; LINKFLAGS ?= "" ; LINKLIBS ?= "" ; OPTIM ?= ; SUFOBJ = .o ; SUFLIB = .a ; SLASH = / ; # NOARSCAN ?= true ; } else if $(JAM_TOOLSET) = LCC { Echo "Compiler is Win32-LCC" ; AR ?= lcclib ; CC ?= lcc ; CCFLAGS ?= "" ; C++ ?= $(CC) ; C++FLAGS ?= $(CCFLAGS) ; LINK ?= lcclnk ; LINKFLAGS ?= "" ; LINKLIBS ?= "" ; OPTIM ?= ; NOARSCAN = true ; } else if $(JAM_TOOLSET) = DIGITALMARS { Echo "Compiler is Digital Mars C/C++" ; AR ?= lib -c ; CC ?= dmc ; CCFLAGS ?= "" ; C++ ?= $(CC) ; C++FLAGS ?= $(CCFLAGS) ; LINK ?= link /nologo ; LINKFLAGS ?= "/EXETYPE:NT /NOMAP" ; LINKLIBS ?= USER32.LIB KERNEL32.LIB GDI32.LIB ; OPTIM ?= ; NOARSCAN = true ; PICFLAGS = -mn -WD ; } else if $(JAM_TOOLSET) = PELLESC { Echo "Compiler is PellesC" ; AR ?= polib ; CC ?= pocc ; CCFLAGS ?= "" ; LINK ?= polink ; LINKFLAGS ?= ; LINKLIBS ?= ; OPTIM ?= ; NOARSCAN = true ; LINKLIBS ?= crt.lib oldnames.lib Win\\kernel32.lib ; } else { # # XXX: We need better comments here !! # Exit "On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the" "Borland or Microsoft directories." ; } STDHRS ?= "" ; } else if $(OS2) { # the list of supported toolsets on OS/2 # local SUPPORTED_TOOLSETS = "EMX" "WATCOM" ; # this variable holds the current toolset # TOOLSET = "" ; # if the JAM_TOOLSET environment variable is defined, check that it is # one of our supported values # if $(JAM_TOOLSET) { if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS) { Echo "The JAM_TOOLSET environment variable is defined but its value" ; Echo "is invalid, please use one of the following:" ; Echo ; for t in $(SUPPORTED_TOOLSETS) { Echo " " $(t) ; } Exit ; } } # if TOOLSET is empty, we'll try to detect the toolset from other # environment variables to remain backwards compatible with Jam 2.3 # if ! $(JAM_TOOLSET) { if $(watcom) { WATCOM = $(watcom) ; TOOLSET = WATCOM ; } else { Echo "Jam cannot be run because you didn't indicate which compilation toolset" ; Echo "to use. To do so, follow these simple instructions:" ; Echo ; Echo " - define one of the following environment variable, with the" ; Echo " appropriate value according to this list:" ; Echo ; Echo " Variable Toolset Description" ; Echo ; Echo " WATCOM Watcom C/C++ Watcom install path" ; Echo " EMX EMX (gcc) EMX install path" ; ############Echo " VISUALAGE IBM Visual Age C/C++ VisualAge install path" ; Echo ; Echo " - define the JAM_TOOLSET environment variable with the *name*" ; Echo " of the toolset variable you want to use." ; Echo ; Echo " e.g.: set WATCOM=C:\WATCOM" ; Echo " set JAM_TOOLSET=WATCOM" ; Echo ; Exit ; } } RM = del /f ; CP = copy ; MV ?= move ; DOT ?= . ; DOTDOT ?= .. ; SUFLIB ?= .lib ; SUFOBJ ?= .obj ; SUFEXE ?= .exe ; SUFLIBSHR ?= .dll ; if $(JAM_TOOLSET) = WATCOM { AR ?= wlib ; BINDIR ?= \\os2\\apps ; CC ?= wcc386 ; CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet C++ ?= wpp386 ; C++FLAGS ?= $(CCFLAGS) ; CP ?= copy ; DOT ?= . ; DOTDOT ?= .. ; LINK ?= wcl386 ; LINKFLAGS ?= /zq ; # zq=quiet LINKLIBS ?= ; MV ?= move ; NOARSCAN ?= true ; OPTIM ?= ; RM ?= del /f ; SLASH ?= \\ ; STDHDRS ?= $(WATCOM)\\h ; SUFEXE ?= .exe ; SUFLIB ?= .lib ; SUFOBJ ?= .obj ; UNDEFFLAG ?= "/u _" ; } else if $(JAM_TOOLSET) = EMX { Echo "Compiler is GCC-EMX" ; AR ?= ar -ru ; CC ?= gcc ; CCFLAGS ?= "" ; C++ ?= $(CC) ; C++FLAGS ?= $(CCFLAGS) ; LINK ?= $(CC) ; LINKFLAGS ?= "" ; LINKLIBS ?= "" ; OPTIM ?= ; SUFOBJ = .o ; SUFLIB = .a ; UNDEFFLAG ?= "-U" ; SLASH = / ; } else { # should never happen Exit "Sorry, but the $(JAM_TOOLSET) toolset isn't supported for now" ; } } else if $(VMS) { C++ ?= cxx ; C++FLAGS ?= ; CC ?= cc ; CCFLAGS ?= ; CHMOD ?= set file/prot= ; CP ?= copy/replace ; CRELIB ?= true ; DOT ?= [] ; DOTDOT ?= [-] ; EXEMODE ?= (w:e) ; FILEMODE ?= (w:r) ; HDRS ?= ; LINK ?= link ; LINKFLAGS ?= "" ; LINKLIBS ?= ; MKDIR ?= create/dir ; MV ?= rename ; OPTIM ?= "" ; RM ?= delete ; RUNVMS ?= mcr ; SHELLMODE ?= (w:er) ; SLASH ?= . ; STDHDRS ?= decc$library_include ; SUFEXE ?= .exe ; SUFLIB ?= .olb ; SUFOBJ ?= .obj ; switch $(OS) { case OPENVMS : CCFLAGS ?= /stand=vaxc ; case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ; } } else if $(MAC) { local OPT ; CW ?= "{CW}" ; MACHDRS ?= "$(UMACHDRS):Universal:Interfaces:CIncludes" "$(CW):MSL:MSL_C:MSL_Common:Include" "$(CW):MSL:MSL_C:MSL_MacOS:Include" ; MACLIBS ?= "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ; MPWLIBS ?= "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ; MPWNLLIBS ?= "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ; SIOUXHDRS ?= ; SIOUXLIBS ?= "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib" "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib" "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ; C++ ?= mwcppc ; C++FLAGS ?= -w off ; CC ?= mwcppc ; CCFLAGS ?= -w off ; CP ?= duplicate -y ; DOT ?= ":" ; DOTDOT ?= "::" ; HDRS ?= $(MACHDRS) $(MPWHDRS) ; LINK ?= mwlinkppc ; LINKFLAGS ?= -mpwtool -warn ; LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ; MKDIR ?= newfolder ; MV ?= rename -y ; NOARSCAN ?= true ; OPTIM ?= ; RM ?= delete -y ; SLASH ?= ":" ; STDHDRS ?= ; SUFLIB ?= .lib ; SUFOBJ ?= .o ; } else if $(OS) = BEOS && $(OSPLAT) = PPC { AR ?= mwld -xml -o ; BINDIR ?= /boot/home/config/bin ; CC ?= mwcc ; CCFLAGS ?= -nosyspath ; C++ ?= $(CC) ; C++FLAGS ?= -nosyspath ; CHMOD ?= chmod ; CHGRP ?= chgrp ; CHOWN ?= chown ; FORTRAN ?= "" ; LEX ?= flex ; LIBDIR ?= /boot/home/config/lib ; LINK ?= mwld ; LINKFLAGS ?= "" ; MANDIR ?= /boot/home/config/man ; NOARSCAN ?= true ; RANLIB ?= ranlib ; STDHDRS ?= /boot/develop/headers/posix ; YACC ?= bison -y ; YACCGEN ?= .c ; YACCFILES ?= y.tab ; YACCFLAGS ?= -d ; } else if $(OS) = BEOS { BINDIR ?= /boot/home/config/bin ; CC ?= gcc ; C++ ?= $(CC) ; CHMOD ?= chmod ; CHGRP ?= chgrp ; CHOWN ?= chown ; FORTRAN ?= "" ; LEX ?= flex ; LIBDIR ?= /boot/home/config/lib ; LINK ?= gcc ; MANDIR ?= /boot/home/config/man ; NOARSCAN ?= true ; RANLIB ?= ranlib ; STDHDRS ?= /boot/develop/headers/posix ; YACC ?= bison -y ; YACCGEN ?= .c ; YACCFILES ?= y.tab ; YACCFLAGS ?= -d ; } else if $(UNIX) { switch $(OS) { case AIX : LINKLIBS ?= -lbsd ; case AMIGA : CC ?= gcc ; YACC ?= bison -y ; case CYGWIN : CC ?= gcc ; CCFLAGS += -D__cygwin__ ; LEX ?= flex ; JAMSHELL ?= sh -c ; RANLIB ?= "" ; SUFEXE ?= .exe ; YACC ?= bison -y ; case DGUX : RANLIB ?= "" ; RELOCATE ?= true ; case HPUX : RANLIB ?= "" ; case INTERIX : CC ?= gcc ; JAMSHELL ?= sh -c ; RANLIB ?= "" ; case IRIX : RANLIB ?= "" ; case MPEIX : CC ?= gcc ; C++ ?= gcc ; CCFLAGS += -D_POSIX_SOURCE ; HDRS += /usr/include ; RANLIB ?= "" ; NOARSCAN ?= true ; NOARUPDATE ?= true ; case MVS : RANLIB ?= "" ; case NEXT : AR ?= libtool -o ; RANLIB ?= "" ; case MACOSX : C++ ?= c++ ; MANDIR ?= /usr/local/share/man ; case NCR : RANLIB ?= "" ; case PTX : RANLIB ?= "" ; case QNX : AR ?= wlib ; CC ?= cc ; CCFLAGS ?= -Q ; # quiet C++ ?= $(CC) ; C++FLAGS ?= -Q ; # quiet LINK ?= $(CC) ; LINKFLAGS ?= -Q ; # quiet NOARSCAN ?= true ; RANLIB ?= "" ; case SCO : RANLIB ?= "" ; RELOCATE ?= true ; case SINIX : RANLIB ?= "" ; case SOLARIS : RANLIB ?= "" ; AR ?= "/usr/ccs/bin/ar ru" ; case UNICOS : NOARSCAN ?= true ; OPTIM ?= -O0 ; case UNIXWARE : RANLIB ?= "" ; RELOCATE ?= true ; } # UNIX defaults CCFLAGS ?= ; C++FLAGS ?= $(CCFLAGS) ; CHMOD ?= chmod ; CHGRP ?= chgrp ; CHOWN ?= chown ; LEX ?= lex ; LINKFLAGS ?= $(CCFLAGS) ; LINKLIBS ?= ; OPTIM ?= -O ; RANLIB ?= ranlib ; YACC ?= yacc ; YACCGEN ?= .c ; YACCFILES ?= y.tab ; YACCFLAGS ?= -d ; SUFOBJSHR ?= .lo ; SUFLIBSHR ?= .la ; PICFLAGS ?= -fpic ; STDHDRS ?= /usr/include ; } # shared library object file suffix. We assume that it is identical # than the normal one SUFOBJSHR ?= $(SUFOBJ) ; SUFLIBSHR ?= $(SUFLIB) ; # the D compiler DC ?= dmd ; # # General defaults; a lot like UNIX # AR ?= ar ru ; AS ?= as ; ASFLAGS ?= ; AWK ?= awk ; BINDIR ?= /usr/local/bin ; C++ ?= cc ; C++FLAGS ?= ; CC ?= cc ; CCFLAGS ?= ; CP ?= cp -f ; CRELIB ?= ; DOT ?= . ; DOTDOT ?= .. ; EXEMODE ?= 711 ; FILEMODE ?= 644 ; FORTRAN ?= f77 ; FORTRANFLAGS ?= ; HDRS ?= ; INSTALLGRIST ?= installed ; JAMFILE ?= Jamfile ; JAMRULES ?= Jamrules ; LEX ?= ; LIBDIR ?= /usr/local/lib ; LINK ?= $(CC) ; LINKFLAGS ?= ; LINKLIBS ?= ; LN ?= ln ; MANDIR ?= /usr/local/man ; MKDIR ?= mkdir ; MV ?= mv -f ; OPTIM ?= ; RCP ?= rcp ; RM ?= rm -f ; RMDIR ?= $(RM) ; RSH ?= rsh ; SED ?= sed ; SHELLHEADER ?= "#!/bin/sh" ; SHELLMODE ?= 755 ; SLASH ?= / ; SUBDIRRULES ?= ; SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ; SUFEXE ?= "" ; SUFLIB ?= .a ; SUFOBJ ?= .o ; UNDEFFLAG ?= "-u _" ; YACC ?= ; YACCGEN ?= ; YACCFILES ?= ; YACCFLAGS ?= ; HDRPATTERN = "^[ ]*#[ ]*include[ ]*[<\"]([^\">]*)[\">].*$" ; OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ; # # Base dependencies - first for "bootstrap" kinds of rules # Depends all : shell files lib exe obj ; Depends all shell files lib exe obj : first ; NotFile all first shell files lib exe obj dirs clean uninstall ; Always clean uninstall ; # # Rules # # /As object : source ; # # Assemble the file _source_, called by the @Object rule. # # Do not call this rule directly, since _object_ and _source_ may have # have platform-specific file extensions # rule As { Depends $(<) : $(>) ; ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ; ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ; } # /Bulk directory : sources ; # # Copies _sources_ into _directory_ # rule Bulk { local i ; for i in $(>) { File $(i:D=$(<)) : $(i) ; } } # /Dc object : source ; # # Compile the file source into object, usin the D compiler $(DC), its # flags $(DCFLAGS) and $(DOPTIM) # Called by the @Object rule # # Do not call this rule directly, since _object_ and _source_ may have # have platform-specific file extensions # rule Dc { Depends $(<) : $(>) ; # Just to clarify here: this sets the per-target DCFLAGS to # be the current value of (global) DCFLAGS and SUBDIRDCFLAGS. DCFLAGS on $(<) += $(DCFLAGS) $(SUBDIRDCFLAGS) ; } # /Cc object : source ; # # Compile the file source into object, using the C compiler $(CC), its # flags $(CCFLAGS) and $(OPTIM), and the header file directories $(HDRS). # Called by the @Object rule # # Do not call this rule directly, since _object_ and _source_ may have # have platform-specific file extensions # rule Cc { Depends $(<) : $(>) ; # If the compiler's -o flag doesn't work, relocate the .o if $(RELOCATE) { CcMv $(<) : $(>) ; } # Just to clarify here: this sets the per-target CCFLAGS to # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS. # CCHDRS and CCDEFS must be reformatted each time for some # compiles (VMS, NT) that malign multiple -D or -I flags. CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ; CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; } # /C++ object : source ; # # Compile the C++ source file _source_. Similar to @CC, called by @Object # # Do not call this rule directly, since _object_ and _source_ may have # have platform-specific file extensions # rule C++ { Depends $(<) : $(>) ; if $(RELOCATE) { CcMv $(<) : $(>) ; } C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ; CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; } # /Chmod target ; # # (Unix and VMS only). Change file permissions on _target_ to target-specific # $(MODE) value set by @Link, @File, @Install* and @Shell rules # rule Chmod { if $(CHMOD) { Chmod1 $(<) ; } } # /Clean clean : targets ; # # Removes existing _targets_ when _clean_ is built. clean is not a dependency # of all, and must be built explicitely for targets to be removed # # /File target : source ; # # Copies _source_ into _target_ # rule File { Depends files : $(<) ; Depends $(<) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MODE on $(<) = $(FILEMODE) ; Chmod $(<) ; } # /Fortran object : source ; # # Compile the Fortran source file _source_. Called by the @Object rule # # Do not call this rule directly, since _obj_ and _source_ may have # have platform-specific file extensions # rule Fortran { Depends $(<) : $(>) ; } # /GenFile target : image sources ; # # Runs the command "_image_ _target_ _sources_" to create _target_ from # _sources_ and _image_ (where _image_ is an executable built by the # @Main rule) # rule GenFile { local _t = [ FGristSourceFiles $(<) ] ; local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ; Depends $(_t) : $(_s) $(>[2-]) ; GenFile1 $(_t) : $(_s) $(>[2-]) ; Clean clean : $(_t) ; } rule GenFile1 { MakeLocate $(<) : $(LOCATE_SOURCE) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; } # /HardLink target : source ; # # Makes _target_ a hard link to _source_, if it isn't one already # (Unix only) # rule HardLink { Depends files : $(<) ; Depends $(<) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; } # /HdrMacroFile # # this rule is specific to FT-Jam. It is used to indicate that a given file # contains definitions for filename macros (e.g. "#define MYFILE_H .h") # that can later be used in #include statements in the rest of the source # # these files must be parsed before any make is tried. # rule HdrMacroFile { HDRMACRO $(<) ; } # /HdrRule source : headers ; # # Arranges the proper dependencies when the file _source_ includes the files # _headers_ through the #include C preprocessor directive # # this rule is not intendend to be called explicitely. It is called # automatically during header scanning on sources handled by the @Object # rule (e.g. sources in @Main or @Library rules) # rule HdrRule { # HdrRule source : headers ; # N.B. This rule is called during binding, potentially after # the fate of many targets has been determined, and must be # used with caution: don't add dependencies to unrelated # targets, and don't set variables on $(<). # Tell Jam that anything depending on $(<) also depends on $(>), # set SEARCH so Jam can find the headers, but then say we don't # care if we can't actually find the headers (they may have been # within ifdefs), local s = $(>:G=$(HDRGRIST:E)) ; Includes $(<) : $(s) ; SEARCH on $(s) = $(HDRSEARCH) ; NoCare $(s) ; # Propagate on $(<) to $(>) HDRSEARCH on $(s) = $(HDRSEARCH) ; HDRSCAN on $(s) = $(HDRSCAN) ; HDRRULE on $(s) = $(HDRRULE) ; HDRGRIST on $(s) = $(HDRGRIST) ; } rule InstallInto { # InstallInto dir : sources ; local i t ; t = $(>:G=$(INSTALLGRIST)) ; # Arrange for jam install # Arrange for jam uninstall # sources are in SEARCH_SOURCE # targets are in dir Depends install : $(t) ; Clean uninstall : $(t) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MakeLocate $(t) : $(<) ; # For each source, make gristed target name # and Install, Chmod, Chown, and Chgrp for i in $(>) { local tt = $(i:G=$(INSTALLGRIST)) ; Depends $(tt) : $(i) ; Install $(tt) : $(i) ; Chmod $(tt) ; if $(OWNER) && $(CHOWN) { Chown $(tt) ; OWNER on $(tt) = $(OWNER) ; } if $(GROUP) && $(CHGRP) { Chgrp $(tt) ; GROUP on $(tt) = $(GROUP) ; } } } # /InstallBin dir : sources ; # # Copy _sources_ into _dir_ with mode $(EXEMODE) # rule InstallBin { local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ; InstallInto $(<) : $(_t) ; MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ; } # /InstallFile dir : sources ; # # Copy _sources_ into _dir_ with mode $(FILEMODE) # rule InstallFile { InstallInto $(<) : $(>) ; MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; } # /InstallLib dir : sources ; # # Copy _sources_ into _dir_ with mode $(FILEMODE) # rule InstallLib { InstallInto $(<) : $(>) ; MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; } # /InstallLib dir : sources ; # # Copy _sources_ into the appropriate subdirectory of _dir_ with mode # $(FILEMODE). The subdirectory is manS, where S is the suffix of each of # sources. # rule InstallMan { # Really this just strips the . from the suffix local i s d ; for i in $(>) { switch $(i:S) { case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ; case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ; case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ; case .n : s = n ; case .man : s = 1 ; } d = man$(s) ; InstallInto $(d:R=$(<)) : $(i) ; } MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; } # /InstallShell dir : sources ; # # Copy _sources_ into _dir_ with mode $(SHELLMODE) # rule InstallShell { InstallInto $(<) : $(>) ; MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ; } # /Lex source.c : source.l ; # # Process the lex source file _source.l_ and rename the lex.yy.c # to _source.c_ . Called by the @Object rule # rule Lex { LexMv $(<) : $(>) ; Depends $(<) : $(>) ; MakeLocate $(<) : $(LOCATE_SOURCE) ; Clean clean : $(<) ; } # /Library library : sources ; # # Compiles _sources_ and archives them into _library_. The intermediate # objects are deleted. Calles @Object and @LibraryFromObjects # # If @Library is invoked with no suffix on _library_, the $(SUFLIB) # suffix is used # rule Library { LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ; Objects $(>) ; } # /SharedLibrary library : sources : def : import ; # # Compiles _sources_ and generates a shared _library_ (i.e. DLL on Windows, # or shared object on Unix). Calls @SharedObjects and @SharedLibraryFromObjects # # If @SharedLibrary is invoked with no suffix on _library_, then # $(SUFLIBSHR) suffix is used # # _def_ is the name of the corresponding definition file used to generate # the library on Windows and OS/2 (ignored otherwise). If undefined, it # will default to _library_ with the .def suffix # # _import_ is the name of the corresponding import library for Windows # and OS/2 platforms (ignored otherwise). If undefined, it will default # to _library_ with the .dll.lib suffix. # rule SharedLibrary { SharedLibraryFromObjects $(<) : $(>:S=$(SUFOBJSHR)) : $(3) : $(4) ; SharedObjects $(>) ; } if $(UNIX) { # this rule is used to find the 'libtool' script in the current # path, this is required when compiling shared objects on Unix # rule LibToolFind { if $(LIBTOOL) { return $(LIBTOOL) ; } local matches = [ Glob $(PATH) : libtool ] ; if ! $(matches) { Exit "could not find 'libtool' program in current path. Aborting !" ; } LIBTOOL = $(matches[1]) ; return $(LIBTOOL) ; } } # /LibraryFromObjects library : objects ; # # Archives _objects_ into _library_. The _objects_ are then deleted # # If _library_ has no suffix, the $(SUFLIB) suffix is used # # Called by @Library rule. Most people should never call this rule # directly. # rule LibraryFromObjects { local _i _l _s ; # Add grist to file names _s = [ FGristFiles $(>) ] ; _l = $(<:S=$(SUFLIB)) ; # library depends on its member objects if $(KEEPOBJS) { Depends obj : $(_s) ; } else { Depends lib : $(_l) ; } # Set LOCATE for the library and its contents. The bound # value shows up as $(NEEDLIBS) on the Link actions. # For compatibility, we only do this if the library doesn't # already have a path. if ! $(_l:D) { MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ; } if $(NOARSCAN) { # If we can't scan the library to timestamp its contents, # we have to just make the library depend directly on the # on-disk object files. Depends $(_l) : $(_s) ; } else { # If we can scan the library, we make the library depend # on its members and each member depend on the on-disk # object file. Depends $(_l) : $(_l)($(_s:BS)) ; for _i in $(_s) { Depends $(_l)($(_i:BS)) : $(_i) ; } } Clean clean : $(_l) ; if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; } Archive $(_l) : $(_s) ; if $(RANLIB) { Ranlib $(_l) ; } # If we can't scan the library, we have to leave the .o's around. if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; } } # /SharedLibraryFromObjects library : objects : def : import ; # # Equivalent of @LibraryFromObjects for shared libraries. # # Called by @SharedLibrary. Most people shouldn't call this rule # directly # rule SharedLibraryFromObjects { local _i _l _s ; # Add grist to file names _s = [ FGristFiles $(>) ] ; _l = $(<:S=$(SUFLIBSHR)) ; #Echo "Library is $(_l)" ; # library depends on its member objects if $(KEEPOBJS) { Depends obj : $(_s) ; } else { Depends lib : $(_l) ; } # Set LOCATE for the library and its contents. The bound # value shows up as $(NEEDLIBS) on the Link actions. # For compatibility, we only do this if the library doesn't # already have a path. if ! $(_l:D) { MakeLocate $(_l) : $(LOCATE_TARGET) ; } # we never scan shared libraries for member objects Depends $(_l) : $(_s) ; Clean clean : $(_l) ; # I don't know if VMS supports shared libraries, so I prefer # to disable the following right now # #if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; } # creating the library is so much fun on Unix :-) if $(UNIX) { local libtool = [ LibToolFind ] ; # find the right libtool AR on $(_l) = "$(libtool) --mode=link $(AR)" ; } else if $(NT) { local _implib = $(4) ; local _def = $(3) ; _implib ?= $(_l:S=$(SUFLIBSHR)$(SUFLIB)) ; _def ?= $(_l:S=.def) ; Clean clean : $(_implib) ; Depends lib : $(_implib) $(_def) ; Depends $(_implib) : $(_def) $(_l) ; Depends $(_l) : $(_def) ; DEFFILENAME on $(_l) = $(_def) ; IMPLIBNAME on $(_l) = $(_implib) ; MakeLocate $(_implib) : $(LOCATE_TARGET) ; MakeLocate $(_implib:S=.exp) : $(LOCATE_TARGET) ; if $(JAM_TOOLSET) in VISUALC BORLANDC LCC WATCOM DIGITALMARS { SharedLink-$(JAM_TOOLSET) $(_l) : $(_s) : $(_implib) : $(_def) ; } DllLink $(_l) : $(_s) ; } else { Echo "Sorry, I don't know how to make a shared library on your system" ; Exit "Please contact the FTJam maintainer for help" ; } } # Since building shared libraries is so different depending on the # compiler being used, I've broken this task into compiler-specific # ones # # # This contains the Visual C++ specific rule used to build a DLL # and its import library # rule SharedLink-VISUALC { # get rid of the '.exp' file when cleaning # Clean clean : $(3:S=.exp) ; } rule SharedLink-BORLANDC { local _deffile = $(4) ; local _implib = $(3) ; LINKFLAGS on $(<) += /x /Gn /Tpd ; LINKLIBS on $(<) = $(LINKLIBS) $(ILINKLIBS) ; # Generate import library with the IMPLIB tool !! # DllImplib $(_implib) : $(<) ; Depends $(_implib) : $(_deffile) $(<) ; Depends lib : $(_implib) ; DEFFILENAME on $(_implib) = $(_deffile) ; # clean the TDS file, since the compiler refuses to not generate it ! MakeLocate $(<:S=.tds) : $(LOCATE_TARGET) ; Clean clean : $(<:S=.tds) ; } rule SharedLink-LCC { if "" { #Echo "Sorry, but generating DLLs with LCC is not supported. That's" ; #Echo "because the 'lcclnk' tool that comes with this compiler is" ; #Echo "unreliable and doesn't work as expected. For more information" ; #Echo "contact the FT-Jam maintainer" ; #Exit ; } # the 'lcclnk' tool is absolutely broken: # - its -o flag doesn't work when there is a LIBRARY statement # in the .def file. # # - it uses the LIBRARY name in the .def file to determine # the name of the dll and its import library, and always # places them in the current directory !! # # - if there is no LIBRARY statement, the -o flag is only # used to determine where the DLL is placed, the import # library will always be placed in the current directory !! # # clean the .exp file too, don't know how to get rid of it Clean clean : $(4:S=.exp) ; } rule SharedLink-WATCOM { #Echo "Sorry, but building DLLs with Watcom isn't supported by this tool" ; #Echo "this comes from the fact that the Watcom linker isn't capable of" ; #Echo "using normal .def files" ; #Exit ; local _deffile = $(4) ; local _implib = $(3) ; IMPLIB on $(<) = $(_implib) ; DEFFILE on $(<) = $(_deffile) ; # clean the TDS file, since the compiler refuses to not generate it ! MakeLocate $(<:S=.tds) : $(LOCATE_TARGET) ; Clean clean : $(<:S=.tds) ; } rule SharedLink-DIGITALMARS { #Echo "Sorry, but building DLLs with Digital Mars isn't supported at the" ; #Echo "moment, please contact the FT-Jam maintainers" ; #Exit ; } # /Link image : objects ; # # Links _image_ from _objects_ and sets permissions on _image_ to # $(EXEMODE). _image_ must be an actual filename; suffix is not # supplied. # # Called by @Main, shouldn't be called by most people # rule Link { MODE on $(<) = $(EXEMODE) ; Chmod $(<) ; } # /LinkLibraries image : libraries ; # # Makes _image_ depend on _libraries_ and includes them during linking # # _image_ may be referenced without a suffix in this rule invocation. # @LinkLibraries supplies the suffix # # You should only use this rule with libraries created through the # @Library rule. For external libraries, use something else (XXX) # rule LinkLibraries { # make library dependencies of target # set NEEDLIBS variable used by 'actions Main' local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; Depends $(_t) : $(>:S=$(SUFLIB)) ; NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ; } # /LinkSharedLibraries image : libraries : # # Same as @LinkLibraries, but to link _image_ with shared libraries # generated through the @SharedLibrary rule # rule LinkSharedLibraries { # make library dependencies of target # set NEEDLIBS variable used by 'actions Main' local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; local _ext = $(SUFLIBSHR) ; if $(NT) || $(OS2) { # on NT or OS/2, we need to link agains the import library, # not the DLL itself !! # _ext = $(SUFLIBSHR)$(SUFLIB) ; } Depends $(_t) : $(>:S=$(_ext)) ; NEEDLIBS on $(_t) += $(>:S=$(_ext)) ; } # /Main image : sources ; # # Compiles _sources_ and links them into _image_. Calls @Objects and # @MainFromObjects. # # _image_ may be supplied without suffix. # rule Main { MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ; Objects $(>) ; } # /MainFromObjects image : objects ; # # Links _objects_ into _image_. Dependency of exe. # @MainFromObjects provides a default suffix for _image_ # rule MainFromObjects { local _s _t ; # Add grist to file names # Add suffix to exe _s = [ FGristFiles $(>) ] ; _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; # so 'jam foo' works when it's really foo.exe if $(_t) != $(<) { Depends $(<) : $(_t) ; NotFile $(<) ; } # make compiled sources a dependency of target Depends exe : $(_t) ; Depends $(_t) : $(_s) ; MakeLocate $(_t) : $(LOCATE_TARGET) ; Clean clean : $(_t) ; # special case for stupid Borland C++, which always generates a # .tds file for executables, even when no debug information is needed # if $(JAM_TOOLSET) = BORLANDC { MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ; Clean clean : $(_t:S=.tds) ; } Link $(_t) : $(_s) ; } # /MakeLocate targets : directory # # Creates _dir_ and causes _target_ to be built into _dir_ # # This is done by setting the target-specific variable LOCATE # on _targets_, and arranges with @MkDir to create the target # directory # rule MakeLocate { # Note we grist the directory name with 'dir', # so that directory path components and other # targets don't conflict. if $(>) { LOCATE on $(<) = $(>) ; Depends $(<) : $(>[1]:G=dir) ; MkDir $(>[1]:G=dir) ; } } # /MkDir dir ; # # Creates _dir_ and its parent directories # rule MkDir { # Ignore timestamps on directories: we only care if they # exist. NoUpdate $(<) ; # Don't create . or any directory already created. if $(<:G=) != $(DOT) && ! $($(<)-mkdir) { # Cheesy gate to prevent multiple invocations on same dir # Arrange for jam dirs # MkDir1 has the actions $(<)-mkdir = true ; Depends dirs : $(<) ; MkDir1 $(<) ; # Recursively make parent directories. # $(<:P) = $(<)'s parent, & we recurse until root local s = $(<:P) ; # Don't try to create A: or A:\ on windows if $(NT) { switch $(s) { case *: : s = ; case *:\\ : s = ; } } # handle "C:", "C:/", "/cygdrive" and "/cygdrive/" in Cygwin if $(UNIX) && $(OS) = CYGWIN { switch $(s) { case ?: : s = ; case ?:/ : s = ; case

/cygdrive : s = ; case /cygdrive/ : s = ; } } if $(s) = $(<) { # The parent is the same as the dir. # We're at the root, which some OS's can't stat, so we mark # it as NotFile. NotFile $(s) ; } else if $(s:G=) { # There's a parent; recurse. Depends $(<) : $(s) ; MkDir $(s) ; } } } # /Object object : source ; # # Compile s a single _source_ file into _object_. The @Main and @Library # rules use it to compile sources. # # Causes _source_ to be scanned for #include directives and calls @HdrRule # to make all included files dependencies of _object_. # # Calls one of the following rules depending on the suffix to do the # actual compilation: # rule Object { # locate object and search for source, if wanted Clean clean : $(<) ; MakeLocate $(<) : $(LOCATE_TARGET) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; # Save HDRS for -I$(HDRS) on compile. # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers # in the .c file's directory, but generated .c files (from # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly # different from $(SEARCH_SOURCE). HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ; # handle #includes for source: Jam scans for headers with # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE) # with the scanned file as the target and the found headers # as the sources. HDRSEARCH is the value of SEARCH used for # the found header files. Finally, if jam must deal with # header files of the same name in different directories, # they can be distinguished with HDRGRIST. # $(SEARCH_SOURCE:E) is where cc first looks for #include # "foo.h" files. If the source file is in a distant directory, # look there. Else, look in "" (the current directory). HDRRULE on $(>) = HdrRule ; HDRSCAN on $(>) = $(HDRPATTERN) ; HDRSEARCH on $(>) = $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ; HDRGRIST on $(>) = $(HDRGRIST) ; # propagate target specific-defines DEFINES on $(<) += $(DEFINES) ; # if source is not .c, generate .c with specific rule switch $(>:S) { case .asm : As $(<) : $(>) ; case .c : Cc $(<) : $(>) ; case .C : C++ $(<) : $(>) ; case .cc : C++ $(<) : $(>) ; case .cpp : C++ $(<) : $(>) ; case .cxx : C++ $(<) : $(>) ; case .c++ : C++ $(<) : $(>) ; case .C++ : C++ $(<) : $(>) ; case .d : Dc $(<) : $(>) ; case .f : Fortran $(<) : $(>) ; case .l : Cc $(<) : $(<:S=.c) ; Lex $(<:S=.c) : $(>) ; case .s : As $(<) : $(>) ; case .y : Cc $(<) : $(<:S=$(YACCGEN)) ; Yacc $(<:S=$(YACCGEN)) : $(>) ; case * : UserObject $(<) : $(>) ; } } # /ObjectCcFlags sources : flags ; # # this rule is used to add compiler flags to the compilation of # specific C sources files. # rule ObjectCcFlags { CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; } # /ObjectC++Flags sources : flags ; # # this rule is used to add compiler flags to the compilation of # specific C++ source files # rule ObjectC++Flags { C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; } # /ObjectDefines objects : macros ; # # this rule is used to add macro defines to the compilation of # specific C and C++ source files # rule ObjectDefines { # must reformat CCDEFS according to current defines local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ; DEFINES on $(s) += $(>) ; CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ; } # /ObjectHdrs sources : paths ; # # this rule is used to add include paths to the compilation of # specific C and C++ source files # rule ObjectHdrs { # Add to HDRS for HdrScan's benefit. # must reformat CCHDRS according to headers local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ; HDRS on $(s) += $(>) ; CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ; } # /Objects sources ; # # this rule is used to compile one or more sources into object files. # do not call it directly, it is used by the Main and Library rules # automatically # rule Objects { local _i ; for _i in [ FGristFiles $(<) ] { Object $(_i:S=$(SUFOBJ)) : $(_i) ; Depends obj : $(_i:S=$(SUFOBJ)) ; } } # /SharedObjects # # this rule is used to compile one or more sources into 'shared object # files'. This means object files used to build either DLLs or Unix shared # libraries. # # do not call this rule directly, it is called by SharedLibrary automatically # rule SharedObjects { # temporarily override SUFOBJ with $(SUFOBJSHR) to # local SUFOBJ = $(SUFOBJSHR) ; # call the normal Objects rule # Objects $(<) ; # add the compiler-specific position-independent-code flag # where needed # ObjectCcFlags $(<) : $(PICFLAGS) ; # change the compiler invokation for all these objects # to use Libtool on Unix systems. We explicitely disable the # generation of static objects here # if $(UNIX) { libtool on $(<:S=$(SUFOBJ)) = [ LibToolFind ] ; CC on $(<:S=$(SUFOBJ)) = "$(libtool) --mode=compile $(CC) -dynamic" ; } } rule RmTemps { Temporary $(>) ; } rule Setuid { MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ; } rule Shell { Depends shell : $(<) ; Depends $(<) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MODE on $(<) = $(SHELLMODE) ; Clean clean : $(<) ; Chmod $(<) ; } rule SoftLink { Depends files : $(<) ; Depends $(<) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; Clean clean : $(<) ; } rule SubDir { # # SubDir TOP d1 d2 ... ; # # Support for a project tree spanning multiple directories. # # SubDir declares a Jamfile's location in a project tree, setting # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source # files can be found. # # TOP is a user-select variable name for root of the tree, and # d1 d2 ... are the directory elements that lead from the root # of the tree to the directory of the Jamfile. # # TOP can be set externally, but normally the first SubDir call # computes TOP as the path up from the current directory; the # path contains one ../ for each of d1 d2 ... # # SubDir reads once the project-specific rules file Jamrules # in the TOP directory, if present. This can be overridden # with the variable TOPRULES. # # SubDir supports multiple, overlaid project trees: SubDir # invocations with different TOPs can appear in the same Jamfile. # The location established by the first SubDir call is used set # the TOPs for the subsequent SubDir calls. # # SubDir's public variables: # # $(TOP) = path from CWD to root. # $(SUBDIR) = path from CWD to the directory SubDir names. # $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names # $(SEARCH_SOURCE) = $(SUBDIR) # $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR) # $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR) # $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s # local _top = $(<[1]) ; local _tokens = $(<[2-]) ; # # First time through sets up relative root and includes Jamrules. # if ! $(_top) { Exit SubDir syntax error ; } if ! $($(_top)-SET) { $(_top)-SET = true ; # First time we've seen this TOP. # We'll initialize a number of internal variables: # # $(TOP-UP) = directories from ROOT to a common point # $(TOP-DOWN) = directories from common point to TOP # $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD # $(SUBDIR_UP) = current value of $(TOP-UP) # $(SUBDIR_DOWN) = current value of $(TOP-DOWN) # $(SUBDIR_ROOT) = current value of $(TOP-ROOT) # if $($(_top)) { # TOP externally set. # We'll ignore the relative (UP/DOWN) path that # got us here, and instead remember the hard ROOT. $(_top)-UP = ; $(_top)-DOWN = ; $(_top)-ROOT = $($(_top)) ; } else { # TOP not preset. # Establishing a new TOP. In the simplest case, # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's # merely a certain number of directories down from # the current directory, and FSubDirPath will set # TOP to a path consisting of ../ for each of the # elements of _tokens, because that represents how # far below TOP the current directory sits. # # In the more complicated case, the starting directory # isn't the directory of jam's invocation but an # location established by previous SubDir call. The # starting directory is SUBDIR_UP directories up from # SUBDIR_ROOT, and then SUBDIR_DOWN directories down # from that. If SUBDIR_ROOT is not set, that means # SUBDIR_DOWN and SUBDIR_UP represent the path from # the directory of jam's invocation. # # In the most complicated case, the _tokens also # represents directories down, because TOP is being # estalished in a directory other than TOP's root. # Hopefully, _tokens and SUBDIR_DOWN represent the # same final directory, relative to the new TOP and # the previous SubDIr's TOP. To find the new TOP, # we have to chop off any common directories from # then ends of _tokens and SUBDIR_DOWN. To do so, # we reverse each of them, call FStripCommon to # remove the initial common elements, and then # reverse them again. After this process, if # both _tokens and SUBDIR_DOWN have elements, it # means the directory names estalished by the two # SubDir calls don't match, and a warning is issued. # All hell will likely break loose at this point, # since the whole SubDir scheme relies on the SubDir # calls accurately naming the current directory. # Strip common trailing elements of _tokens and SUBDIR_DOWN. _tokens = [ FReverse $(_tokens) ] ; SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ; FStripCommon _tokens : SUBDIR_DOWN ; SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ; _tokens = [ FReverse $(_tokens) ] ; if $(SUBDIR_DOWN) && $(_tokens) { Echo Warning: SubDir $(<) misplaced! ; } # We'll remember the relative (UP/DOWN) path that # got us here, plus any hard ROOT starting point # for the UP/DOWN. If TOP is never set externally, # ROOT will always be "" (directory of jam's invocation). $(_top)-UP = $(SUBDIR_UP) $(_tokens) ; $(_top)-DOWN = $(SUBDIR_DOWN) ; $(_top)-ROOT = $(SUBDIR_ROOT:E="") ; $(_top) = [ FSubDirPath $(_top) ] ; } # Set subdir vars for the inclusion of the Jamrules, # just in case they have SubDir rules of their own. # Note that SUBDIR_DOWN is empty: it's all the way # up where the Jamrules live. These gets overrided # just after the inclusion. SUBDIR_UP = $($(_top)-UP) ; SUBDIR_DOWN = ; SUBDIR_ROOT = $($(_top)-ROOT) ; # Include $(TOPRULES) or $(TOP)/Jamrules. # Include $(TOPRULES) if set. # Otherwise include $(TOP)/Jamrules if present. if $($(_top)RULES) { include $($(_top)RULES) ; } else { NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ; include $(JAMRULES:R=$($(_top)):G=$(_top)) ; } } # Get path from $(TOP) to named directory. # Save dir tokens for other potential uses. SUBDIR_UP = $($(_top)-UP) ; SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ; SUBDIR_ROOT = $($(_top)-ROOT) ; SUBDIR_TOKENS = $(SUBDIR_DOWN) ; SUBDIR = [ FSubDirPath $(<) ] ; # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST # These can be reset if needed. For example, if the source # directory should not hold object files, LOCATE_TARGET can # subsequently be redefined. SEARCH_SOURCE = $(SUBDIR) ; LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ; LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ; SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ; # Reset per-directory ccflags, hdrs, etc, # listed in SUBDIRRESET. # Note use of variable expanded assignment var SUBDIR$(SUBDIRRESET) = ; # Invoke user-specific SubDir extensions, # rule names listed in SUBDIRRULES. # Note use of variable expanded rule invocation $(SUBDIRRULES) $(<) ; } rule FSubDirPath { # FSubDirPath TOP d1 ... ; # Returns path to named directory. # If jam is invoked in a subdirectory of the TOP, then we # need to prepend a ../ for every level we must climb up # (TOP-UP), and then append the directory names we must # climb down (TOP-DOWN), plus the named directories d1 ... # If TOP was set externally, or computed from another TOP # that was, we'll have to reroot the whole thing at TOP-ROOT. local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ; return $(_r:R=$($(<[1])-ROOT)) ; } rule SubDirDcFlags { SUBDIRDCFLAGS += $(<) ; } rule SubDirCcFlags { SUBDIRCCFLAGS += $(<) ; } rule SubDirC++Flags { SUBDIRC++FLAGS += $(<) ; } rule SubDirHdrs { SUBDIRHDRS += [ FDirName $(<) ] ; } rule SubInclude { # SubInclude TOP d1 ... ; # # Include a subdirectory's Jamfile. # We use SubDir to get there, in case the included Jamfile # either doesn't have its own SubDir (naughty) or is a subtree # with its own TOP. if ! $($(<[1])) { Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ; } SubDir $(<) ; include $(JAMFILE:D=$(SUBDIR)) ; } rule SubRules { # SubRules TOP d1 ... : Other-TOP ; # # Read another tree's Jamrules, by giving it's path according # to this tree and it's own name. if ! $($(<[1])) { Exit SubRules $(<[1]) without prior SubDir $(<[1]) ; } SubDir $(<) ; SubDir $(>) ; } rule Undefines { UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ; } rule UserObject { Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ; } rule Yacc { local _h ; _h = $(<:BS=.h) ; # Some places don't have a yacc. MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ; if $(YACC) { Depends $(<) $(_h) : $(>) ; Yacc1 $(<) $(_h) : $(>) ; YaccMv $(<) $(_h) : $(>) ; Clean clean : $(<) $(_h) ; } # make sure someone includes $(_h) else it will be # a deadly independent target Includes $(<) : $(_h) ; } # # Utility rules; no side effects on these # # /FGrist path to file ; # # Returns a single string that is used as grist # rule FGrist { return $(<:J=!) ; } rule FGristFiles { return $(<:G=$(SOURCE_GRIST:E)) ; } rule FGristSourceFiles { # Produce source file name name with grist in it, # if SOURCE_GRIST is set. # Leave header files alone, because they have a global # visibility. if ! $(SOURCE_GRIST) { return $(<) ; } else { local _i _o ; for _i in $(<) { switch $(_i) { case *.h : _o += $(_i) ; case * : _o += $(_i:G=$(SOURCE_GRIST)) ; } } return $(_o) ; } } rule FReverse { if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; } } rule FSubDir { # If $(>) is the path to the current directory, compute the # path (using ../../ etc) back to that root directory. # Sets result in $(<) if ! $(<[1]) { return $(DOT) ; } else { local _i _d ; _d = $(DOTDOT) ; for _i in $(<[2-]) { _d = $(_d:R=$(DOTDOT)) ; } return $(_d) ; } } rule FStripCommon { # FStripCommon v1 : v2 ; # Strip common initial elements of variables v1 and v2. # Modifies the variable values themselves. if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) { $(<) = $($(<)[2-]) ; $(>) = $($(>)[2-]) ; FStripCommon $(<) : $(>) ; } } rule FRelPath { local _l _r ; # first strip off common parts _l = $(<) ; _r = $(>) ; FStripCommon _l : _r ; # now make path to root and path down _l = [ FSubDir $(_l) ] ; _r = [ FDirName $(_r) ] ; # Concatenate and save # XXX This should be better if $(_r) = $(DOT) { return $(_l) ; } else { return $(_r:R=$(_l)) ; } } rule FAppendSuffix { # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;" # returns (yacc,lex,foo.bat) on Unix and # (yacc.exe,lex.exe,foo.bat) on NT. if $(>) { local _i _o ; for _i in $(<) { if $(_i:S) { _o += $(_i) ; } else { _o += $(_i:S=$(>)) ; } } return $(_o) ; } else { return $(<) ; } } # # Operating system specific utility rules # First, the (generic) UNIX versions # rule FQuote { return "\\\"$(<)\\\"" ; } rule FDefines { return -D$(<) ; } rule FIncludes { return -I$(<) ; } rule FDirName { # Turn individual elements in $(<) into a usable path. local _i ; local _s = $(DOT) ; for _i in $(<) { _s = $(_i:R=$(_s)) ; } return $(_s) ; } if $(OS2) { rule FQuote { return "\"$(<)\"" ; } rule FIncludes { return /I$(<) ; } } else if $(NT) && $(JAM_TOOLSET) != MINGW && $(JAM_TOOLSET) != LCC { rule FDefines { return /D$(<) ; } rule FIncludes { return /I$(<) ; } } else if $(MAC) { rule FQuote { return "\"$(<)\"" ; } rule FDefines { return "-define '$(<)'" ; } rule FIncludes { return "\"$(<:J=,)\"" ; } } else if $(VMS) { rule FQuote { return "\"\"\"$(<)\"\"\"" ; } rule FDefines { return "/define=( $(<:J=,) )" ; } rule FIncludes { return "/inc=( $(<:J=,) )" ; } rule FDirName { local _s _i ; # Turn individual elements in $(<) into a usable path. if ! $(<) { _s = $(DOT) ; } else { # This handles the following cases: # a -> [.a] # a b c -> [.a.b.c] # x: -> x: # x: a -> x:[a] # x:[a] b -> x:[a.b] switch $(<[1]) { case *:* : _s = $(<[1]) ; case \\[*\\] : _s = $(<[1]) ; case * : _s = [.$(<[1])] ; } for _i in [.$(<[2-])] { _s = $(_i:R=$(_s)) ; } } return $(_s) ; } } # # Actions # # # First the defaults # actions updated together piecemeal Archive { $(AR) $(<) $(>) } actions As { $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>) } actions C++ { $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions Cc { $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions Dc { $(DC) -c -of$(<) $(DCFLAGS) $(DOPTIM) $(>) } actions Chgrp { $(CHGRP) $(GROUP) $(<) } actions Chmod1 { $(CHMOD) $(MODE) $(<) } actions Chown { $(CHOWN) $(OWNER) $(<) } actions piecemeal together existing Clean { $(RM) $(>) } actions File { $(CP) $(>) $(<) } actions GenFile1 { $(>[1]) $(<) $(>[2-]) } actions Fortran { $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>) } actions HardLink { $(RM) $(<) && $(LN) $(>) $(<) } actions Install { $(CP) $(>) $(<) } actions Lex { $(LEX) $(>) } actions LexMv { $(MV) lex.yy.c $(<) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } actions MkDir1 { $(MKDIR) $(<) } actions together Ranlib { $(RANLIB) $(<) } actions quietly updated piecemeal together RmTemps { $(RM) $(>) } actions Shell { $(AWK) ' NR == 1 { print "$(SHELLHEADER)" } NR == 1 && /^[#:]/ { next } /^##/ { next } { print } ' < $(>) > $(<) } actions SoftLink { $(RM) $(<) && $(LN) -s $(>) $(<) } actions Yacc1 { $(YACC) $(YACCFLAGS) $(>) } actions YaccMv { $(MV) $(YACCFILES).c $(<[1]) $(MV) $(YACCFILES).h $(<[2]) } # # RELOCATE - for compilers with broken -o flags # if $(RELOCATE) { actions C++ { $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions Cc { $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions ignore CcMv { [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<) } } # # NOARUPDATE - can't update an archive # if $(NOARUPDATE) { actions Archive { $(AR) $(<) $(>) } } # # UNIX specific actions # if $(UNIX) { actions GenFile1 { PATH="$PATH:." $(>[1]) $(<) $(>[2-]) } } # # NT specific actions # if $(NT) { if $(JAM_TOOLSET) = VISUALC || $(JAM_TOOLSET) = INTELC { actions updated together piecemeal Archive { if exist $(<) set _$(<:B)_=$(<) $(AR) /out:$(<) %_$(<:B)_% $(>) } actions As { $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul; } actions Cc { $(CC) /c /Fo$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>) } actions C++ { $(C++) /c /Fo$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp$(>) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME { $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } } else if $(JAM_TOOLSET) = VISUALC16 { actions updated together piecemeal Archive { $(AR) $(<) -+$(>) } actions Cc { $(CC) /c /Fo$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions C++ { $(C++) /c /Fo$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Tp$(>) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME { $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } } else if $(JAM_TOOLSET) = BORLANDC { actions updated together piecemeal Archive { $(AR) $(<) -+$(>) } actions Link bind NEEDLIBS { $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>) } actions DllLink bind NEEDLIBS DEFFILENAME { $(ILINK) $(LINKFLAGS) $(>) , $(<) ,, $(LINKLIBS:E) $(NEEDLIBS:E) , $(DEFFILENAME) } actions DllImplib bind DEFFILENAME { $(IMPLIB) -a $(<) $(>) $(DEFFILENAME) } actions C++ { $(C++) -c -o$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions Cc { $(CC) -c -o$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } } else if $(JAM_TOOLSET) = MINGW { actions together piecemeal Archive { $(AR) $(<) $(>:T) } actions Cc { $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>) } actions C++ { $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>) } actions DllLink bind DEFFILENAME IMPLIBNAME { $(LINK) $(LINKFLAGS) -shared -o $(<) $(>) $(DEFFILENAME) -Wl,--out-implib,$(IMPLIBNAME) } } else if $(JAM_TOOLSET) = WATCOM { actions together piecemeal Archive { $(AR) -q $(<) +-$(>) } actions Cc { $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo=$(<) -I$(STDHDRS) $(>) } actions C++ { $(C++) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo=$(<) -I$(STDHDRS) $(>) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME { $(LINK) $(LINKFLAGS) -l=NT_DLL -"export=$(DEFFILENAME) option implib=$(IMPLIBNAME)" /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } actions Shell { $(CP) $(>) $(<) } } else if $(JAM_TOOLSET) = LCC { actions together piecemeal Archive { $(AR) /out:$(<) $(>) } actions Cc { $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -Fo$(<) -I$(STDHDRS) $(>) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } actions DllLink bind NEEDLIBS DEFFILENAME { $(LINK) $(LINKFLAGS) -DLL -o $(<) $(UNDEFS) $(>) $(DEFFILENAME) $(NEEDLIBS) $(LINKLIBS) } actions ignore DllLinkMv { $(MV) $(2) $(1) } actions Shell { $(CP) $(>) $(<) } } else if $(JAM_TOOLSET) = DIGITALMARS { actions together piecemeal Archive { $(AR) $(<) $(>) } actions Cc { $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -o$(<) -I$(STDHDRS) $(>) } actions C++ { $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -o$(<) -I$(STDHDRS) $(>) } # note: we don't generate MAP files here ! actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) $(>),$(<),NUL, $(NEEDLIBS) $(LINKLIBS) } # note: we don't generate MAP files here ! actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME { $(LINK) $(LINKFLAGS) /IMPLIB:$(IMPLIBNAME) $(>) , $(<) ,NUL, $(LINKLIBS:E) $(NEEDLIBS:E) , $(DEFFILENAME) } actions Shell { $(CP) $(>) $(<) } } else if $(JAM_TOOLSET) = PELLESC { actions together piecemeal Archive { $(AR) /OUT:$(<) $(>) } actions Cc { $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo $(<) -I$(STDHDRS) $(>) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS) } actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME { $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS) } actions Shell { $(CP) $(>) $(<) } } } # # OS2 specific actions # else if $(OS2) { if $(JAM_TOOLSET) = WATCOM { actions together piecemeal Archive { $(AR) -q $(<) +-$(>) } actions Cc { $(CC) /Fo=$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions C++ { $(C++) /Fo=$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions Link bind NEEDLIBS { $(LINK) -q $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } actions Shell { $(CP) $(>) $(<) } } else if $(JAM_TOOLSET) = EMX { actions together piecemeal Archive { $(AR) $(<) $(>:T) } actions Cc { $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions C++ { $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } } } # # VMS specific actions # else if $(VMS) { actions updated together piecemeal Archive { lib/replace $(<) $(>[1]) ,$(>[2-]) } actions Cc { $(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions C++ { $(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>) } actions piecemeal together existing Clean { $(RM) $(>[1]);* ,$(>[2-]);* } actions together quietly CreLib { if f$search("$(<)") .eqs. "" then lib/create $(<) } actions GenFile1 { mcr $(>[1]) $(<) $(>[2-]) } actions Link bind NEEDLIBS { $(LINK)/exe=$(<) $(LINKFLAGS) $(>:J=,) ,$(NEEDLIBS)/lib ,$(LINKLIBS) } actions quietly updated piecemeal together RmTemps { $(RM) $(>[1]);* ,$(>[2-]);* } actions Shell { $(CP) $(>) $(<) } } # # Mac specifc actions # else if $(MAC) { actions together Archive { $(LINK) -library -o $(<) $(>) } actions Cc { set -e MWCincludes $(CCHDRS) $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(>) } actions C++ { set -e MWCincludes $(CCHDRS) $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(>) } actions Link bind NEEDLIBS { $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)" } } if $(WIN98) { actions existing Clean { del $(>) } } # # Backwards compatibility with jam 1, where rules were uppercased. # rule BULK { Bulk $(<) : $(>) ; } rule FILE { File $(<) : $(>) ; } rule HDRRULE { HdrRule $(<) : $(>) ; } rule INSTALL { Install $(<) : $(>) ; } rule LIBRARY { Library $(<) : $(>) ; } rule LIBS { LinkLibraries $(<) : $(>) ; } rule LINK { Link $(<) : $(>) ; } rule MAIN { Main $(<) : $(>) ; } rule SETUID { Setuid $(<) ; } rule SHELL { Shell $(<) : $(>) ; } rule UNDEFINES { Undefines $(<) : $(>) ; } # Old INSTALL* didn't take dest directory. rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; } rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; } rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; } # Compatibility with jam 2.2. rule addDirName { $(<) += [ FDirName $(>) ] ; } rule makeCommon { FStripCommon $(<) : $(>) ; } rule _makeCommon { FStripCommon $(<) : $(>) ; } rule makeDirName { $(<) = [ FDirName $(>) ] ; } rule makeGrist { $(<) = [ FGrist $(>) ] ; } rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; } rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; } rule makeString { $(<) = $(>:J) ; } rule makeSubDir { $(<) = [ FSubDir $(>) ] ; } rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; } # # special package-management rules # # check that the package root directory is set # otherwise, set it to $HOME/packages by default # # $(1) : list variable identifier # $(2) : new list # rule _PkgAppend { local result = $($(1)) ; local i ; for i in $(2) { if ! $(i) in $(result) { result += $(i) ; } } $(1) = $(result) ; } # $(1) : list variable identifier # $(2) : new list # rule _PkgPrepend { local result = $($(1)) ; local i ; for i in $(2) { if ! $(i) in $(result) { result = $(i) $(result) ; } } $(1) = $(result) ; } # $(1) : Package Name # $(2) : optional top-level installation directory # rule PkgBegin { if $(_PKG_NAME) { Echo "nested package declarations are not allowed. please use" Exit "PkgEnd to finish" $(_PKG_NAME)"'s declaration" ; } if ! $(PACKAGE_ROOT) { PACKAGE_ROOT = [ FDirName $(HOME) packages ] ; Echo "PACKAGE_ROOT variable not set, using" $(PACKAGE_ROOT) "directory" ; } _PKG_NAME = $(1[1]) ; _PKG_DESC = [ FDirName $(PACKAGE_ROOT) $(_PKG_NAME).pc ] ; _PKG_TOP = $(2) ; if ! $(_PKG_TOP) { _PKG_TOP = [ FDirName $(PACKAGE_ROOT) $(_PKG_NAME) ] ; } _PKG_ORG_HDRS = $(HDRS) ; _PKG_ORG_DEFINES = $(DEFINES) ; _PKG_ORG_LINKLIBS = $(LINKLIBS) ; _PKG_ORG_SUBDIRHDRS = $(SUBDIRHDRS) ; pkg-$(_PKG_NAME)-top = $(_PKG_TOP) ; _PKG_USES = ; _PKG_DEFINES = ; _PKG_INCLUDES = ; _PKG_LIBS = ; _PKG_DO_INSTALL = ; _PKG_ALL_USES = ; _PkgUpdate ; } rule PkgEnd { if $(_PKG_DO_INSTALL) { _PkgGeneratePc $(_PKG_DESC) ; PKG on $(_PKG_DESC) = $(_PKG_NAME) ; } HDRS = $(_PKG_ORG_HDRS) ; DEFINES = $(_PKG_ORG_DEFINES) ; LINKLIBS = $(_PKG_ORG_LINKLIBS) ; SUBDIRHDRS = $(_PKG_ORG_SUBDIRHDRS) ; _PKG_NAME = ; _PKG_DO_INSTALL = ; } # # rule _PkgReverse { local p ; result = $(1[1]) ; for p in $(1[2-]) { result = $(p) $(result) ; } return $(result) ; } # $(1) : package descriptor file path # rule _PkgGeneratePc { MkDir $(PACKAGE_ROOT) ; Depends $(1) : $(PACKAGE_ROOT) ; Depends install : $(1) ; Clean uninstall : $(1) ; Always $(1) ; # always re-install, overwrite old version } if $(UNIX) { actions _PkgGeneratePc { echo "# this file was generated automatically - do not edit" > $(1) echo "pkg-$(PKG)-uses = $(pkg-$(PKG)-uses) ;" >> $(1) echo "pkg-$(PKG)-libs = $(pkg-$(PKG)-libs:Q) ;" >> $(1) echo "pkg-$(PKG)-defines = $(pkg-$(PKG)-defines) ;" >> $(1) echo "pkg-$(PKG)-includes = $(pkg-$(PKG)-includes:Q) ;" >> $(1) echo "pkg-$(PKG)-ok = 1 ;" >> $(1) } } else { actions _PkgGeneratePc { echo # this file was generated automatically - do not edit > $(1) echo pkg-$(PKG)-uses = $(pkg-$(PKG)-uses) ; >> $(1) echo pkg-$(PKG)-libs = $(pkg-$(PKG)-libs:Q) ; >> $(1) echo pkg-$(PKG)-defines = $(pkg-$(PKG)-defines) ; >> $(1) echo pkg-$(PKG)-includes = $(pkg-$(PKG)-includes:Q) ; >> $(1) echo pkg-$(PKG)-ok = 1 ; >> $(1) } } rule PkgInstallPc { # nothing, this is now handled automatically by PkgEnd } # recomputes current package's settings whenever needed # # no arguments # rule _PkgUpdate { local p z ; _PKG_ALL_DEFINES = ; _PKG_ALL_INCLUDES = ; _PKG_ALL_LIBS = ; _PKG_USE_LIBS = ; for p in $(_PKG_ALL_USES) { _PkgAppend _PKG_ALL_DEFINES : $(pkg-$(p)-defines) ; _PkgAppend _PKG_ALL_INCLUDES : $(pkg-$(p)-includes) ; } for p in [ _PkgReverse $(_PKG_ALL_USES) ] { local thelibs = $(pkg-$(p)-libs) ; _PKG_ALL_LIBS += $(thelibs) ; _PKG_USE_LIBS += $(thelibs[1]) ; } _PkgAppend _PKG_ALL_DEFINES : $(_PKG_DEFINES) ; _PkgAppend _PKG_ALL_INCLUDES : $(_PKG_INCLUDES) ; HDRS = $(_PKG_ORG_HDRS) $(_PKG_ALL_INCLUDES) ; DEFINES = $(_PKG_ORG_DEFINES) $(_PKG_ALL_DEFINES) ; LINKLIBS = $(_PKG_ORG_LINKLIBS) $(_PKG_ALL_LIBS) ; pkg-$(_PKG_NAME)-includes = $(_PKG_INCLUDES) ; pkg-$(_PKG_NAME)-defines = $(_PKG_DEFINES) ; pkg-$(_PKG_NAME)-uses = $(_PKG_USES) ; pkg-$(_PKG_NAME)-libs = $(_PKG_LIBS) ; } # $(1) : list of packages to use # $(2) : name of missing packages variable # rule _PkgUses { local p ; for p in $(1) { if ! $(p) in $(_PKG_ALL_USES) { local pcfile = [ FDirName $(PACKAGE_ROOT) $(p).pc ] ; NoCare $(pcfile) ; include $(pcfile) ; if ! $(pkg-$(p)-ok) { $(2) += $(p) ; } else if $(pkg-$(p)-uses) { _PkgUses $(pkg-$(p)-uses) ; } _PKG_ALL_USES += $(p) ; } } } # $(1) : Package name list # rule PkgUses { local pkg-missing = ; _PkgUses $(1) : pkg-missing ; if $(pkg-missing) { Exit "Please install the following required packages:" $(pkg-missing) ; } _PkgPrepend _PKG_USES : $(1) ; _PkgUpdate ; } # $(1) : target directory # $(2) : list of sources relative to $(3) # $(3) : top source directory # rule _PkgMakeLocate { local top = $(3:E=$(DOT)) ; local dir file ss ; local dirs ; for ss in $(2) { file = [ FDirName $(top) $(ss:G="") ] ; dir = $(1) ; if $(ss:D) { dir = [ FDirName $(dir) $(ss:D) ] ; } LOCATE on $(ss) = $(1) ; Depends $(ss) : $(dir) ; if ! $(dir) in $(dirs) { dirs += $(dir) ; } } MkDir $(dirs) ; } # $(1) : target directory # $(2) : list of source files relative to $(3) # $(3) : top source directory # rule _PkgInstallInto { # InstallInto dir : sources ; local sources = $(2) ; local targets = $(sources:G=$(INSTALLGRIST)) ; # Arrange for jam install # Arrange for jam uninstall # sources are in SEARCH_SOURCE # targets are in dir Depends install : $(targets) ; Clean uninstall : $(targets) ; _PkgMakeLocate $(1) : $(targets) : $(3) ; # For each source, make gristed target name # and Install, Chmod, Chown, and Chgrp for s in $(sources) { local t = $(s:G=$(INSTALLGRIST)) ; Depends $(t) : $(s) ; SEARCH on $(s) = $(3) ; Install $(t) : $(s) ; Chmod $(t) ; if $(OWNER) && $(CHOWN) { Chown $(t) ; OWNER on $(t) = $(OWNER) ; } if $(GROUP) && $(CHGRP) { Chgrp $(t) ; GROUP on $(t) = $(GROUP) ; } } } # $(1) : target directory # $(2) : list of source binaries # $(3) : top source directory # rule _PkgInstallBin { local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ; _PkgInstallInto $(<) : $(_t) : $(3) ; MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ; } # $(1) : target directory # $(2) : list of source shells # $(3) : top source directory # rule _PkgInstallShell { _PkgInstallInto $(1) : $(2) : $(3) ; MODE on $(2:G=$(INSTALLGRIST)) = $(SHELLMODE) ; } # $(1) : target directory # $(2) : list of source files # $(3) : top source directory # rule _PkgInstallFile { _PkgInstallInto $(1) : $(2) : $(3) ; MODE on $(2:G=$(INSTALLGRIST)) = $(FILEMODE) ; } # $(1) : list of include paths # rule PkgIncludes { _PKG_INCLUDES += $(1) ; _PkgUpdate ; } rule PkgDefines { _PKG_DEFINES += $(1) ; _PkgUpdate ; } # $(1) : list of header files # $(2) : top-level source directory # $(3) : optional directory suffix # rule PkgInstallHeader { local dir = [ FDirName $(_PKG_TOP) include ] ; _PKG_DO_INSTALL = 1 ; _PkgInstallFile [ FDirName $(dir) $(3) ] : $(1) : $(2) ; _PkgAppend _PKG_INCLUDES : $(dir) ; _PkgUpdate ; } # $(1) : library name # rule PkgInstallLib { local lib = $(1:S=$(SUFLIB)) ; local dir = [ FDirName $(_PKG_TOP) lib ] ; _PKG_DO_INSTALL = 1 ; _PkgInstallFile $(dir) : $(lib) : $(DOT) ; _PkgPrepend _PKG_LIBS : [ FDirName $(dir) $(lib) ] ; _PkgUpdate ; } # $(1) : required library names or link flags # rule PkgNeedLib { _PkgAppend _PKG_LIBS : $(1) ; _PkgUpdate ; } rule PkgMain { MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ; Objects $(>) ; LINKLIBS on $(<:S=$(SUFEXE)) += $(LINKLIBS) ; Depends $(<:S=$(SUFEXE)) : $(_PKG_USE_LIBS) ; } # $(1) : list of directories relative to $(2) # $(2) : top search directory # $(3) : pattern # rule PkgGlob { local files dir ; files = [ GLOB [ FDirName $(2) $(1) ] : $(3) ] ; dir = [ FDirName $(1) ] ; return $(files:D=$(dir)) ; } # # Now include the user's Jamfile. # include $(JAMFILE) ; ftjam-2.5.2/fileunix.c0000744000424500003730000002215110441006327014401 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * fileunix.c - manipulate file names and scan directories on UNIX/AmigaOS * * External routines: * * file_dirscan() - scan a directory for files * file_time() - get timestamp of file, if not done by file_dirscan() * file_archscan() - scan an archive for files * * File_dirscan() and file_archscan() call back a caller provided function * for each file found. A flag to this callback function lets file_dirscan() * and file_archscan() indicate that a timestamp is being provided with the * file. If file_dirscan() or file_archscan() do not provide the file's * timestamp, interested parties may later call file_time(). * * 04/08/94 (seiwald) - Coherent/386 support added. * 12/19/94 (mikem) - solaris string table insanity support * 02/14/95 (seiwald) - parse and build /xxx properly * 05/03/96 (seiwald) - split into pathunix.c * 11/21/96 (peterk) - BEOS does not have Unix-style archives * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan * 04/03/01 (seiwald) - AIX uses SARMAG * 07/16/02 (seiwald) - Support BSD style long filename in archives. * 11/04/02 (seiwald) - const-ing for string literals * 12/27/02 (seiwald) - support for AIX big archives * 12/30/02 (seiwald) - terminate ar_hdr for solaris sscanf() * 12/30/02 (seiwald) - skip solaris' empty archive member names (/, //xxx) */ # include "jam.h" # include "filesys.h" # include "pathsys.h" # ifdef USE_FILEUNIX # if defined( OS_SEQUENT ) || \ defined( OS_DGUX ) || \ defined( OS_SCO ) || \ defined( OS_ISC ) # define PORTAR 1 # endif # if defined(__EMX__) # include # include # endif # if defined( OS_RHAPSODY ) || \ defined( OS_MACOSX ) || \ defined( OS_NEXT ) /* need unistd for rhapsody's proper lseek */ # include # include # define STRUCT_DIRENT struct direct # else # include # define STRUCT_DIRENT struct dirent # endif # ifdef OS_COHERENT # include # define HAVE_AR # endif # if defined( OS_MVS ) || \ defined( OS_INTERIX ) #define ARMAG "!\n" #define SARMAG 8 #define ARFMAG "`\n" struct ar_hdr /* archive file member header - printable ascii */ { char ar_name[16]; /* file member name - `/' terminated */ char ar_date[12]; /* file member date - decimal */ char ar_uid[6]; /* file member user id - decimal */ char ar_gid[6]; /* file member group id - decimal */ char ar_mode[8]; /* file member mode - octal */ char ar_size[10]; /* file member size - decimal */ char ar_fmag[2]; /* ARFMAG - string to end header */ }; # define HAVE_AR # endif # if defined( OS_QNX ) || \ defined( OS_BEOS ) || \ defined( OS_MPEIX ) # define NO_AR # define HAVE_AR # endif # ifndef HAVE_AR # ifdef _AIX43 /* AIX 43 ar SUPPORTs only __AR_BIG__ */ # define __AR_BIG__ # endif # include # endif /* * file_dirscan() - scan a directory for files */ void file_dirscan( const char *dir, scanback func, void *closure ) { PATHNAME f; DIR *d; STRUCT_DIRENT *dirent; char filename[ MAXJPATH ]; /* First enter directory itself */ memset( (char *)&f, '\0', sizeof( f ) ); f.f_dir.ptr = dir; f.f_dir.len = strlen(dir); dir = *dir ? dir : "."; /* Special case / : enter it */ if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '/' ) (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); /* Now enter contents of directory */ if( !( d = opendir( dir ) ) ) return; if( DEBUG_BINDSCAN ) printf( "scan directory %s\n", dir ); while( dirent = readdir( d ) ) { # ifdef old_sinix /* Broken structure definition on sinix. */ f.f_base.ptr = dirent->d_name - 2; # else f.f_base.ptr = dirent->d_name; # endif f.f_base.len = strlen( f.f_base.ptr ); path_build( &f, filename, 0 ); (*func)( closure, filename, 0 /* not stat()'ed */, (time_t)0 ); } closedir( d ); } /* * file_time() - get timestamp of file, if not done by file_dirscan() */ int file_time( const char *filename, time_t *time ) { struct stat statbuf; if( stat( filename, &statbuf ) < 0 ) return -1; *time = statbuf.st_mtime; return 0; } /* * file_archscan() - scan an archive for files */ # ifndef AIAMAG /* God-fearing UNIX */ # define SARFMAG 2 # define SARHDR sizeof( struct ar_hdr ) void file_archscan( const char *archive, scanback func, void *closure ) { # ifndef NO_AR struct ar_hdr ar_hdr; char buf[ MAXJPATH ]; long offset; char *string_table = 0; int fd; if( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 ) return; if( read( fd, buf, SARMAG ) != SARMAG || strncmp( ARMAG, buf, SARMAG ) ) { close( fd ); return; } offset = SARMAG; if( DEBUG_BINDSCAN ) printf( "scan archive %s\n", archive ); while( read( fd, &ar_hdr, SARHDR ) == SARHDR && !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) ) { long lar_date; long lar_size; char lar_name[256]; char *dst = lar_name; /* solaris sscanf() does strlen first, so terminate somewhere */ ar_hdr.ar_fmag[0] = 0; /* Get date & size */ sscanf( ar_hdr.ar_date, "%ld", &lar_date ); sscanf( ar_hdr.ar_size, "%ld", &lar_size ); /* Handle solaris string table. ** The entry under the name // is the table, ** and entries with the name /nnnn refer to the table. */ if( ar_hdr.ar_name[0] != '/' ) { /* traditional archive entry names: ** ends at the first space, /, or null. */ char *src = ar_hdr.ar_name; const char *e = src + sizeof( ar_hdr.ar_name ); while( src < e && *src && *src != ' ' && *src != '/' ) *dst++ = *src++; } else if( ar_hdr.ar_name[1] == '/' ) { /* this is the "string table" entry of the symbol table, ** which holds strings of filenames that are longer than ** 15 characters (ie. don't fit into a ar_name) */ string_table = (char *)malloc(lar_size); lseek(fd, offset + SARHDR, 0); if( read(fd, string_table, lar_size) != lar_size ) printf( "error reading string table\n" ); } else if( string_table && ar_hdr.ar_name[1] != ' ' ) { /* Long filenames are recognized by "/nnnn" where nnnn is ** the offset of the string in the string table represented ** in ASCII decimals. */ char *src = string_table + atoi( ar_hdr.ar_name + 1 ); while( *src != '/' ) *dst++ = *src++; } /* Terminate lar_name */ *dst = 0; /* Modern (BSD4.4) long names: if the name is "#1/nnnn", ** then the actual name is the nnnn bytes after the header. */ if( !strcmp( lar_name, "#1" ) ) { int len = atoi( ar_hdr.ar_name + 3 ); if( read( fd, lar_name, len ) != len ) printf("error reading archive entry\n"); lar_name[len] = 0; } /* Build name and pass it on. */ if( lar_name[0] ) { if( DEBUG_BINDSCAN ) printf( "archive name %s found\n", lar_name ); sprintf( buf, "%s(%s)", archive, lar_name ); (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date ); } /* Position at next member */ offset += SARHDR + ( ( lar_size + 1 ) & ~1 ); lseek( fd, offset, 0 ); } if (string_table) free(string_table); close( fd ); # endif /* NO_AR */ } # else /* AIAMAG - RS6000 AIX */ void file_archscan( const char *archive, scanback func, void *closure ) { struct fl_hdr fl_hdr; struct { struct ar_hdr hdr; char pad[ 256 ]; } ar_hdr ; char buf[ MAXJPATH ]; long offset; int fd; if( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 ) return; # ifdef __AR_BIG__ if( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ || strncmp( AIAMAGBIG, fl_hdr.fl_magic, SAIAMAG ) ) { if( strncmp( AIAMAG, fl_hdr.fl_magic, SAIAMAG ) ) printf( "Can't read new archive %s before AIX 4.3.\n" ); close( fd ); return; } # else if( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ || strncmp( AIAMAG, fl_hdr.fl_magic, SAIAMAG ) ) { close( fd ); return; } # endif sscanf( fl_hdr.fl_fstmoff, "%ld", &offset ); if( DEBUG_BINDSCAN ) printf( "scan archive %s\n", archive ); while( offset > 0 && lseek( fd, offset, 0 ) >= 0 && read( fd, &ar_hdr, sizeof( ar_hdr ) ) >= sizeof( ar_hdr.hdr ) ) { long lar_date; int lar_namlen; sscanf( ar_hdr.hdr.ar_namlen, "%d", &lar_namlen ); sscanf( ar_hdr.hdr.ar_date, "%ld", &lar_date ); sscanf( ar_hdr.hdr.ar_nxtmem, "%ld", &offset ); if( !lar_namlen ) continue; ar_hdr.hdr._ar_name.ar_name[ lar_namlen ] = '\0'; sprintf( buf, "%s(%s)", archive, ar_hdr.hdr._ar_name.ar_name ); (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date ); } close( fd ); } # endif /* AIAMAG - RS6000 AIX */ # endif /* USE_FILEUNIX */ ftjam-2.5.2/scan.c0000744000424500003730000001763210441006327013512 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * scan.c - the jam yacc scanner * * 12/26/93 (seiwald) - bump buf in yylex to 10240 - yuk. * 09/16/94 (seiwald) - check for overflows, unmatched {}'s, etc. * Also handle tokens abutting EOF by remembering * to return EOF now matter how many times yylex() * reinvokes yyline(). * 02/11/95 (seiwald) - honor only punctuation keywords if SCAN_PUNCT. * 07/27/95 (seiwald) - Include jamgram.h after scan.h, so that YYSTYPE is * defined before Linux's yacc tries to redefine it. * 01/10/01 (seiwald) - \ can now escape any whitespace char * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "lists.h" # include "parse.h" # include "scan.h" # include "jamgram.h" # include "jambase.h" # include "newstr.h" struct keyword { const char *word; int type; } keywords[] = { # include "jamgramtab.h" { 0, 0 } } ; struct include { struct include *next; /* next serial include file */ const char *string; /* pointer into current line */ char **strings; /* for yyfparse() -- text to parse */ FILE *file; /* for yyfparse() -- file being read */ const char *fname; /* for yyfparse() -- file name */ int line; /* line counter for error messages */ char buf[ 512 ]; /* for yyfparse() -- line buffer */ } ; static struct include *incp = 0; /* current file; head of chain */ static int scanmode = SCAN_NORMAL; static int anyerrors = 0; static char *symdump( YYSTYPE *s ); # define BIGGEST_TOKEN 10240 /* no single token can be larger */ /* * Set parser mode: normal, string, or keyword */ void yymode( int n ) { scanmode = n; } void yyerror( const char *s ) { if( incp ) printf( "%s: line %d: ", incp->fname, incp->line ); printf( "%s at %s\n", s, symdump( &yylval ) ); ++anyerrors; } int yyanyerrors() { return anyerrors != 0; } void yyfparse( const char *s ) { struct include *i = (struct include *)malloc( sizeof( *i ) ); /* Push this onto the incp chain. */ i->string = ""; i->strings = 0; i->file = 0; i->fname = copystr( s ); i->line = 0; i->next = incp; incp = i; /* If the filename is "+", it means use the internal jambase. */ if( !strcmp( s, "+" ) ) i->strings = jambase; } /* * yyline() - read new line and return first character * * Fabricates a continuous stream of characters across include files, * returning EOF at the bitter end. */ int yyline() { struct include *i = incp; if( !incp ) return EOF; /* Once we start reading from the input stream, we reset the */ /* include insertion point so that the next include file becomes */ /* the head of the list. */ /* If there is more data in this line, return it. */ if( *i->string ) return *i->string++; /* If we're reading from an internal string list, go to the */ /* next string. */ if( i->strings ) { if( !*i->strings ) goto next; i->line++; i->string = *(i->strings++); return *i->string++; } /* If necessary, open the file */ if( !i->file ) { FILE *f = stdin; if( strcmp( i->fname, "-" ) && !( f = fopen( i->fname, "r" ) ) ) perror( i->fname ); i->file = f; } /* If there's another line in this file, start it. */ if( i->file && fgets( i->buf, sizeof( i->buf ), i->file ) ) { i->line++; i->string = i->buf; return *i->string++; } next: /* This include is done. */ /* Free it up and return EOF so yyparse() returns to parse_file(). */ incp = i->next; /* Close file, free name */ if( i->file && i->file != stdin ) fclose( i->file ); freestr( i->fname ); free( (char *)i ); return EOF; } /* * yylex() - set yylval to current token; return its type * * Macros to move things along: * * yychar() - return and advance character; invalid after EOF * yyprev() - back up one character; invalid before yychar() * * yychar() returns a continuous stream of characters, until it hits * the EOF of the current include file. */ # define yychar() ( *incp->string ? *incp->string++ : yyline() ) # define yyprev() ( incp->string-- ) int yylex() { int c; char buf[BIGGEST_TOKEN]; char *b = buf; if( !incp ) goto eof; /* Get first character (whitespace or of token) */ c = yychar(); if( scanmode == SCAN_STRING ) { /* If scanning for a string (action's {}'s), look for the */ /* closing brace. We handle matching braces, if they match! */ int nest = 1; while( c != EOF && b < buf + sizeof( buf ) ) { if( c == '{' ) nest++; if( c == '}' && !--nest ) break; *b++ = c; c = yychar(); } /* We ate the ending brace -- regurgitate it. */ if( c != EOF ) yyprev(); /* Check obvious errors. */ if( b == buf + sizeof( buf ) ) { yyerror( "action block too big" ); goto eof; } if( nest ) { yyerror( "unmatched {} in action block" ); goto eof; } *b = 0; yylval.type = STRING; yylval.string = newstr( buf ); } else { char *b = buf; struct keyword *k; int inquote = 0; int notkeyword; /* Eat white space */ for( ;; ) { /* Skip past white space */ while( c != EOF && isspace( c ) ) c = yychar(); /* Not a comment? Swallow up comment line. */ if( c != '#' ) break; while( ( c = yychar() ) != EOF && c != '\n' ) ; } /* c now points to the first character of a token. */ if( c == EOF ) goto eof; /* While scanning the word, disqualify it for (expensive) */ /* keyword lookup when we can: $anything, "anything", \anything */ notkeyword = c == '$'; /* look for white space to delimit word */ /* "'s get stripped but preserve white space */ /* \ protects next character */ while( c != EOF && b < buf + sizeof( buf ) && ( inquote || !isspace( c ) ) ) { if( c == '"' ) { /* begin or end " */ inquote = !inquote; notkeyword = 1; } else if( c != '\\' ) { /* normal char */ *b++ = c; } else if( ( c = yychar()) != EOF ) { /* \c */ *b++ = c; notkeyword = 1; } else { /* \EOF */ break; } c = yychar(); } /* Check obvious errors. */ if( b == buf + sizeof( buf ) ) { yyerror( "string too big" ); goto eof; } if( inquote ) { yyerror( "unmatched \" in string" ); goto eof; } /* We looked ahead a character - back up. */ if( c != EOF ) yyprev(); /* scan token table */ /* don't scan if it's obviously not a keyword or if its */ /* an alphabetic when were looking for punctuation */ *b = 0; yylval.type = ARG; if( !notkeyword && !( isalpha( *buf ) && scanmode == SCAN_PUNCT ) ) { for( k = keywords; k->word; k++ ) if( *buf == *k->word && !strcmp( k->word, buf ) ) { yylval.type = k->type; yylval.string = k->word; /* used by symdump */ break; } } if( yylval.type == ARG ) yylval.string = newstr( buf ); } if( DEBUG_SCAN ) printf( "scan %s\n", symdump( &yylval ) ); return yylval.type; eof: yylval.type = EOF; return yylval.type; } static char * symdump( YYSTYPE *s ) { static char buf[ BIGGEST_TOKEN + 20 ]; switch( s->type ) { case EOF: sprintf( buf, "EOF" ); break; case 0: sprintf( buf, "unknown symbol %s", s->string ); break; case ARG: sprintf( buf, "argument %s", s->string ); break; case STRING: sprintf( buf, "string \"%s\"", s->string ); break; default: sprintf( buf, "keyword %s", s->string ); break; } return buf; } ftjam-2.5.2/patchlevel.h0000744000424500003730000000025010441006332014702 0ustar dturnermhpsys/* Keep JAMVERSYM in sync with VERSION. */ /* It can be accessed as $(JAMVERSION) in the Jamfile. */ #define VERSION "2.5.2" #define JAMVERSYM "JAMVERSION=2.5.2" ftjam-2.5.2/Jam.html0000744000424500003730000012347510441006330014014 0ustar dturnermhpsys Jam - Make(1) Redux

Jam - Make(1) Redux

The Jam Executable

USAGE

jam [ -a ] [ -g ] [ -n ] [ -q ] [ -v ]
    [ -d debug ] 
    [ -f jambase ] 
    [ -j jobs ] 
    [ -o actionsfile ] 
    [ -s var=value ] 
    [ -t target ] 
    [ target ... ]

DESCRIPTION

Jam is a program construction tool, like make(1).

Jam recursively builds target files from source files, using dependency information and updating actions expressed in the Jambase file, which is written in jam's own interpreted language. The default Jambase is compiled into jam and provides a boilerplate for common use, relying on a user-provide file "Jamfile" to enumerate actual targets and sources.

The Jambase is described in the Jambase Reference and the document Using Jamfiles and Jambase.

OPTIONS

If target is provided on the command line, jam builds target; otherwise jam builds the target 'all'.

Jam may be invoked with the following options:

-a Build all targets anyway, even if they are up-to-date.
-d c Turn on display option c and off the default display (summary info and actions):
a
Show summary info, actions, quiet actions, and the use of temporary targets
c
Show the names of files that cause rebuilds, i.e. new sources, missing targets, etc.
d
Display a dependency graph (in jam syntax).
m
Display the dependency analysis, and target/source timestamps and paths
x
Show shell arguments
-d n Enable cummulative debugging levels from 1 to n. Interesting values are:
1
Show actions and summary info (the default)
3
Old name for -dm (described above)
5
Show rule invocations and variable expansions
6
Show directory/header file/archive scans
7
Show variable settings
8
Show variable fetches
9
Show variable manipulation, scanner tokens
-d +n Enable debugging level n.
-d 0 Turn off all debugging levels. Only errors are emitted.
-f jambase Read jambase instead of using the built-in Jambase. Multiple -f flags are permitted.
-g Build targets with the newest sources first, rather than in the order of appearance in the Jambase/Jamfiles.
-j n Run up to n shell commands concurrently (UNIX and NT only). The default is 1.
-n Don't actually execute the updating actions, but do everything else. This changes the debug level to -dax.
-o file Write the updating actions to the specified file instead of running them (or outputting them, as on the Mac).
-q Quit quickly (as if an interrupt was received) as soon as any target build fails.
-s var=value Set the variable var to value, overriding both internal variables and variables imported from the environment.
-t target Rebuild target and everything that depends on it, even if it is up-to-date.
-v Print the version of jam and exit.

OPERATION

Jam has four phases of operation: start-up, parsing, binding, and updating.

Start-up

Upon start-up, jam imports environment variable settings into jam variables. Environment variables are split at blanks with each word becoming an element in the variable's list of values. Environment variables whose names end in PATH are split at $(SPLITPATH) characters (e.g., ":" for Unix).

To set a variable's value on the command line, overriding the variable's environment value, use the -s option. To see variable assignments made during jam's execution, use the -d+7 option.

Parsing

In the parsing phase, jam reads and executes the Jambase file, by default the built-in one. It is written in the jam language. See Language below. The last action of the Jambase is to read (via the "include" rule) a user-provided file called "Jamfile".

Collectively, the purpose of the Jambase and the Jamfile is to name built target and source files, construct the dependency graph among them, and associate build actions with targets. The Jambase defines boilerplate rules and variable assignments, and the Jamfile uses these to specify the actual relationship among the target and source files. See the Jambase Reference and the document Using Jamfiles and Jambase for information.

Binding

Binding
After parsing, jam recursively descends the dependency graph and binds every file target with a location in the filesystem.

Targets
Any string value in jam can represent a target, and it does so if the DEPENDS or INCLUDES rules make it part of the dependency graph. Build targets are files to be updated. Source targets are the files used in updating build targets. Build targets and source targets are collectively referred to as file targets, and frequently build targets are source targets for other build targets. Pseudotargets are symbols which represent dependencies on other targets, but which are not themselves associated with any real file.

A file target's identifier is generally the file's name, which can be absolutely rooted, relative to the directory of jam's invocation, or simply local (no directory). Most often it is the last case, and the actual file path is bound using the $(SEARCH) and $(LOCATE) special variables. See SEARCH and LOCATE Variables below. A local filename is optionally qualified with "grist," a string value used to assure uniqueness. A file target with an identifier of the form file(member) is a library member (usually an ar(1) archive on UNIX).

The use of $(SEARCH) and $(LOCATE) allows jam to separate the the location of files from their names, so that Jamfiles can refer to files locally (i.e. relative to the Jamfile's directory), yet still be usable when jam is invoked from a distant directory. The use of grist allows files with the same name to be identified uniquely, so that jam can read a whole directory tree of Jamfiles and not mix up same-named targets.

Update Determination
After binding each target, jam determines whether the target needs updating, and if so marks the target for the updating phase. A target is normally so marked if it is missing, it is older than any of its sources, or any of its sources are marked for updating. This behavior can be modified by the application of special built-in rules. See Modifying Binding below.

Header File Scanning
During the binding phase, jam also performs header file scanning, where it looks inside source files for the implicit dependencies on other files caused by C's #include syntax. This is controlled by the special variables $(HDRSCAN) and $(HDRRULE). The result of the scan is formed into a rule invocation, with the scanned file as the target and the found included file names as the sources. Note that this is the only case where rules are invoked outside the parsing phase. See HDRSCAN and HDRRULE Variables below.

Updating

After binding, jam again recursively descends the dependency graph, this time executing the update actions for each target marked for update during the binding phase. If a target's updating actions fail, then all other targets which depend on that target are skipped.

The -j flag instructs jam to build more than one target at a time. If there are multiple actions on a single target, they are run sequentially. The -g flag reorders builds so that targets with newest sources are built first. Normally, they are built in the order of appearance in the Jamfiles.

LANGUAGE

Overview

Jam has a interpreted, procedural language with a few select features to effect program construction. Statements in jam are rule (procedure) definitions, rule invocations, updating action definitions, flow-of-control structures, variable assignments, and sundry language support.

Lexical Features

Jam treats its input files as whitespace-separated tokens, with two exceptions: double quotes (") can enclose whitespace to embed it into a token, and everything between the matching curly braces ({}) in the definition of a updating actions is treated as a single string. A backslash (\) can escape a double quote, or any single whitespace character.

Jam requires whitespace (blanks, tabs, or newlines) to surround all tokens, including the colon (:) and semicolon (;) tokens.

Jam keywords (as mentioned in this document) are reserved and generally must be quoted with double quotes (") to be used as arbitrary tokens, such as variable or target names.

Datatype

Jam's only data type is a one-dimensional list of arbitrary strings. They arise as literal (whitespace-separated) tokens in the Jambase or included files, as the result of variable expansion of those tokens, or as the return value from a rule invocation.

Rules

The basic jam language entity is called a rule. A rule is simply a procedure definition, with a body of jam statements to be run when the rule is invoked. The syntax of rule invocation make it possible to write Jamfiles that look a bit like Makefiles.

Rules take up to 9 arguments ($(1) through $(9), each a list) and can have a return value (a single list). A rule's return value can be expanded in a list by enclosing the rule invocation with [ and ].

Updating Actions

A rule may have updating actions associated with it, in which case arguments $(1) and $(2) are treated as built targets and sources, respectively. Updating actions are the OS shell commands to execute when updating the built targets of the rule.

When an rule with updating actions is invoked, those actions are added to those associated with its built targets ($(1)) before the rule's procedure is run. Later, to build the targets in the updating phase, the actions are passed to the OS command shell, with $(1) and $(2) replaced by bound versions of the target names. See Binding above.

Statements

Jam's langauge has the following statements:

rulename field1 : field2 : ... : fieldN ;

Invoke a rule. A rule is invoked with values in field1 through fieldN (9 max). They may be referenced in the procedure's statements as $(1) through $(<9>N). $(<) and $(>) are synonymous with $(1) and $(2).

rulename undergoes variable expansion. If the resulting list is more than one value, each rule is invoked with the same arguments, and the result of the invocation is the concatenation of all the results.

actions [ modifiers ] rulename { commands }

Define a rule's updating actions, replacing any previous definition. The first two arguments may be referenced in the action's commands as $(1) and $(2) or $(<) and $(>).

The following action modifiers are understood:

actions bind vars $(vars) will be replaced with bound values.
actions existing $(>) includes only source targets currently existing.
actions ignore The return status of the commands is ignored.
actions piecemeal commands are repeatedly invoked with a subset of $(>) small enough to fit in the command buffer on this OS.
actions quietly The action is not echoed to the standard output.
actions together The $(>) from multiple invocations of the same action on the same built target are glommed together.
actions updated $(>) includes only source targets themselves marked for updating.

break

Breaks out of the closest enclosing for or while loop.

continue

Jumps to the end of the closest enclosing for or while loop.

for var in list { statements }

Executes statements for each element in list, setting the variable var to the element value.

if cond { statements } [ else statement ]

Does the obvious; the else clause is optional. cond is built of:
a true if any a element is a non-zero-length string
a = b list a matches list b string-for-string
a != b list a does not match list b
a < b a[i] string is less than b[i] string, where i is first mismatched element in lists a and b
a <= b every a string is less than or equal to its b counterpart
a > b a[i] string is greater than b[i] string, where i is first mismatched element
a >= b every a string is greater than or equal to its b counterpart
a in b true if all elements of a can be found in b, or if a has no elements
! cond condition not true
cond && cond conjunction
cond || cond disjunction
( cond ) precedence grouping

include file ;

Causes jam to read the named file. The file is bound like a regular target (see Binding above) but unlike a regular target the include file cannot be built. Marking an include file target with the NOCARE rule makes it optional: if it is missing, it causes no error.

The include file is inserted into the input stream during the parsing phase. The primary input file and all the included file(s) are treated as a single file; that is, jam infers no scope boundaries from included files.

local vars [ = values ] ;

Creates new vars inside to the enclosing {} block, obscuring any previous values they might have. The previous values for vars are restored when the current block ends. Any rule called or file included will see the local and not the previous value (this is sometimes called Dynamic Scoping). The local statement may appear anywhere, even outside of a block (in which case the previous value is restored when the input ends). The vars are initialized to values if present, or left uninitialized otherwise.

on target statement ;

Run statement under the influence of target's target-specific variables. These variables become local copies during statement's run, but they may be updated as target-specific variables using the usual "variable on targets =" syntax.

return values ;

Within a rule body, the return statement sets the return value for an invocation of the rule and terminates the rule's execution.

rule rulename [ : vars ] { statements }

Define a rule's procedure, replacing any previous definition. If vars are provided, they are assigned the values of the parameters ($(1) to $(9)) when statements are executed, as with the local statement.

switch value
{
case pattern1 : statements ;
case pattern2 : statements ;
...
}

The switch statement executes zero or one of the enclosed statements, depending on which, if any, is the first case whose pattern matches value. The pattern values are not variable-expanded. The pattern values may include the following wildcards:
? match any single character
* match zero or more characters
[chars] match any single character in chars
[^chars] match any single character not in chars
\x match x (escapes the other wildcards)

while cond { statements }

Repeatedly execute statements while cond remains true upon entry. (See the description of cond expression syntax under if, above).

Variables

Jam variables are lists of zero or more elements, with each element being a string value. An undefined variable is indistinguishable from a variable with an empty list, however, a defined variable may have one more elements which are null strings. All variables are referenced as $(variable).

Variables are either global or target-specific. In the latter case, the variable takes on the given value only during the target's binding, header file scanning, and updating; and during the "on target statement" statement.

A variable is defined with:

variable = elements ;
variable += elements ;
variable ?= elements ;
variable on targets = elements ;
variable on targets += elements ;
variable on targets ?= elements ;

The first three forms set variable globally. The last three forms set a target-specific variable. The = operator replaces any previous elements of variable with elements; the += operation adds elements to variable's list of elements; the ?= operator sets variable only if it was previously unset. The last form "variable on targets ?= elements" checks to see if the target-specific, not the global, variable is set. (The ?= operator also has an old form "default =".)

Variables referenced in updating commands will be replaced with their values; target-specific values take precedence over global values. Variables passed as arguments ($(1) and $(2)) to actions are replaced with their bound values; the "bind" modifier can be used on actions to cause other variables to be replaced with bound values. See Action Modifiers above.

Jam variables are not re-exported to the environment of the shell that executes the updating actions, but the updating actions can reference jam variables with $(variable).

Variable Expansion

During parsing, jam performs variable expansion on each token that is not a keyword or rule name. Such tokens with embedded variable references are replaced with zero or more tokens. Variable references are of the form $(v) or $(vm), where v is the variable name, and m are optional modifiers.

Variable expansion in a rule's actions is similar to variable expansion in statements, except that the action string is tokenized at whitespace regardless of quoting.

The result of a token after variable expansion is the product of the components of the token, where each component is a literal substring or a list substituting a variable reference. For example:


$(X) -> a b c
t$(X) -> ta tb tc
$(X)z -> az bz cz
$(X)-$(X) -> a-a a-b a-c b-a b-b b-c c-a c-b c-c

The variable name and modifiers can themselves contain a variable reference, and this partakes of the product as well:


$(X) -> a b c
$(Y) -> 1 2
$(Z) -> X Y
$($(Z)) -> a b c 1 2

Because of this product expansion, if any variable reference in a token is undefined, the result of the expansion is an empty list. If any variable element is a null string, the result propagates the non-null elements:


$(X) -> a ""
$(Y) -> "" 1
$(Z) ->
*$(X)$(Y)* -> *a* *a1* ** *1*
*$(X)$(Z)* ->

A variable element's string value can be parsed into grist and filename-related components. Modifiers to a variable are used to select elements, select components, and replace components. The modifiers are:

[n] Select element number n (starting at 1). If the variable contains fewer than n elements, the result is a zero-element list.
[n-m] Select elements number n through m.
[n-] Select elements number n through the last.
:B Select filename base.
:S Select (last) filename suffix.
:M Select archive member name.
:D Select directory path.
:P Select parent directory.
:G Select grist.
:U Replace lowercase characters with uppercase.
:L Replace uppercase characters with lowercase.
:chars Select the components listed in chars.
:G=grist Replace grist with grist.
:D=path Replace directory with path.
:B=base Replace the base part of file name with base.
:S=suf Replace the suffix of file name with suf.
:M=mem Replace the archive member name with mem.
:R=root Prepend root to the whole file name, if not already rooted.
:E=value Use value instead if the variable is unset.
:J=joinval Concatentate list elements into single element, separated by joinval.

On VMS, $(var:P) is the parent directory of $(var:D); on Unix and NT, $(var:P) and $(var:D) are the same.

Built-in Rules

Jam has twelve built-in rules, all of which are pure procedure rules without updating actions. They are in three groups: the first builds the dependency graph; the second modifies it; and the third are just utility rules.

Dependency Building

DEPENDS targets1 : targets2 ;
Builds a direct dependency: makes each of targets1 depend on each of targets2. Generally, targets1 will be rebuilt if targets2 are themselves rebuilt are or are newer than targets1.

INCLUDES targets1 : targets2 ;
Builds a sibling dependency: makes any target that depends on any of targets1 also depend on each of targets2. This reflects the dependencies that arise when one source file includes another: the object built from the source file depends both on the original and included source file, but the two sources files don't depend on each other. For example:

DEPENDS foo.o : foo.c ;
INCLUDES foo.c : foo.h ;

"foo.o" depends on "foo.c" and "foo.h" in this example.

Modifying Binding

The six rules ALWAYS, LEAVES, NOCARE, NOTFILE, NOUPDATE, and TEMPORARY modify the dependency graph so that jam treats the targets differently during its target binding phase. See Binding above. Normally, jam updates a target if it is missing, if its filesystem modification time is older than any of its dependencies (recursively), or if any of its dependencies are being updated. This basic behavior can be changed by invoking the following rules:

ALWAYS targets ;
Causes targets to be rebuilt regardless of whether they are up-to-date (they must still be in the dependency graph). This is used for the clean and uninstall targets, as they have no dependencies and would otherwise appear never to need building. It is best applied to targets that are also NOTFILE targets, but it can also be used to force a real file to be updated as well.

LEAVES targets ;
Makes each of targets depend only on its leaf sources, and not on any intermediate targets. This makes it immune to its dependencies being updated, as the "leaf" dependencies are those without their own dependencies and without updating actions. This allows a target to be updated only if original source files change.

NOCARE targets ;
Causes jam to ignore targets that neither can be found nor have updating actions to build them. Normally for such targets jam issues a warning and then skips other targets that depend on these missing targets. The HdrRule in Jambase uses NOCARE on the header file names found during header file scanning, to let jam know that the included files may not exist. For example, if a #include is within an #ifdef, the included file may not actually be around.

NOTFILE targets ;
Marks targets as pseudotargets and not real files. No timestamp is checked, and so the actions on such a target are only executed if the target's dependencies are updated, or if the target is also marked with ALWAYS. The default jam target "all" is a pseudotarget. In Jambase, NOTFILE is used to define several addition convenient pseudotargets.

NOUPDATE targets ;
Causes the timestamps on targets to be ignored. This has two effects: first, once the target has been created it will never be updated; second, manually updating target will not cause other targets to be updated. In Jambase, for example, this rule is applied to directories by the MkDir rule, because MkDir only cares that the target directory exists, not when it has last been updated.

TEMPORARY targets ;
Marks targets as temporary, allowing them to be removed after other targets that depend upon them have been updated. If a TEMPORARY target is missing, jam uses the timestamp of the target's parent. Jambase uses TEMPORARY to mark object files that are archived in a library after they are built, so that they can be deleted after they are archived.

Utility Rules
The remaining rules are utility rules.

ECHO args ;
Echo args ;
echo args ;
Blurts out the message args to stdout.

EXIT args ;
Exit args ;
exit args ;
Blurts out the message args to stdout and then exits with a failure status.

GLOB directories : patterns ;
Scans directories for files matching patterns, returning the list of matching files (with directory prepended). patterns uses the same syntax as in the switch statement. Only useful within the [ ] construct, to change the result into a list.

MATCH regexps : list ;
Matches the egrep(1) style regular expressions regexps against the strings in list. The result is the concatenation of matching () subexpressions for each string in list, and for each regular expression in regexps. Only useful within the [ ] construct, to change the result into a list.

Built-in Variables

This section discusses variables that have special meaning to jam.

SEARCH and LOCATE Variables

These two variables control the binding of file target names to locations in the file system. Generally, $(SEARCH) is used to find existing sources while $(LOCATE) is used to fix the location for built targets.

Rooted (absolute path) file targets are bound as is. Unrooted file target names are also normally bound as is, and thus relative to the current directory, but the settings of $(LOCATE) and $(SEARCH) alter this:

  • If $(LOCATE) is set then the target is bound relative to the first directory in $(LOCATE). Only the first element is used for binding.
  • If $(SEARCH) is set then the target is bound to the first directory in $(SEARCH) where the target file already exists.
  • If the $(SEARCH) search fails, the target is bound relative to the current directory anyhow.

Both $(SEARCH) and $(LOCATE) should be set target-specific and not globally. If they were set globally, jam would use the same paths for all file binding, which is not likely to produce sane results. When writing your own rules, especially ones not built upon those in Jambase, you may need to set $(SEARCH) or $(LOCATE) directly. Almost all of the rules defined in Jambase set $(SEARCH) and $(LOCATE) to sensible values for sources they are looking for and targets they create, respectively.

HDRSCAN and HDRRULE Variables

These two variable control header file scanning. $(HDRSCAN) is an egrep(1) pattern, with ()'s surrounding the file name, used to find file inclusion statements in source files. Jambase uses $(HDRPATTERN) as the pattern for $(HDRSCAN). $(HDRRULE) is the name of a rule to invoke with the results of the scan: the scanned file is the target, the found files are the sources. $(HDRRULE) is run under the influence of the scanned file's target-specific variables.

Both $(HDRSCAN) and $(HDRRULE) must be set for header file scanning to take place, and they should be set target-specific and not globally. If they were set globally, all files, including executables and libraries, would be scanned for header file include statements.

The scanning for header file inclusions is not exact, but it is at least dynamic, so there is no need to run something like makedepend(GNU) to create a static dependency file. The scanning mechanism errs on the side of inclusion (i.e., it is more likely to return filenames that are not actually used by the compiler than to miss include files) because it can't tell if #include lines are inside #ifdefs or other conditional logic. In Jambase, HdrRule applies the NOCARE rule to each header file found during scanning so that if the file isn't present yet doesn't cause the compilation to fail, jam won't care.

Also, scanning for regular expressions only works where the included file name is literally in the source file. It can't handle languages that allow including files using variable names (as the Jam language itself does).

Platform Identifier Variables

A number of Jam built-in variables can be used to identify runtime platform:

OSOS identifier string
OSPLATUnderlying architecture, when applicable
MACtrue on MAC platform
NTtrue on NT platform
OS2true on OS2 platform
UNIXtrue on Unix platforms
VMStrue on VMS platform

Jam Version Variables

JAMDATETime and date at jam start-up.
JAMUNAMEOuput of uname(1) command (Unix only)
JAMVERSIONjam version, as reported by jam -v.

JAMSHELL Variable

When jam executes a rule's action block, it forks and execs a shell, passing the action block as an argument to the shell. The invocation of the shell can be controlled by $(JAMSHELL). The default on Unix is, for example:

JAMSHELL = /bin/sh -c % ;

The % is replaced with the text of the action block.

Jam does not directly support building in parallel across multiple hosts, since that is heavily dependent on the local environment. To build in parallel across multiple hosts, you need to write your own shell that provides access to the multiple hosts. You then reset $(JAMSHELL) to reference it.

Just as jam expands a % to be the text of the rule's action block, it expands a ! to be the multi-process slot number. The slot number varies between 1 and the number of concurrent jobs permitted by the -j flag given on the command line. Armed with this, it is possible to write a multiple host shell. For example:


#!/bin/sh

# This sample JAMSHELL uses the SunOS on(1) command to execute a
# command string with an identical environment on another host.

# Set JAMSHELL = jamshell ! %
#
# where jamshell is the name of this shell file.
#
# This version handles up to -j6; after that they get executed
# locally.

case $1 in
1|4) on winken sh -c "$2";;
2|5) on blinken sh -c "$2";;
3|6) on nod sh -c "$2";;
*) eval "$2";;
esac

DIAGNOSTICS

In addition to generic error messages, jam may emit one of the following:

warning: unknown rule X
A rule was invoked that has not been defined with an "actions" or "rule" statement.

using N temp target(s)
Targets marked as being temporary (but nonetheless present) have been found.

updating N target(s)
Targets are out-of-date and will be updated.

can't find N target(s)
Source files can't be found and there are no actions to create them.

can't make N target(s)
Due to sources not being found, other targets cannot be made.

warning: X depends on itself
A target depends on itself either directly or through its sources.

don't know how to make X
A target is not present and no actions have been defined to create it.

X skipped for lack of Y
A source failed to build, and thus a target cannot be built.

warning: using independent target X
A target that is not a dependency of any other target is being referenced with $(<) or $(>).

X removed
Jam removed a partially built target after being interrupted.

BUGS, LIMITATIONS

The -j flag can cause jam to get confused when single actions update more than one target at a time. jam may proceed as if the targets were built even though they are still under construction.

For parallel building to be successful, the dependencies among files must be properly spelled out, as targets tend to get built in a quickest-first ordering. Also, beware of un-parallelizable commands that drop fixed-named files into the current directory, like yacc(1) does.

With the -j flag, errors from failed commands can get staggeringly mixed up.

A poorly set $(JAMSHELL) is likely to result in silent failure.

SEE ALSO

Jam documentation and source are available from the Perforce Public Depot.

AUTHOR

Jam's author is Christopher Seiwald (seiwald@perforce.com). Documentation is provided by Perforce Software, Inc.


Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
Comments to info@perforce.com
Last updated: May, 2002
$Id: //public/jam/src/Jam.html#19 $ ftjam-2.5.2/scan.h0000744000424500003730000000267110441006330013506 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * scan.h - the jam yacc scanner * * External functions: * * yyerror( char *s ) - print a parsing error message * yyfparse( char *s ) - scan include file s * yylex() - parse the next token, returning its type * yymode() - adjust lexicon of scanner * yyparse() - declaration for yacc parser * yyanyerrors() - indicate if any parsing errors occured * * The yymode() function is for the parser to adjust the lexicon of the * scanner. Aside from normal keyword scanning, there is a mode to * handle action strings (look only for the closing }) and a mode to * ignore most keywords when looking for a punctuation keyword. This * allows non-punctuation keywords to be used in lists without quoting. * * 11/04/02 (seiwald) - const-ing for string literals */ /* * YYSTYPE - value of a lexical token */ # define YYSTYPE YYSYMBOL typedef struct _YYSTYPE { int type; const char *string; PARSE *parse; LIST *list; int number; } YYSTYPE; extern YYSTYPE yylval; void yymode( int n ); void yyerror( const char *s ); int yyanyerrors(); void yyfparse( const char *s ); int yyline(); int yylex(); int yyparse(); # define SCAN_NORMAL 0 /* normal parsing */ # define SCAN_STRING 1 /* look only for matching } */ # define SCAN_PUNCT 2 /* only punctuation keywords */ ftjam-2.5.2/regexp.c0000744000424500003730000010134710441006331014050 0ustar dturnermhpsys/* * regcomp and regexec -- regsub and regerror are elsewhere * * Copyright (c) 1986 by University of Toronto. * Written by Henry Spencer. Not derived from licensed software. * * Permission is granted to anyone to use this software for any * purpose on any computer system, and to redistribute it freely, * subject to the following restrictions: * * 1. The author is not responsible for the consequences of use of * this software, no matter how awful, even if they arise * from defects in it. * * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to | *** to assist in implementing egrep. *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching *** as in BSD grep and ex. *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \. *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods, *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy. *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald *** seiwald@vix.com, on 28 August 1993, for use in jam. Regmagic.h *** was moved into regexp.h, and the include of regexp.h now uses "'s *** to avoid conflicting with the system regexp.h. Const, bless its *** soul, was removed so it can compile everywhere. The declaration *** of strchr() was in conflict on AIX, so it was removed (as it is *** happily defined in string.h). *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald *** seiwald@perforce.com, on 20 January 2000, to use function prototypes. *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald *** seiwald@perforce.com, on 05 November 2002, to const string literals. * * Beware that some of this code is subtly aware of the way operator * precedence is structured in regular expressions. Serious changes in * regular-expression syntax might require a total rethink. */ #include "regexp.h" #include #include #ifndef ultrix #include #endif #include /* * The "internal use only" fields in regexp.h are present to pass info from * compile to execute that permits the execute phase to run lots faster on * simple cases. They are: * * regstart char that must begin a match; '\0' if none obvious * reganch is the match anchored (at beginning-of-line only)? * regmust string (pointer into program) that match must include, or NULL * regmlen length of regmust string * * Regstart and reganch permit very fast decisions on suitable starting points * for a match, cutting down the work a lot. Regmust permits fast rejection * of lines that cannot possibly match. The regmust tests are costly enough * that regcomp() supplies a regmust only if the r.e. contains something * potentially expensive (at present, the only such thing detected is * or + * at the start of the r.e., which can involve a lot of backup). Regmlen is * supplied because the test in regexec() needs it and regcomp() is computing * it anyway. */ /* * Structure for regexp "program". This is essentially a linear encoding * of a nondeterministic finite-state machine (aka syntax charts or * "railroad normal form" in parsing technology). Each node is an opcode * plus a "next" pointer, possibly plus an operand. "Next" pointers of * all nodes except BRANCH implement concatenation; a "next" pointer with * a BRANCH on both ends of it is connecting two alternatives. (Here we * have one of the subtle syntax dependencies: an individual BRANCH (as * opposed to a collection of them) is never concatenated with anything * because of operator precedence.) The operand of some types of node is * a literal string; for others, it is a node leading into a sub-FSM. In * particular, the operand of a BRANCH node is the first node of the branch. * (NB this is *not* a tree structure: the tail of the branch connects * to the thing following the set of BRANCHes.) The opcodes are: */ /* definition number opnd? meaning */ #define END 0 /* no End of program. */ #define BOL 1 /* no Match "" at beginning of line. */ #define EOL 2 /* no Match "" at end of line. */ #define ANY 3 /* no Match any one character. */ #define ANYOF 4 /* str Match any character in this string. */ #define ANYBUT 5 /* str Match any character not in this string. */ #define BRANCH 6 /* node Match this alternative, or the next... */ #define BACK 7 /* no Match "", "next" ptr points backward. */ #define EXACTLY 8 /* str Match this string. */ #define NOTHING 9 /* no Match empty string. */ #define STAR 10 /* node Match this (simple) thing 0 or more times. */ #define PLUS 11 /* node Match this (simple) thing 1 or more times. */ #define WORDA 12 /* no Match "" at wordchar, where prev is nonword */ #define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */ #define OPEN 20 /* no Mark this point in input as start of #n. */ /* OPEN+1 is number 1, etc. */ #define CLOSE 30 /* no Analogous to OPEN. */ /* * Opcode notes: * * BRANCH The set of branches constituting a single choice are hooked * together with their "next" pointers, since precedence prevents * anything being concatenated to any individual branch. The * "next" pointer of the last BRANCH in a choice points to the * thing following the whole choice. This is also where the * final "next" pointer of each individual branch points; each * branch starts with the operand node of a BRANCH node. * * BACK Normal "next" pointers all implicitly point forward; BACK * exists to make loop structures possible. * * STAR,PLUS '?', and complex '*' and '+', are implemented as circular * BRANCH structures using BACK. Simple cases (one character * per match) are implemented with STAR and PLUS for speed * and to minimize recursive plunges. * * OPEN,CLOSE ...are numbered at compile time. */ /* * A node is one char of opcode followed by two chars of "next" pointer. * "Next" pointers are stored as two 8-bit pieces, high order first. The * value is a positive offset from the opcode of the node containing it. * An operand, if any, simply follows the node. (Note that much of the * code generation knows about this implicit relationship.) * * Using two bytes for the "next" pointer is vast overkill for most things, * but allows patterns to get big without disasters. */ #define OP(p) (*(p)) #define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) #define OPERAND(p) ((p) + 3) /* * See regmagic.h for one further detail of program structure. */ /* * Utility definitions. */ #ifndef CHARBITS #define UCHARAT(p) ((int)*(unsigned char *)(p)) #else #define UCHARAT(p) ((int)*(p)&CHARBITS) #endif #define FAIL(m) { regerror(m); return(NULL); } #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') /* * Flags to be passed up and down. */ #define HASWIDTH 01 /* Known never to match null string. */ #define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ #define SPSTART 04 /* Starts with * or +. */ #define WORST 0 /* Worst case. */ /* * Global work variables for regcomp(). */ static char *regparse; /* Input-scan pointer. */ static int regnpar; /* () count. */ static char regdummy; static char *regcode; /* Code-emit pointer; ®dummy = don't. */ static long regsize; /* Code size. */ /* * Forward declarations for regcomp()'s friends. */ #ifndef STATIC #define STATIC static #endif STATIC char *reg( int paren, int *flagp ); STATIC char *regbranch( int *flagp ); STATIC char *regpiece( int *flagp ); STATIC char *regatom( int *flagp ); STATIC char *regnode( int op ); STATIC char *regnext( register char *p ); STATIC void regc( int b ); STATIC void reginsert( char op, char *opnd ); STATIC void regtail( char *p, char *val ); STATIC void regoptail( char *p, char *val ); #ifdef STRCSPN STATIC int strcspn(); #endif /* - regcomp - compile a regular expression into internal code * * We can't allocate space until we know how big the compiled form will be, * but we can't compile it (and thus know how big it is) until we've got a * place to put the code. So we cheat: we compile it twice, once with code * generation turned off and size counting turned on, and once "for real". * This also means that we don't allocate space until we are sure that the * thing really will compile successfully, and we never have to move the * code and thus invalidate pointers into it. (Note that it has to be in * one piece because free() must be able to free it all.) * * Beware that the optimization-preparation code in here knows about some * of the structure of the compiled regexp. */ regexp * regcomp( const char *exp ) { register regexp *r; register char *scan; register char *longest; register unsigned len; int flags; if (exp == NULL) FAIL("NULL argument"); /* First pass: determine size, legality. */ #ifdef notdef if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */ #endif regparse = (char *)exp; regnpar = 1; regsize = 0L; regcode = ®dummy; regc(MAGIC); if (reg(0, &flags) == NULL) return(NULL); /* Small enough for pointer-storage convention? */ if (regsize >= 32767L) /* Probably could be 65535L. */ FAIL("regexp too big"); /* Allocate space. */ r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); if (r == NULL) FAIL("out of space"); /* Second pass: emit code. */ regparse = (char *)exp; regnpar = 1; regcode = r->program; regc(MAGIC); if (reg(0, &flags) == NULL) return(NULL); /* Dig out information for optimizations. */ r->regstart = '\0'; /* Worst-case defaults. */ r->reganch = 0; r->regmust = NULL; r->regmlen = 0; scan = r->program+1; /* First BRANCH. */ if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ scan = OPERAND(scan); /* Starting-point info. */ if (OP(scan) == EXACTLY) r->regstart = *OPERAND(scan); else if (OP(scan) == BOL) r->reganch++; /* * If there's something expensive in the r.e., find the * longest literal string that must appear and make it the * regmust. Resolve ties in favor of later strings, since * the regstart check works with the beginning of the r.e. * and avoiding duplication strengthens checking. Not a * strong reason, but sufficient in the absence of others. */ if (flags&SPSTART) { longest = NULL; len = 0; for (; scan != NULL; scan = regnext(scan)) if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { longest = OPERAND(scan); len = strlen(OPERAND(scan)); } r->regmust = longest; r->regmlen = len; } } return(r); } /* - reg - regular expression, i.e. main body or parenthesized thing * * Caller must absorb opening parenthesis. * * Combining parenthesis handling with the base level of regular expression * is a trifle forced, but the need to tie the tails of the branches to what * follows makes it hard to avoid. */ static char * reg( int paren, /* Parenthesized? */ int *flagp ) { register char *ret; register char *br; register char *ender; register int parno; int flags; *flagp = HASWIDTH; /* Tentatively. */ /* Make an OPEN node, if parenthesized. */ if (paren) { if (regnpar >= NSUBEXP) FAIL("too many ()"); parno = regnpar; regnpar++; ret = regnode(OPEN+parno); } else ret = NULL; /* Pick up the branches, linking them together. */ br = regbranch(&flags); if (br == NULL) return(NULL); if (ret != NULL) regtail(ret, br); /* OPEN -> first. */ else ret = br; if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; while (*regparse == '|' || *regparse == '\n') { regparse++; br = regbranch(&flags); if (br == NULL) return(NULL); regtail(ret, br); /* BRANCH -> BRANCH. */ if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; } /* Make a closing node, and hook it on the end. */ ender = regnode((paren) ? CLOSE+parno : END); regtail(ret, ender); /* Hook the tails of the branches to the closing node. */ for (br = ret; br != NULL; br = regnext(br)) regoptail(br, ender); /* Check for proper termination. */ if (paren && *regparse++ != ')') { FAIL("unmatched ()"); } else if (!paren && *regparse != '\0') { if (*regparse == ')') { FAIL("unmatched ()"); } else FAIL("junk on end"); /* "Can't happen". */ /* NOTREACHED */ } return(ret); } /* - regbranch - one alternative of an | operator * * Implements the concatenation operator. */ static char * regbranch( int *flagp ) { register char *ret; register char *chain; register char *latest; int flags; *flagp = WORST; /* Tentatively. */ ret = regnode(BRANCH); chain = NULL; while (*regparse != '\0' && *regparse != ')' && *regparse != '\n' && *regparse != '|') { latest = regpiece(&flags); if (latest == NULL) return(NULL); *flagp |= flags&HASWIDTH; if (chain == NULL) /* First piece. */ *flagp |= flags&SPSTART; else regtail(chain, latest); chain = latest; } if (chain == NULL) /* Loop ran zero times. */ (void) regnode(NOTHING); return(ret); } /* - regpiece - something followed by possible [*+?] * * Note that the branching code sequences used for ? and the general cases * of * and + are somewhat optimized: they use the same NOTHING node as * both the endmarker for their branch list and the body of the last branch. * It might seem that this node could be dispensed with entirely, but the * endmarker role is not redundant. */ static char * regpiece( int *flagp ) { register char *ret; register char op; register char *next; int flags; ret = regatom(&flags); if (ret == NULL) return(NULL); op = *regparse; if (!ISMULT(op)) { *flagp = flags; return(ret); } if (!(flags&HASWIDTH) && op != '?') FAIL("*+ operand could be empty"); *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); if (op == '*' && (flags&SIMPLE)) reginsert(STAR, ret); else if (op == '*') { /* Emit x* as (x&|), where & means "self". */ reginsert(BRANCH, ret); /* Either x */ regoptail(ret, regnode(BACK)); /* and loop */ regoptail(ret, ret); /* back */ regtail(ret, regnode(BRANCH)); /* or */ regtail(ret, regnode(NOTHING)); /* null. */ } else if (op == '+' && (flags&SIMPLE)) reginsert(PLUS, ret); else if (op == '+') { /* Emit x+ as x(&|), where & means "self". */ next = regnode(BRANCH); /* Either */ regtail(ret, next); regtail(regnode(BACK), ret); /* loop back */ regtail(next, regnode(BRANCH)); /* or */ regtail(ret, regnode(NOTHING)); /* null. */ } else if (op == '?') { /* Emit x? as (x|) */ reginsert(BRANCH, ret); /* Either x */ regtail(ret, regnode(BRANCH)); /* or */ next = regnode(NOTHING); /* null. */ regtail(ret, next); regoptail(ret, next); } regparse++; if (ISMULT(*regparse)) FAIL("nested *?+"); return(ret); } /* - regatom - the lowest level * * Optimization: gobbles an entire sequence of ordinary characters so that * it can turn them into a single node, which is smaller to store and * faster to run. Backslashed characters are exceptions, each becoming a * separate node; the code is simpler that way and it's not worth fixing. */ static char * regatom( int *flagp ) { register char *ret; int flags; *flagp = WORST; /* Tentatively. */ switch (*regparse++) { /* FIXME: these chars only have meaning at beg/end of pat? */ case '^': ret = regnode(BOL); break; case '$': ret = regnode(EOL); break; case '.': ret = regnode(ANY); *flagp |= HASWIDTH|SIMPLE; break; case '[': { register int classr; register int classend; if (*regparse == '^') { /* Complement of range. */ ret = regnode(ANYBUT); regparse++; } else ret = regnode(ANYOF); if (*regparse == ']' || *regparse == '-') regc(*regparse++); while (*regparse != '\0' && *regparse != ']') { if (*regparse == '-') { regparse++; if (*regparse == ']' || *regparse == '\0') regc('-'); else { classr = UCHARAT(regparse-2)+1; classend = UCHARAT(regparse); if (classr > classend+1) FAIL("invalid [] range"); for (; classr <= classend; classr++) regc(classr); regparse++; } } else regc(*regparse++); } regc('\0'); if (*regparse != ']') FAIL("unmatched []"); regparse++; *flagp |= HASWIDTH|SIMPLE; } break; case '(': ret = reg(1, &flags); if (ret == NULL) return(NULL); *flagp |= flags&(HASWIDTH|SPSTART); break; case '\0': case '|': case '\n': case ')': FAIL("internal urp"); /* Supposed to be caught earlier. */ break; case '?': case '+': case '*': FAIL("?+* follows nothing"); break; case '\\': switch (*regparse++) { case '\0': FAIL("trailing \\"); break; case '<': ret = regnode(WORDA); break; case '>': ret = regnode(WORDZ); break; /* FIXME: Someday handle \1, \2, ... */ default: /* Handle general quoted chars in exact-match routine */ goto de_fault; } break; de_fault: default: /* * Encode a string of characters to be matched exactly. * * This is a bit tricky due to quoted chars and due to * '*', '+', and '?' taking the SINGLE char previous * as their operand. * * On entry, the char at regparse[-1] is going to go * into the string, no matter what it is. (It could be * following a \ if we are entered from the '\' case.) * * Basic idea is to pick up a good char in ch and * examine the next char. If it's *+? then we twiddle. * If it's \ then we frozzle. If it's other magic char * we push ch and terminate the string. If none of the * above, we push ch on the string and go around again. * * regprev is used to remember where "the current char" * starts in the string, if due to a *+? we need to back * up and put the current char in a separate, 1-char, string. * When regprev is NULL, ch is the only char in the * string; this is used in *+? handling, and in setting * flags |= SIMPLE at the end. */ { char *regprev; register char ch; regparse--; /* Look at cur char */ ret = regnode(EXACTLY); for ( regprev = 0 ; ; ) { ch = *regparse++; /* Get current char */ switch (*regparse) { /* look at next one */ default: regc(ch); /* Add cur to string */ break; case '.': case '[': case '(': case ')': case '|': case '\n': case '$': case '^': case '\0': /* FIXME, $ and ^ should not always be magic */ magic: regc(ch); /* dump cur char */ goto done; /* and we are done */ case '?': case '+': case '*': if (!regprev) /* If just ch in str, */ goto magic; /* use it */ /* End mult-char string one early */ regparse = regprev; /* Back up parse */ goto done; case '\\': regc(ch); /* Cur char OK */ switch (regparse[1]){ /* Look after \ */ case '\0': case '<': case '>': /* FIXME: Someday handle \1, \2, ... */ goto done; /* Not quoted */ default: /* Backup point is \, scan * point is after it. */ regprev = regparse; regparse++; continue; /* NOT break; */ } } regprev = regparse; /* Set backup point */ } done: regc('\0'); *flagp |= HASWIDTH; if (!regprev) /* One char? */ *flagp |= SIMPLE; } break; } return(ret); } /* - regnode - emit a node */ static char * /* Location. */ regnode( int op ) { register char *ret; register char *ptr; ret = regcode; if (ret == ®dummy) { regsize += 3; return(ret); } ptr = ret; *ptr++ = op; *ptr++ = '\0'; /* Null "next" pointer. */ *ptr++ = '\0'; regcode = ptr; return(ret); } /* - regc - emit (if appropriate) a byte of code */ static void regc( int b ) { if (regcode != ®dummy) *regcode++ = b; else regsize++; } /* - reginsert - insert an operator in front of already-emitted operand * * Means relocating the operand. */ static void reginsert( char op, char *opnd ) { register char *src; register char *dst; register char *place; if (regcode == ®dummy) { regsize += 3; return; } src = regcode; regcode += 3; dst = regcode; while (src > opnd) *--dst = *--src; place = opnd; /* Op node, where operand used to be. */ *place++ = op; *place++ = '\0'; *place++ = '\0'; } /* - regtail - set the next-pointer at the end of a node chain */ static void regtail( char *p, char *val ) { register char *scan; register char *temp; register int offset; if (p == ®dummy) return; /* Find last node. */ scan = p; for (;;) { temp = regnext(scan); if (temp == NULL) break; scan = temp; } if (OP(scan) == BACK) offset = scan - val; else offset = val - scan; *(scan+1) = (offset>>8)&0377; *(scan+2) = offset&0377; } /* - regoptail - regtail on operand of first argument; nop if operandless */ static void regoptail( char *p, char *val ) { /* "Operandless" and "op != BRANCH" are synonymous in practice. */ if (p == NULL || p == ®dummy || OP(p) != BRANCH) return; regtail(OPERAND(p), val); } /* * regexec and friends */ /* * Global work variables for regexec(). */ static const char *reginput; /* String-input pointer. */ static char *regbol; /* Beginning of input, for ^ check. */ static const char **regstartp; /* Pointer to startp array. */ static const char **regendp; /* Ditto for endp. */ /* * Forwards. */ STATIC int regtry( regexp *prog, const char *string ); STATIC int regmatch( char *prog ); STATIC int regrepeat( char *p ); #ifdef DEBUG int regnarrate = 0; void regdump(); STATIC char *regprop(); #endif /* - regexec - match a regexp against a string */ int regexec( register regexp *prog, register const char *string ) { register char *s; /* Be paranoid... */ if (prog == NULL || string == NULL) { regerror("NULL parameter"); return(0); } /* Check validity of program. */ if (UCHARAT(prog->program) != MAGIC) { regerror("corrupted program"); return(0); } /* If there is a "must appear" string, look for it. */ if (prog->regmust != NULL) { s = (char *)string; while ((s = strchr(s, prog->regmust[0])) != NULL) { if (strncmp(s, prog->regmust, prog->regmlen) == 0) break; /* Found it. */ s++; } if (s == NULL) /* Not present. */ return(0); } /* Mark beginning of line for ^ . */ regbol = (char *)string; /* Simplest case: anchored match need be tried only once. */ if (prog->reganch) return(regtry(prog, string)); /* Messy cases: unanchored match. */ s = (char *)string; if (prog->regstart != '\0') /* We know what char it must start with. */ while ((s = strchr(s, prog->regstart)) != NULL) { if (regtry(prog, s)) return(1); s++; } else /* We don't -- general case. */ do { if (regtry(prog, s)) return(1); } while (*s++ != '\0'); /* Failure. */ return(0); } /* - regtry - try match at specific point */ static int /* 0 failure, 1 success */ regtry( regexp *prog, const char *string ) { register int i; register const char **sp; register const char **ep; reginput = string; regstartp = prog->startp; regendp = prog->endp; sp = prog->startp; ep = prog->endp; for (i = NSUBEXP; i > 0; i--) { *sp++ = NULL; *ep++ = NULL; } if (regmatch(prog->program + 1)) { prog->startp[0] = string; prog->endp[0] = reginput; return(1); } else return(0); } /* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static int /* 0 failure, 1 success */ regmatch( char *prog ) { register char *scan; /* Current node. */ char *next; /* Next node. */ scan = prog; #ifdef DEBUG if (scan != NULL && regnarrate) fprintf(stderr, "%s(\n", regprop(scan)); #endif while (scan != NULL) { #ifdef DEBUG if (regnarrate) fprintf(stderr, "%s...\n", regprop(scan)); #endif next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) return(0); break; case EOL: if (*reginput != '\0') return(0); break; case WORDA: /* Must be looking at a letter, digit, or _ */ if ((!isalnum(*reginput)) && *reginput != '_') return(0); /* Prev must be BOL or nonword */ if (reginput > regbol && (isalnum(reginput[-1]) || reginput[-1] == '_')) return(0); break; case WORDZ: /* Must be looking at non letter, digit, or _ */ if (isalnum(*reginput) || *reginput == '_') return(0); /* We don't care what the previous char was */ break; case ANY: if (*reginput == '\0') return(0); reginput++; break; case EXACTLY: { register int len; register char *opnd; opnd = OPERAND(scan); /* Inline the first character, for speed. */ if (*opnd != *reginput) return(0); len = strlen(opnd); if (len > 1 && strncmp(opnd, reginput, len) != 0) return(0); reginput += len; } break; case ANYOF: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) return(0); reginput++; break; case ANYBUT: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) return(0); reginput++; break; case NOTHING: break; case BACK: break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: { register int no; register const char *save; no = OP(scan) - OPEN; save = reginput; if (regmatch(next)) { /* * Don't set startp if some later * invocation of the same parentheses * already has. */ if (regstartp[no] == NULL) regstartp[no] = save; return(1); } else return(0); } break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: { register int no; register const char *save; no = OP(scan) - CLOSE; save = reginput; if (regmatch(next)) { /* * Don't set endp if some later * invocation of the same parentheses * already has. */ if (regendp[no] == NULL) regendp[no] = save; return(1); } else return(0); } break; case BRANCH: { register const char *save; if (OP(next) != BRANCH) /* No choice. */ next = OPERAND(scan); /* Avoid recursion. */ else { do { save = reginput; if (regmatch(OPERAND(scan))) return(1); reginput = save; scan = regnext(scan); } while (scan != NULL && OP(scan) == BRANCH); return(0); /* NOTREACHED */ } } break; case STAR: case PLUS: { register char nextch; register int no; register const char *save; register int min; /* * Lookahead to avoid useless match attempts * when we know what character comes next. */ nextch = '\0'; if (OP(next) == EXACTLY) nextch = *OPERAND(next); min = (OP(scan) == STAR) ? 0 : 1; save = reginput; no = regrepeat(OPERAND(scan)); while (no >= min) { /* If it could work, try it. */ if (nextch == '\0' || *reginput == nextch) if (regmatch(next)) return(1); /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return(0); } break; case END: return(1); /* Success! */ break; default: regerror("memory corruption"); return(0); break; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ regerror("corrupted pointers"); return(0); } /* - regrepeat - repeatedly match something simple, report how many */ static int regrepeat( char *p ) { register int count = 0; register const char *scan; register char *opnd; scan = reginput; opnd = OPERAND(p); switch (OP(p)) { case ANY: count = strlen(scan); scan += count; break; case EXACTLY: while (*opnd == *scan) { count++; scan++; } break; case ANYOF: while (*scan != '\0' && strchr(opnd, *scan) != NULL) { count++; scan++; } break; case ANYBUT: while (*scan != '\0' && strchr(opnd, *scan) == NULL) { count++; scan++; } break; default: /* Oh dear. Called inappropriately. */ regerror("internal foulup"); count = 0; /* Best compromise. */ break; } reginput = scan; return(count); } /* - regnext - dig the "next" pointer out of a node */ static char * regnext( register char *p ) { register int offset; if (p == ®dummy) return(NULL); offset = NEXT(p); if (offset == 0) return(NULL); if (OP(p) == BACK) return(p-offset); else return(p+offset); } #ifdef DEBUG STATIC char *regprop(); /* - regdump - dump a regexp onto stdout in vaguely comprehensible form */ void regdump( regexp *r ) { register char *s; register char op = EXACTLY; /* Arbitrary non-END op. */ register char *next; s = r->program + 1; while (op != END) { /* While that wasn't END last time... */ op = OP(s); printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ next = regnext(s); if (next == NULL) /* Next ptr. */ printf("(0)"); else printf("(%d)", (s-r->program)+(next-s)); s += 3; if (op == ANYOF || op == ANYBUT || op == EXACTLY) { /* Literal string, where present. */ while (*s != '\0') { putchar(*s); s++; } s++; } putchar('\n'); } /* Header fields of interest. */ if (r->regstart != '\0') printf("start `%c' ", r->regstart); if (r->reganch) printf("anchored "); if (r->regmust != NULL) printf("must have \"%s\"", r->regmust); printf("\n"); } /* - regprop - printable representation of opcode */ static char * regprop( char *op ) { register char *p; static char buf[50]; (void) strcpy(buf, ":"); switch (OP(op)) { case BOL: p = "BOL"; break; case EOL: p = "EOL"; break; case ANY: p = "ANY"; break; case ANYOF: p = "ANYOF"; break; case ANYBUT: p = "ANYBUT"; break; case BRANCH: p = "BRANCH"; break; case EXACTLY: p = "EXACTLY"; break; case NOTHING: p = "NOTHING"; break; case BACK: p = "BACK"; break; case END: p = "END"; break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); p = NULL; break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); p = NULL; break; case STAR: p = "STAR"; break; case PLUS: p = "PLUS"; break; case WORDA: p = "WORDA"; break; case WORDZ: p = "WORDZ"; break; default: regerror("corrupted opcode"); break; } if (p != NULL) (void) strcat(buf, p); return(buf); } #endif /* * The following is provided for those people who do not have strcspn() in * their C libraries. They should get off their butts and do something * about it; at least one public-domain implementation of those (highly * useful) string routines has been published on Usenet. */ #ifdef STRCSPN /* * strcspn - find length of initial segment of s1 consisting entirely * of characters not from s2 */ static int strcspn( char *s1, char *s2 ) { register char *scan1; register char *scan2; register int count; count = 0; for (scan1 = s1; *scan1 != '\0'; scan1++) { for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ if (*scan1 == *scan2++) return(count); count++; } return(count); } #endif void regerror( const char *s ) { printf( "re error %s\n", s ); } ftjam-2.5.2/rules.c0000744000424500003730000001726710441006331013717 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * rules.c - access to RULEs, TARGETs, and ACTIONs * * External routines: * * bindrule() - return pointer to RULE, creating it if necessary * bindtarget() - return pointer to TARGET, creating it if necessary * copytarget() - make a new target with the old target's name * touchtarget() - mark a target to simulate being new * targetlist() - turn list of target names into a TARGET chain * targetentry() - add a TARGET to a chain of TARGETS * targetchain() - append two TARGET chains * actionlist() - append to an ACTION chain * addsettings() - add a deferred "set" command to a target * copysettings() - copy a settings list for temp use * pushsettings() - set all target specific variables * popsettings() - reset target specific variables to their pre-push values * freesettings() - delete a settings list * donerules() - free RULE and TARGET tables * * 04/12/94 (seiwald) - actionlist() now just appends a single action. * 08/23/94 (seiwald) - Support for '+=' (append to variable) * 06/21/02 (seiwald) - support for named parameters * 11/04/02 (seiwald) - const-ing for string literals * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET */ # include "jam.h" # include "lists.h" # include "parse.h" # include "variable.h" # include "rules.h" # include "newstr.h" # include "hash.h" static struct hash *rulehash = 0; static struct hash *targethash = 0; /* * bindrule() - return pointer to RULE, creating it if necessary */ RULE * bindrule( const char *rulename ) { RULE rule, *r = &rule; if( !rulehash ) rulehash = hashinit( sizeof( RULE ), "rules" ); r->name = rulename; if( hashenter( rulehash, (HASHDATA **)&r ) ) { r->name = newstr( rulename ); /* never freed */ r->procedure = (PARSE *)0; r->actions = (char *)0; r->bindlist = L0; r->params = L0; r->flags = 0; } return r; } /* * bindtarget() - return pointer to TARGET, creating it if necessary */ TARGET * bindtarget( const char *targetname ) { TARGET target, *t = ⌖ if( !targethash ) targethash = hashinit( sizeof( TARGET ), "targets" ); t->name = targetname; if( hashenter( targethash, (HASHDATA **)&t ) ) { memset( (char *)t, '\0', sizeof( *t ) ); t->name = newstr( targetname ); /* never freed */ t->boundname = t->name; /* default for T_FLAG_NOTFILE */ } return t; } /* * copytarget() - make a new target with the old target's name * * Not entered into hash table -- for internal nodes. */ TARGET * copytarget( const TARGET *ot ) { TARGET *t; t = (TARGET *)malloc( sizeof( *t ) ); memset( (char *)t, '\0', sizeof( *t ) ); t->name = copystr( ot->name ); t->boundname = t->name; t->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL; return t; } /* * touchtarget() - mark a target to simulate being new */ void touchtarget( const char *t ) { bindtarget( t )->flags |= T_FLAG_TOUCHED; } /* * targetlist() - turn list of target names into a TARGET chain * * Inputs: * chain existing TARGETS to append to * targets list of target names */ TARGETS * targetlist( TARGETS *chain, LIST *targets ) { for( ; targets; targets = list_next( targets ) ) chain = targetentry( chain, bindtarget( targets->string ) ); return chain; } /* * targetentry() - add a TARGET to a chain of TARGETS * * Inputs: * chain exisitng TARGETS to append to * target new target to append */ TARGETS * targetentry( TARGETS *chain, TARGET *target ) { TARGETS *c; c = (TARGETS *)malloc( sizeof( TARGETS ) ); c->target = target; if( !chain ) chain = c; else chain->tail->next = c; chain->tail = c; c->next = 0; return chain; } /* * targetchain() - append two TARGET chains * * Inputs: * chain exisitng TARGETS to append to * target new target to append */ TARGETS * targetchain( TARGETS *chain, TARGETS *targets ) { TARGETS *c; if( !targets ) return chain; else if( !chain ) return targets; chain->tail->next = targets; chain->tail = targets->tail; return chain; } /* * actionlist() - append to an ACTION chain */ ACTIONS * actionlist( ACTIONS *chain, ACTION *action ) { ACTIONS *actions = (ACTIONS *)malloc( sizeof( ACTIONS ) ); actions->action = action; if( !chain ) chain = actions; else chain->tail->next = actions; chain->tail = actions; actions->next = 0; return chain; } /* * addsettings() - add a deferred "set" command to a target * * Adds a variable setting (varname=list) onto a chain of settings * for a particular target. Replaces the previous previous value, * if any, unless 'append' says to append the new list onto the old. * Returns the head of the chain of settings. */ SETTINGS * addsettings( SETTINGS *head, int setflag, const char *symbol, LIST *value ) { SETTINGS *v; /* Look for previous setting */ for( v = head; v; v = v->next ) if( !strcmp( v->symbol, symbol ) ) break; /* If not previously set, alloc a new. */ /* If appending, do so. */ /* Else free old and set new. */ if( !v ) { v = (SETTINGS *)malloc( sizeof( *v ) ); v->symbol = newstr( symbol ); v->value = value; v->next = head; head = v; } else switch( setflag ) { case VAR_SET: /* Toss old, set new */ list_free( v->value ); v->value = value; break; case VAR_APPEND: /* Append new to old */ v->value = list_append( v->value, value ); break; case VAR_DEFAULT: /* Toss new, old already set */ list_free( value ); break; } /* Return (new) head of list. */ return head; } /* * copysettings() - copy a settings list for temp use * * When target-specific variables are pushed into place with pushsettings(), * any global variables with the same name are swapped onto the target's * SETTINGS chain. If that chain gets modified (by using the "on target" * syntax), popsettings() would wrongly swap those modified values back * as the new global values. * * copysettings() protects the target's SETTINGS chain by providing a * copy of the chain to pass to pushsettings() and popsettings(), so that * the target's original SETTINGS chain can be modified using the usual * "on target" syntax. */ SETTINGS * copysettings( SETTINGS *from ) { SETTINGS *head = 0, *v; for( ; from; from = from->next ) { SETTINGS *v = (SETTINGS *)malloc( sizeof( *v ) ); v->symbol = copystr( from->symbol ); v->value = list_copy( 0, from->value ); v->next = head; head = v; } return head; } /* * pushsettings() - set all target specific variables */ void pushsettings( SETTINGS *v ) { for( ; v; v = v->next ) v->value = var_swap( v->symbol, v->value ); } /* * popsettings() - reset target specific variables to their pre-push values */ void popsettings( SETTINGS *v ) { pushsettings( v ); /* just swap again */ } /* * freesettings() - delete a settings list */ void freesettings( SETTINGS *v ) { while( v ) { SETTINGS *n = v->next; freestr( v->symbol ); list_free( v->value ); free( (char *)v ); v = n; } } /* * donerules() - free RULE and TARGET tables */ void donerules() { hashdone( rulehash ); hashdone( targethash ); } ftjam-2.5.2/variable.h0000744000424500003730000000134310441006331014343 0ustar dturnermhpsys/* * Copyright 1993, 2000 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * variable.h - handle jam multi-element variables * * 11/04/02 (seiwald) - const-ing for string literals */ void var_defines( const char **e ); int var_string( const char *in, char *out, int outsize, LOL *lol ); LIST * var_get( const char *symbol ); void var_set( const char *symbol, LIST *value, int flag ); LIST * var_swap( const char *symbol, LIST *value ); void var_done(); /* * Defines for var_set(). */ # define VAR_SET 0 /* override previous value */ # define VAR_APPEND 1 /* append to previous value */ # define VAR_DEFAULT 2 /* set only if no previous value */ ftjam-2.5.2/hdrmacro.c0000744000424500003730000000752010441006332014354 0ustar dturnermhpsys/* * Copyright 1993, 2000 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ # include "jam.h" # include "lists.h" # include "parse.h" # include "compile.h" # include "rules.h" # include "variable.h" # include "regexp.h" # include "hdrmacro.h" # include "hash.h" # include "newstr.h" /* * hdrmacro.c - handle header files that define macros used in * #include statements. * * we look for lines like "#define MACRO <....>" or '#define MACRO " "' * in the target file. When found, we * * we then phony up a rule invocation like: * * $(HDRRULE) : ; * * External routines: * headers1() - scan a target for "#include MACRO" lines and try * to resolve them when needed * * Internal routines: * headers1() - using regexp, scan a file and build include LIST * * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule, * so that headers() doesn't have to mock up a parse structure * just to invoke a rule. */ static LIST *header_macros1( LIST *l, char *file, int rec, regexp *re[] ); /* this type is used to store a dictionary of file header macros */ typedef struct header_macro { const char* symbol; const char* filename; /* we could maybe use a LIST here ?? */ } HEADER_MACRO; static struct hash* header_macros_hash = 0; /* * headers() - scan a target for include files and call HDRRULE */ # define MAXINC 10 void macro_headers( TARGET *t ) { LIST *hdrrule; regexp *re; FILE *f; char buf[ 1024 ]; int i; if ( DEBUG_HEADER ) printf( "macro header scan for %s\n", t->name ); /* this regexp is used to detect lines of the form */ /* "#define MACRO <....>" or "#define MACRO "....." */ /* in the header macro files.. */ re = regcomp( "^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*" "[<\"]([^\">]*)[\">].*$" ); if( ( f = fopen( t->boundname, "r" ) ) == 0 ) return; while( fgets( buf, sizeof( buf ), f ) ) { HEADER_MACRO var, *v = &var; if ( regexec( re, buf ) && re->startp[1] ) { char buf1[ MAXSYM ], buf2[ MAXSYM ]; int l1, l2; l1 = re->endp[1] - re->startp[1]; l2 = re->endp[2] - re->startp[2]; memcpy( buf1, re->startp[1], l1 ); memcpy( buf2, re->startp[2], l2 ); buf1[l1] = '\0'; buf2[l2] = '\0'; /* we detected a line that looks like "#define MACRO filename */ if ( DEBUG_HEADER ) printf( "macro '%s' used to define filename '%s' in '%s'\n", buf1, buf2, t->boundname ); /* add macro definition to hash table */ if ( !header_macros_hash ) header_macros_hash = hashinit( sizeof( HEADER_MACRO ), "hdrmacros" ); v->symbol = (const char*)buf1; v->filename = 0; if ( hashenter( header_macros_hash, (HASHDATA **)&v ) ) { v->symbol = newstr( buf1 ); /* never freed */ v->filename = newstr( buf2 ); /* never freed */ } /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */ /* WE MIGHT AS WELL USE A LIST TO STORE THEM.. */ } } fclose( f ); free( re ); } const char* macro_header_get( const char* macro_name ) { HEADER_MACRO var, *v = &var; v->symbol = (char*)macro_name; if( header_macros_hash && hashcheck( header_macros_hash, (HASHDATA **)&v ) ) { if ( DEBUG_HEADER ) printf( "### macro '%s' evaluated to '%s'\n", macro_name, v->filename ); return (const char*) v->filename; } return 0; } ftjam-2.5.2/regexp.h0000744000424500003730000000152210441006332014050 0ustar dturnermhpsys/* * Definitions etc. for regexp(3) routines. * * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], * not the System V one. * * 11/04/02 (seiwald) - const-ing for string literals */ #define NSUBEXP 10 typedef struct regexp { const char *startp[NSUBEXP]; const char *endp[NSUBEXP]; char regstart; /* Internal use only. */ char reganch; /* Internal use only. */ char *regmust; /* Internal use only. */ int regmlen; /* Internal use only. */ char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; regexp *regcomp( const char *exp ); int regexec( regexp *prog, const char *string ); void regerror( const char *s ); /* * The first byte of the regexp internal "program" is actually this magic * number; the start node begins in the second byte. */ #define MAGIC 0234 ftjam-2.5.2/rules.h0000744000424500003730000001500410441006333013711 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * rules.h - targets, rules, and related information * * This file describes the structures holding the targets, rules, and * related information accumulated by interpreting the statements * of the jam files. * * The following are defined: * * RULE - a generic jam rule, the product of RULE and ACTIONS * ACTIONS - a chain of ACTIONs * ACTION - a RULE instance with targets and sources * SETTINGS - variables to set when executing a TARGET's ACTIONS * TARGETS - a chain of TARGETs * TARGET - a file or "thing" that can be built * * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET. * 04/12/94 (seiwald) - actionlist() now just appends a single action. * 06/01/94 (seiwald) - new 'actions existing' does existing sources * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. * 01/19/95 (seiwald) - split DONTKNOW into CANTFIND/CANTMAKE. * 02/02/95 (seiwald) - new LEAVES modifier on targets. * 02/14/95 (seiwald) - new NOUPDATE modifier on targets. * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx * 06/21/02 (seiwald) - support for named parameters * 07/17/02 (seiwald) - TEMPORARY sources for headers now get built * 11/04/02 (seiwald) - const-ing for string literals * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET */ typedef struct _rule RULE; typedef struct _target TARGET; typedef struct _targets TARGETS; typedef struct _action ACTION; typedef struct _actions ACTIONS; typedef struct _settings SETTINGS ; /* RULE - a generic jam rule, the product of RULE and ACTIONS */ struct _rule { const char *name; PARSE *procedure; /* parse tree from RULE */ const char *actions; /* command string from ACTIONS */ LIST *bindlist; /* variable to bind for actions */ LIST *params; /* bind args to local vars */ int flags; /* modifiers on ACTIONS */ # define RULE_UPDATED 0x01 /* $(>) is updated sources only */ # define RULE_TOGETHER 0x02 /* combine actions on single target */ # define RULE_IGNORE 0x04 /* ignore return status of executes */ # define RULE_QUIETLY 0x08 /* don't mention it unless verbose */ # define RULE_PIECEMEAL 0x10 /* split exec so each $(>) is small */ # define RULE_EXISTING 0x20 /* $(>) is pre-exisitng sources only */ # define RULE_MAXLINE 0x40 /* cmd specific maxline (last) */ } ; /* ACTIONS - a chain of ACTIONs */ struct _actions { ACTIONS *next; ACTIONS *tail; /* valid only for head */ ACTION *action; } ; /* ACTION - a RULE instance with targets and sources */ struct _action { RULE *rule; TARGETS *targets; TARGETS *sources; /* aka $(>) */ char running; /* has been started */ char status; /* see TARGET status */ } ; /* SETTINGS - variables to set when executing a TARGET's ACTIONS */ struct _settings { SETTINGS *next; const char *symbol; /* symbol name for var_set() */ LIST *value; /* symbol value for var_set() */ } ; /* TARGETS - a chain of TARGETs */ struct _targets { TARGETS *next; TARGETS *tail; /* valid only for head */ TARGET *target; } ; /* TARGET - a file or "thing" that can be built */ struct _target { const char *name; const char *boundname; /* if search() relocates target */ ACTIONS *actions; /* rules to execute, if any */ SETTINGS *settings; /* variables to define */ char flags; /* status info */ # define T_FLAG_TEMP 0x01 /* TEMPORARY applied */ # define T_FLAG_NOCARE 0x02 /* NOCARE applied */ # define T_FLAG_NOTFILE 0x04 /* NOTFILE applied */ # define T_FLAG_TOUCHED 0x08 /* ALWAYS applied or -t target */ # define T_FLAG_LEAVES 0x10 /* LEAVES applied */ # define T_FLAG_NOUPDATE 0x20 /* NOUPDATE applied */ # define T_FLAG_INTERNAL 0x40 /* internal INCLUDES node */ char binding; /* how target relates to real file */ # define T_BIND_UNBOUND 0 /* a disembodied name */ # define T_BIND_MISSING 1 /* couldn't find real file */ # define T_BIND_PARENTS 2 /* using parent's timestamp */ # define T_BIND_EXISTS 3 /* real file, timestamp valid */ TARGETS *depends; /* dependencies */ TARGET *includes; /* includes */ time_t time; /* update time */ time_t leaf; /* update time of leaf sources */ char fate; /* make0()'s diagnosis */ # define T_FATE_INIT 0 /* nothing done to target */ # define T_FATE_MAKING 1 /* make0(target) on stack */ # define T_FATE_STABLE 2 /* target didn't need updating */ # define T_FATE_NEWER 3 /* target newer than parent */ # define T_FATE_SPOIL 4 /* >= SPOIL rebuilds parents */ # define T_FATE_ISTMP 4 /* unneeded temp target oddly present */ # define T_FATE_BUILD 5 /* >= BUILD rebuilds target */ # define T_FATE_TOUCHED 5 /* manually touched with -t */ # define T_FATE_MISSING 6 /* is missing, needs updating */ # define T_FATE_NEEDTMP 7 /* missing temp that must be rebuild */ # define T_FATE_OUTDATED 8 /* is out of date, needs updating */ # define T_FATE_UPDATE 9 /* deps updated, needs updating */ # define T_FATE_BROKEN 10 /* >= BROKEN ruins parents */ # define T_FATE_CANTFIND 10 /* no rules to make missing target */ # define T_FATE_CANTMAKE 11 /* can't find dependents */ char progress; /* tracks make1() progress */ # define T_MAKE_INIT 0 /* make1(target) not yet called */ # define T_MAKE_ONSTACK 1 /* make1(target) on stack */ # define T_MAKE_ACTIVE 2 /* make1(target) in make1b() */ # define T_MAKE_RUNNING 3 /* make1(target) running commands */ # define T_MAKE_DONE 4 /* make1(target) done */ char status; /* execcmd() result */ int asynccnt; /* child deps outstanding */ TARGETS *parents; /* used by make1() for completion */ char *cmds; /* type-punned command list */ } ; RULE *bindrule( const char *rulename ); TARGET *bindtarget( const char *targetname ); TARGET *copytarget( const TARGET *t ); void touchtarget( const char *t ); TARGETS *targetlist( TARGETS *chain, LIST *targets ); TARGETS *targetentry( TARGETS *chain, TARGET *target ); TARGETS *targetchain( TARGETS *chain, TARGETS *targets ); ACTIONS *actionlist( ACTIONS *chain, ACTION *action ); SETTINGS *addsettings( SETTINGS *v, int setflag, const char *sym, LIST *val ); SETTINGS *copysettings( SETTINGS *v ); void pushsettings( SETTINGS *v ); void popsettings( SETTINGS *v ); void freesettings( SETTINGS *v ); void donerules(); ftjam-2.5.2/configure0000744000424500003730000000027710441006333014320 0ustar dturnermhpsys#!/bin/sh # # Call the 'configure' script located in 'builds/unix'. # # This should re-generate the following files: # # Makefile # patchlevel.h # cd builds/unix ./configure "$@" # eof ftjam-2.5.2/filemac.c0000744000424500003730000000736610441006333014166 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * filemac.c - manipulate file names and scan directories on macintosh * * External routines: * * file_dirscan() - scan a directory for files * file_time() - get timestamp of file, if not done by file_dirscan() * file_archscan() - scan an archive for files * * File_dirscan() and file_archscan() call back a caller provided function * for each file found. A flag to this callback function lets file_dirscan() * and file_archscan() indicate that a timestamp is being provided with the * file. If file_dirscan() or file_archscan() do not provide the file's * timestamp, interested parties may later call file_time(). * * 04/08/94 (seiwald) - Coherent/386 support added. * 12/19/94 (mikem) - solaris string table insanity support * 02/14/95 (seiwald) - parse and build /xxx properly * 05/03/96 (seiwald) - split into pathunix.c * 11/21/96 (peterk) - BEOS does not have Unix-style archives * 01/21/00 (malyn) - divorced from GUSI * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "filesys.h" # include "pathsys.h" # ifdef OS_MAC #include #include # include <:sys:stat.h> void CopyC2PStr(const char * cstr, StringPtr pstr) { int len; for (len = 0; *cstr && len<255; pstr[++len] = *cstr++) ; pstr[0] = len; } /* * file_dirscan() - scan a directory for files */ void file_dirscan( const char *dir, scanback func, void *closure ) { PATHNAME f; char filename[ MAXJPATH ]; unsigned char fullPath[ 512 ]; FSSpec spec; WDPBRec vol; Str63 volName; CInfoPBRec lastInfo; int index = 1; /* First enter directory itself */ memset( (char *)&f, '\0', sizeof( f ) ); f.f_dir.ptr = dir; f.f_dir.len = strlen(dir); if( DEBUG_BINDSCAN ) printf( "scan directory %s\n", dir ); /* Special case ":" - enter it */ if( f.f_dir.len == 1 && f.f_dir.ptr[0] == ':' ) (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); /* Now enter contents of directory */ vol.ioNamePtr = volName; if( PBHGetVolSync( &vol ) ) return; CopyC2PStr( dir, fullPath ); if( FSMakeFSSpec( vol.ioWDVRefNum, vol.ioWDDirID, fullPath, &spec ) ) return; lastInfo.dirInfo.ioVRefNum = spec.vRefNum; lastInfo.dirInfo.ioDrDirID = spec.parID; lastInfo.dirInfo.ioNamePtr = spec.name; lastInfo.dirInfo.ioFDirIndex = 0; lastInfo.dirInfo.ioACUser = 0; if( PBGetCatInfoSync(&lastInfo) ) return; if (!(lastInfo.dirInfo.ioFlAttrib & 0x10)) return; // ioDrDirID must be reset each time. spec.parID = lastInfo.dirInfo.ioDrDirID; for( ;; ) { lastInfo.dirInfo.ioVRefNum = spec.vRefNum; lastInfo.dirInfo.ioDrDirID = spec.parID; lastInfo.dirInfo.ioNamePtr = fullPath; lastInfo.dirInfo.ioFDirIndex = index++; if( PBGetCatInfoSync(&lastInfo) ) return; f.f_base.ptr = (char *)fullPath + 1; f.f_base.len = *fullPath; path_build( &f, filename, 0 ); (*func)( closure, filename, 0 /* not stat()'ed */, (time_t)0 ); } } /* * file_time() - get timestamp of file, if not done by file_dirscan() */ int file_time( const char *filename, time_t *time ) { struct stat statbuf; if( stat( filename, &statbuf ) < 0 ) return -1; *time = statbuf.st_mtime; return 0; } /* * file_archscan() - scan an archive for files */ void file_archscan( const char *archive, scanback func, void *closure ) { } # endif /* macintosh */ ftjam-2.5.2/pathunix.c0000744000424500003730000001256510441006334014424 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * pathunix.c - manipulate file names on UNIX, NT, OS2, AmigaOS * * External routines: * * path_parse() - split a file name into dir/base/suffix/member * path_build() - build a filename given dir/base/suffix/member * path_parent() - make a PATHNAME point to its parent dir * * File_parse() and path_build() just manipuate a string and a structure; * they do not make system calls. * * 04/08/94 (seiwald) - Coherent/386 support added. * 12/26/93 (seiwald) - handle dir/.suffix properly in path_build() * 12/19/94 (mikem) - solaris string table insanity support * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way. * 02/14/95 (seiwald) - parse and build /xxx properly * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we * should expect hdr searches to come up with strings * like "thing/thing.h". So we need to test for "/" as * well as "\" when parsing pathnames. * 03/16/95 (seiwald) - fixed accursed typo on line 69. * 05/03/96 (seiwald) - split from filent.c, fileunix.c * 12/20/96 (seiwald) - when looking for the rightmost . in a file name, * don't include the archive member name. * 01/13/01 (seiwald) - turn off \ handling on UNIX, on by accident * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "pathsys.h" # ifdef USE_PATHUNIX /* * path_parse() - split a file name into dir/base/suffix/member */ void path_parse( const char *file, PATHNAME *f ) { const char *p, *q; const char *end; memset( (char *)f, 0, sizeof( *f ) ); /* Look for */ if( file[0] == '<' && ( p = strchr( file, '>' ) ) ) { f->f_grist.ptr = file; f->f_grist.len = p - file; file = p + 1; } /* Look for dir/ */ p = strrchr( file, '/' ); # if PATH_DELIM == '\\' /* On NT, look for dir\ as well */ { char *p1 = strrchr( file, '\\' ); p = p1 > p ? p1 : p; } # endif if( p ) { f->f_dir.ptr = file; f->f_dir.len = p - file; /* Special case for / - dirname is /, not "" */ if( !f->f_dir.len ) f->f_dir.len = 1; # if PATH_DELIM == '\\' /* Special case for D:/ - dirname is D:/, not "D:" */ if( f->f_dir.len == 2 && file[1] == ':' ) f->f_dir.len = 3; # endif file = p + 1; } end = file + strlen( file ); /* Look for (member) */ if( ( p = strchr( file, '(' ) ) && end[-1] == ')' ) { f->f_member.ptr = p + 1; f->f_member.len = end - p - 2; end = p; } /* Look for .suffix */ /* This would be memrchr() */ p = 0; q = file; while( q = (char *)memchr( q, '.', end - q ) ) p = q++; if( p ) { f->f_suffix.ptr = p; f->f_suffix.len = end - p; end = p; } /* Leaves base */ f->f_base.ptr = file; f->f_base.len = end - file; } /* * path_build() - build a filename given dir/base/suffix/member */ void path_build( PATHNAME *f, char *file, int binding ) { /* Start with the grist. If the current grist isn't */ /* surrounded by <>'s, add them. */ if( f->f_grist.len ) { if( f->f_grist.ptr[0] != '<' ) *file++ = '<'; memcpy( file, f->f_grist.ptr, f->f_grist.len ); file += f->f_grist.len; if( file[-1] != '>' ) *file++ = '>'; } /* Don't prepend root if it's . or directory is rooted */ # if PATH_DELIM == '/' if( f->f_root.len && !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' ) && !( f->f_dir.len && f->f_dir.ptr[0] == '/' ) ) # else /* unix */ if( f->f_root.len && !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' ) && !( f->f_dir.len && f->f_dir.ptr[0] == '/' ) && !( f->f_dir.len && f->f_dir.ptr[0] == '\\' ) && !( f->f_dir.len && f->f_dir.ptr[1] == ':' ) ) # endif /* unix */ { memcpy( file, f->f_root.ptr, f->f_root.len ); file += f->f_root.len; *file++ = PATH_DELIM; } if( f->f_dir.len ) { memcpy( file, f->f_dir.ptr, f->f_dir.len ); file += f->f_dir.len; } /* UNIX: Put / between dir and file */ /* NT: Put \ between dir and file */ if( f->f_dir.len && ( f->f_base.len || f->f_suffix.len ) ) { /* UNIX: Special case for dir \ : don't add another \ */ /* NT: Special case for dir / : don't add another / */ # if PATH_DELIM == '\\' if( !( f->f_dir.len == 3 && f->f_dir.ptr[1] == ':' ) ) # endif if( !( f->f_dir.len == 1 && f->f_dir.ptr[0] == PATH_DELIM ) ) *file++ = PATH_DELIM; } if( f->f_base.len ) { memcpy( file, f->f_base.ptr, f->f_base.len ); file += f->f_base.len; } if( f->f_suffix.len ) { memcpy( file, f->f_suffix.ptr, f->f_suffix.len ); file += f->f_suffix.len; } if( f->f_member.len ) { *file++ = '('; memcpy( file, f->f_member.ptr, f->f_member.len ); file += f->f_member.len; *file++ = ')'; } *file = 0; } /* * path_parent() - make a PATHNAME point to its parent dir */ void path_parent( PATHNAME *f ) { /* just set everything else to nothing */ f->f_base.ptr = f->f_suffix.ptr = f->f_member.ptr = ""; f->f_base.len = f->f_suffix.len = f->f_member.len = 0; } # endif /* unix, NT, OS/2, AmigaOS */ ftjam-2.5.2/Porting0000744000424500003730000000425210441006334013757 0ustar dturnermhpsysNotes on porting Jam - revised 12/31/2000 1) Working out system dependencies in the Jam code. Jam's OS footprint is fairly small. For OS independent work Jam liberally uses standard libc functions like stdio, malloc, and string. The OS dependent interfaces are: From filesys.h: file_parse() - split a file name into dir/base/suffix/member file_build() - build a filename given dir/base/suffix/member file_dirscan() - scan a directory for files file_archscan() - scan an archive for files file_time() - get the timestamp of a file, if not already done by file_dirscan(). From execcmd.h: execcmd() - execute a shell script execwait() - wait for any outstanding execcmd()'s. The current implementations are: filemac.c - mac MPW filent.c - NT fileos2.c - OS/2 fileunix.c - all UNIX filevms.c - VMS execmac.c - mac MPW execunix.c - UNIX, OS/2, NT execvms.c - VMS 2) Defining OSMAJOR, OSMINOR in jam.h So that the Jambase and Jamfile know their host, Jam defines $(OS) to be something useful for each platform. Make sure that there is code in jam.h to generate a useful value for $(OS), and key it off the platform specific C-preprocessor symbol. If the C-preprocessor doesn't itself defines such a symbol, add a define to the Makefile. In addition to $(OS), you can also set $(OSPLAT) if the OS runs on multiple platforms (like Linux or NT). 3) Working out system dependencies in the Jambase With the value of $(OS) available, the Jambase can be extended to support special variables or rules for new platforms. See the current support for VMS, NT, and Mac. 4) Yacc troubles The generated files jamgram.h and jamgram.c are distributed for the poor souls without yacc. 5) Known problematic systems: - Pyramid has no malloc.h, memory.h - Encore has no stdlib.h - Bull DPX has sys/file.h problems 6) Send the results back. If you do porting work, the result can be integrated into future releases if you send it back to the author's address in the README. ftjam-2.5.2/README.ORG0000744000424500003730000001040210441006334013712 0ustar dturnermhpsysbelow is the original Jam 2.5 README file: ============================================================================= Jam/MR (aka "jam - make(1) redux") /+\ +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. \+/ This is Release 2.5 of Jam, a make-like program. License is hereby granted to use this software and distribute it freely, as long as this copyright notice is retained and modifications are clearly marked. ALL WARRANTIES ARE HEREBY DISCLAIMED. FEATURES -> Jam is a make(1) replacement that makes building simple things simple and building complicated things manageable. -> Jam's language is expressive, making Jamfiles (c.f. Makefiles) compact. Here's a sample: Main smail : main.c map.c resolve.c deliver.c misc.c parser.y alias.c pw.c headers.c scanner.l getpath.c str.c ; This builds "smail" from a dozen source files. Jam handles header file dependencies automatically and on-the-fly. -> Jam is very portable: it runs on UNIX, VMS, Mac, and NT. Most Jamfiles themselves are portable, like the sample above. -> Jam is unintrusive: it is small, it has negligible CPU overhead, and it doesn't create any of its own funny files (c.f. Odin, nmake, SunOS make). -> Jam can build large projects spread across many directories in one pass, without recursing, tracking the relationships among all files. Jam can do this with multiple, concurrent processes. -> Jam isn't under the blinkin GNU copyright, so you can incorporate it into commercial products. INFORMATION GUIDE Jam.html jam and language reference. Jambase.html Reference for the Jambase boilerplate file. Jamfile.html Easy reading on creating a Jamfile and using jam. RELNOTES Release 2.3 release notes. Porting Notes on porting jam to wildcat platforms. README This file. Includes installation instructions. jam.c Contains the jam command's main() as well as an introduction to the code, for serious hackers. INSTALLING The Makefile (UNIX, NT), build.com (VMS), Build.mpw (Mac MPW) are for bootstrapping. Once jam is built, it can rebuild itself. UNIX Build jam with make(1) on: Platform $(OS) ------------------------- AIX AIX * BSD/386 1.0 BSDI COHERENT/386 COHERENT DGUX 5.4 DGUX FreeBSD FREEBSD HPUX 9.0 HPUX IRIX 5.0 IRIX Linux LINUX NEXTSTEP 3.2 NEXT OSF/1 OSF PTX V2.1.0 PTX Solaris 2 SOLARIS * SunOS4.1 SUNOS Ultrix 4.2 ULTRIX BeOS BEOS * * requires editing Makefile Windows Build jam with nmake on: Platform $(OS) ------------------------- NT NT * OS/2 OS2 * The NT MAXLINE (command line length) is still set in jam.h to 996, which was apparently the NT 3.5 limit. On 4.0, the limit is somewhere around 10K. For now, you can increase MAXLINE in jam.h so that a jam running on 4.0 will use the full command line length, but that jam.exe will fail miserably on the older OS. On NT, a variable must be set before invoking jam to tell it where the C compiler lives. The name of this variable depends on which compiler you are using: BCCROOT: The Borland C compiler MSVCDIR: The Microsoft Compiler 6.0 (for NT) MSVCNT: The Microsoft Compiler 5.0 (for NT) MSVC: The Microsoft Compiler 1.5 (for Windows) Only MSVCNT and MSVCDIR have really been tested and are known to work. Macintosh Build jam with Build.mpw on: Platform $(OS) ------------------------- Macintosh MAC You'll need to edit Build.mpw to set CW. VMS Build jam with @build.com on: Platform $(OS) ------------------------- VMS 5.4 VMS OPENVMS OPENVMS Comments to the author! November, 1993 - release 1.0 March, 1995 - release 2.0 February, 1996 - release 2.1 November, 1997 - release 2.2 December, 2000 - release 2.3 March, 2002 - release 2.4 December, 2002 - release 2.5 rc1 January, 2003 - release 2.5 rc2 April, 2003 - release 2.5 rc3 August, 2004 - release 2.5 (rc3 moniker merely dropped) Christopher Seiwald seiwald@perforce.com ftjam-2.5.2/timestamp.c0000744000424500003730000001015410441006335014560 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * timestamp.c - get the timestamp of a file or archive member * * 09/22/00 (seiwald) - downshift names on OS2, too * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "hash.h" # include "filesys.h" # include "pathsys.h" # include "timestamp.h" # include "newstr.h" /* * BINDING - all known files */ typedef struct _binding BINDING; struct _binding { const char *name; short flags; # define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */ short progress; # define BIND_INIT 0 /* never seen */ # define BIND_NOENTRY 1 /* timestamp requested but file never found */ # define BIND_SPOTTED 2 /* file found but not timed yet */ # define BIND_MISSING 3 /* file found but can't get timestamp */ # define BIND_FOUND 4 /* file found and time stamped */ time_t time; /* update time - 0 if not exist */ } ; static struct hash *bindhash = 0; static void time_enter( void *, const char *, int , time_t ); static const char *time_progress[] = { "INIT", "NOENTRY", "SPOTTED", "MISSING", "FOUND" } ; /* * timestamp() - return timestamp on a file, if present */ void timestamp( char *target, time_t *time ) { PATHNAME f1, f2; BINDING binding, *b = &binding; char buf[ MAXJPATH ]; # ifdef DOWNSHIFT_PATHS char path[ MAXJPATH ]; char *p = path; do *p++ = tolower( *target ); while( *target++ ); target = path; # endif if( !bindhash ) bindhash = hashinit( sizeof( BINDING ), "bindings" ); /* Quick path - is it there? */ b->name = target; b->time = b->flags = 0; b->progress = BIND_INIT; if( hashenter( bindhash, (HASHDATA **)&b ) ) b->name = newstr( target ); /* never freed */ if( b->progress != BIND_INIT ) goto afterscanning; b->progress = BIND_NOENTRY; /* Not found - have to scan for it */ path_parse( target, &f1 ); /* Scan directory if not already done so */ { BINDING binding, *b = &binding; f2 = f1; f2.f_grist.len = 0; path_parent( &f2 ); path_build( &f2, buf, 0 ); b->name = buf; b->time = b->flags = 0; b->progress = BIND_INIT; if( hashenter( bindhash, (HASHDATA **)&b ) ) b->name = newstr( buf ); /* never freed */ if( !( b->flags & BIND_SCANNED ) ) { file_dirscan( buf, time_enter, bindhash ); b->flags |= BIND_SCANNED; } } /* Scan archive if not already done so */ if( f1.f_member.len ) { BINDING binding, *b = &binding; f2 = f1; f2.f_grist.len = 0; f2.f_member.len = 0; path_build( &f2, buf, 0 ); b->name = buf; b->time = b->flags = 0; b->progress = BIND_INIT; if( hashenter( bindhash, (HASHDATA **)&b ) ) b->name = newstr( buf ); /* never freed */ if( !( b->flags & BIND_SCANNED ) ) { file_archscan( buf, time_enter, bindhash ); b->flags |= BIND_SCANNED; } } afterscanning: if( b->progress == BIND_SPOTTED ) { if( file_time( b->name, &b->time ) < 0 ) b->progress = BIND_MISSING; else b->progress = BIND_FOUND; } *time = b->progress == BIND_FOUND ? b->time : 0; } static void time_enter( void *closure, const char *target, int found, time_t time ) { BINDING binding, *b = &binding; struct hash *bindhash = (struct hash *)closure; # ifdef DOWNSHIFT_PATHS char path[ MAXJPATH ]; char *p = path; do *p++ = tolower( *target ); while( *target++ ); target = path; # endif b->name = target; b->flags = 0; if( hashenter( bindhash, (HASHDATA **)&b ) ) b->name = newstr( target ); /* never freed */ b->time = time; b->progress = found ? BIND_FOUND : BIND_SPOTTED; if( DEBUG_BINDSCAN ) printf( "time ( %s ) : %s\n", target, time_progress[b->progress] ); } /* * donestamps() - free timestamp tables */ void donestamps() { hashdone( bindhash ); } ftjam-2.5.2/hdrmacro.h0000744000424500003730000000055210441006335014362 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * hdrmacro.h - parses header files for #define MACRO or * #define MACRO "filename" definitions */ void macro_headers( TARGET *t ); const char* macro_header_get( const char* macro_name ); ftjam-2.5.2/timestamp.h0000744000424500003730000000041710441006335014566 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * timestamp.h - get the timestamp of a file or archive member */ void timestamp( char *target, time_t *time ); void donestamps(); ftjam-2.5.2/headers.c0000744000424500003730000000766610441006335014206 0ustar dturnermhpsys/* * Copyright 1993, 2000 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * headers.c - handle #includes in source files * * Using regular expressions provided as the variable $(HDRSCAN), * headers() searches a file for #include files and phonies up a * rule invocation: * * $(HDRRULE) : ; * * External routines: * headers() - scan a target for include files and call HDRRULE * * Internal routines: * headers1() - using regexp, scan a file and build include LIST * * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule, * so that headers() doesn't have to mock up a parse structure * just to invoke a rule. * 03/02/02 (seiwald) - rules can be invoked via variable names * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 11/04/02 (seiwald) - const-ing for string literals * 12/09/02 (seiwald) - push regexp creation down to headers1(). */ # include "jam.h" # include "lists.h" # include "parse.h" # include "compile.h" # include "rules.h" # include "variable.h" # include "regexp.h" # include "headers.h" # include "newstr.h" # include "hdrmacro.h" static LIST *headers1( const char *file, LIST *hdrscan ); /* * headers() - scan a target for include files and call HDRRULE */ # define MAXINC 10 void headers( TARGET *t ) { LIST *hdrscan; LIST *hdrrule; LIST *hdrcache; LOL lol; if( !( hdrscan = var_get( "HDRSCAN" ) ) || !( hdrrule = var_get( "HDRRULE" ) ) ) return; /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ if( DEBUG_HEADER ) printf( "header scan %s\n", t->name ); lol_init( &lol ); lol_add( &lol, list_new( L0, t->name, 1 ) ); lol_add( &lol, headers1( t->boundname, hdrscan ) ); if( lol_get( &lol, 1 ) ) list_free( evaluate_rule( hdrrule->string, &lol, L0 ) ); /* Clean up */ lol_free( &lol ); } /* * headers1() - using regexp, scan a file and build include LIST */ static LIST * headers1( const char *file, LIST *hdrscan ) { FILE *f; int i; int rec = 0; LIST *result = 0; regexp *re[ MAXINC ]; regexp *re_macros; char buf[ 1024 ]; if( !( f = fopen( file, "r" ) ) ) return result; while( rec < MAXINC && hdrscan ) { re[rec++] = regcomp( hdrscan->string ); hdrscan = list_next( hdrscan ); } /* the following regexp is used to detect cases where a */ /* file is included through a line line "#include MACRO" */ re_macros = regcomp( "^[ ]*#[ ]*include[ ]*([A-Za-z][A-Za-z0-9_]*).*$" ); while( fgets( buf, sizeof( buf ), f ) ) { for( i = 0; i < rec; i++ ) if( regexec( re[i], buf ) && re[i]->startp[1] ) { /* Copy and terminate extracted string. */ char buf2[ MAXSYM ]; int l = re[i]->endp[1] - re[i]->startp[1]; memcpy( buf2, re[i]->startp[1], l ); buf2[ l ] = 0; result = list_new( result, buf2, 0 ); if( DEBUG_HEADER ) printf( "header found: %s\n", buf2 ); } /* special treatment for #include MACRO */ if ( regexec( re_macros, buf ) && re_macros->startp[1] ) { const char* header_filename; char buf2[ MAXSYM ]; int l = re_macros->endp[1] - re_macros->startp[1]; memcpy( buf2, re_macros->startp[1], l ); buf2[ l ] = 0; if ( DEBUG_HEADER ) printf( "macro header found: %s", buf2 ); header_filename = macro_header_get( buf2 ); if (header_filename) { if ( DEBUG_HEADER ) printf( " resolved to '%s'\n", header_filename ); result = list_new( result, header_filename, 0 ); } else { if ( DEBUG_HEADER ) printf( " ignored !!\n" ); } } } free( re_macros ); while( rec ) free( (char*)re[--rec] ); fclose( f ); return result; } ftjam-2.5.2/jamgram.c0000744000424500003730000007112110441006336014175 0ustar dturnermhpsys#ifndef lint static char const yyrcsid[] = "$FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28 2000/01/17 02:04:06 bde Exp $"; #endif #include #define YYBYACC 1 #define YYMAJOR 1 #define YYMINOR 9 #define YYLEX yylex() #define YYEMPTY -1 #define yyclearin (yychar=(YYEMPTY)) #define yyerrok (yyerrflag=0) #define YYRECOVERING() (yyerrflag!=0) static int yygrowstack(); #define YYPREFIX "yy" #line 84 "jamgram.y" #include "jam.h" #include "lists.h" #include "variable.h" #include "parse.h" #include "scan.h" #include "compile.h" #include "newstr.h" #include "rules.h" # define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ # define F0 (LIST *(*)(PARSE *, LOL *, int *))0 # define P0 (PARSE *)0 # define S0 (char *)0 # define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) # define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) # define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) # define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) # define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) # define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) # define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) # define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) # define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) # define pon( l,r ) parse_make( compile_on,l,r,P0,S0,S0,0 ) # define prule( a,p ) parse_make( compile_rule,a,p,P0,S0,S0,0 ) # define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) # define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) # define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) # define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) # define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) #line 57 "y.tab.c" #define YYERRCODE 256 #define _LANGLE_t 257 #define _LANGLE_EQUALS_t 258 #define _EQUALS_t 259 #define _RANGLE_t 260 #define _RANGLE_EQUALS_t 261 #define _BAR_t 262 #define _BARBAR_t 263 #define _SEMIC_t 264 #define _COLON_t 265 #define _BANG_t 266 #define _BANG_EQUALS_t 267 #define _QUESTION_EQUALS_t 268 #define _LPAREN_t 269 #define _RPAREN_t 270 #define _LBRACKET_t 271 #define _RBRACKET_t 272 #define _LBRACE_t 273 #define _RBRACE_t 274 #define _AMPER_t 275 #define _AMPERAMPER_t 276 #define _PLUS_EQUALS_t 277 #define ACTIONS_t 278 #define BIND_t 279 #define BREAK_t 280 #define CASE_t 281 #define CONTINUE_t 282 #define DEFAULT_t 283 #define ELSE_t 284 #define EXISTING_t 285 #define FOR_t 286 #define IF_t 287 #define IGNORE_t 288 #define IN_t 289 #define INCLUDE_t 290 #define LOCAL_t 291 #define MAXLINE_t 292 #define ON_t 293 #define PIECEMEAL_t 294 #define QUIETLY_t 295 #define RETURN_t 296 #define RULE_t 297 #define SWITCH_t 298 #define TOGETHER_t 299 #define UPDATED_t 300 #define WHILE_t 301 #define ARG 302 #define STRING 303 const short yylhs[] = { -1, 0, 0, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 13, 14, 3, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 15, 10, 10, 10, 6, 6, 4, 16, 16, 5, 18, 5, 17, 17, 17, 11, 11, 19, 19, 19, 19, 19, 19, 19, 12, 12, }; const short yylen[] = { 2, 0, 1, 0, 1, 1, 2, 4, 6, 3, 3, 3, 4, 6, 3, 3, 3, 7, 5, 5, 7, 5, 6, 3, 0, 0, 9, 1, 1, 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 0, 2, 4, 0, 3, 1, 1, 3, 1, 0, 2, 1, 0, 4, 2, 4, 4, 0, 2, 1, 1, 1, 1, 1, 1, 2, 0, 2, }; const short yydefred[] = { 0, 57, 0, 62, 54, 54, 0, 0, 54, 54, 0, 54, 0, 54, 0, 56, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 27, 29, 28, 0, 54, 0, 0, 54, 0, 54, 0, 9, 69, 66, 0, 68, 67, 65, 64, 0, 63, 14, 55, 15, 54, 43, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 54, 0, 23, 16, 0, 0, 0, 0, 30, 0, 54, 11, 0, 0, 59, 58, 70, 54, 0, 0, 44, 42, 34, 35, 0, 36, 37, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 54, 52, 12, 54, 54, 72, 24, 0, 0, 0, 49, 0, 0, 18, 46, 21, 0, 61, 60, 0, 0, 0, 8, 22, 0, 13, 25, 17, 20, 47, 0, 26, }; const short yydgoto[] = { 16, 21, 22, 18, 45, 30, 46, 47, 118, 31, 85, 23, 98, 140, 151, 119, 25, 50, 20, 60, }; const short yysindex[] = { -134, 0, -134, 0, 0, 0, -294, -260, 0, 0, -253, 0, -288, 0, -260, 0, 0, 0, -134, -214, -261, 0, -240, -198, -218, -253, -206, -239, -260, -260, -228, -9, -197, -199, -102, -191, -238, -193, 47, 0, 0, 0, 0, -177, 0, -181, -179, 0, -253, 0, -183, 0, 0, 0, -209, 0, 0, 0, 0, -184, 0, 0, 0, 0, 0, 0, 67, 0, -260, -260, -260, -260, -260, -260, -260, -260, -134, -260, -260, 0, 0, -134, 0, 0, -166, -173, -178, -134, 0, -200, 0, 0, -158, -245, 0, 0, 0, 0, -164, -155, 0, 0, 0, 0, -71, 0, 0, -133, -133, -71, -167, 2, 2, -142, 0, -238, -134, -162, -151, -178, -138, 0, 0, 0, 0, 0, 0, 0, -134, -139, -134, 0, -125, -114, 0, 0, 0, -110, 0, 0, -148, -116, -102, 0, 0, -134, 0, 0, 0, 0, 0, -113, 0, }; const short yyrindex[] = { 160, 0, -109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -236, 0, 0, 0, 0, 0, -56, 0, 0, 0, 0, -29, 0, 0, 0, 0, 0, -107, 0, 0, 0, 0, 0, 0, 0, 0, -224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -109, 0, 0, 0, 0, 4, 0, 0, -101, 0, -100, -109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, -226, -132, 92, 0, 101, 110, 0, 0, -107, -109, 0, 0, -100, 0, 0, 0, 0, 0, 0, 0, 0, -109, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -250, 0, 0, 0, 0, 0, 0, 0, }; const short yygindex[] = { 0, 20, -54, -34, 8, 5, -47, 84, 56, 42, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #define YYTABLESIZE 386 const short yytable[] = { 82, 19, 94, 5, 3, 19, 28, 19, 27, 29, 1, 1, 24, 26, 36, 34, 32, 33, 1, 35, 17, 37, 110, 19, 3, 49, 1, 114, 54, 54, 62, 3, 48, 120, 51, 54, 40, 40, 39, 19, 51, 15, 15, 122, 40, 40, 61, 40, 51, 15, 64, 124, 89, 93, 41, 92, 38, 15, 63, 40, 80, 67, 132, 42, 84, 81, 54, 79, 41, 43, 65, 66, 99, 83, 141, 101, 143, 42, 139, 44, 86, 19, 88, 43, 90, 91, 19, 52, 113, 95, 53, 150, 19, 96, 54, 97, 55, 56, 125, 115, 116, 57, 58, 117, 59, 126, 123, 129, 149, 127, 102, 103, 104, 105, 106, 107, 108, 109, 128, 111, 112, 19, 130, 134, 68, 69, 70, 71, 72, 137, 41, 41, 138, 19, 75, 19, 136, 1, 41, 2, 133, 41, 77, 78, 3, 142, 4, 19, 5, 144, 19, 145, 6, 7, 146, 147, 8, 9, 148, 10, 1, 152, 11, 12, 13, 3, 48, 14, 15, 1, 71, 2, 50, 121, 45, 135, 3, 131, 4, 0, 5, 0, 0, 0, 6, 7, 68, 69, 8, 71, 72, 10, 0, 0, 11, 12, 13, 0, 0, 14, 15, 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 53, 53, 0, 53, 0, 53, 53, 0, 53, 53, 53, 0, 0, 0, 0, 0, 53, 31, 31, 31, 31, 31, 31, 31, 0, 0, 0, 31, 0, 0, 31, 0, 0, 31, 0, 31, 31, 68, 69, 70, 71, 72, 73, 74, 0, 0, 0, 75, 68, 69, 70, 71, 72, 76, 0, 77, 78, 0, 75, 0, 0, 19, 0, 19, 19, 0, 5, 3, 19, 0, 19, 19, 19, 5, 3, 0, 19, 19, 0, 0, 19, 19, 0, 19, 0, 0, 19, 19, 19, 0, 0, 19, 19, 68, 69, 70, 71, 72, 73, 74, 0, 0, 0, 75, 0, 0, 0, 0, 0, 87, 0, 77, 78, 68, 69, 70, 71, 72, 73, 74, 0, 0, 0, 75, 0, 32, 100, 0, 32, 32, 0, 77, 78, 32, 0, 0, 32, 0, 0, 32, 33, 32, 32, 33, 33, 0, 0, 0, 33, 0, 0, 33, 38, 38, 33, 0, 33, 33, 0, 0, 38, 39, 39, 38, 0, 38, 38, 0, 0, 39, 0, 0, 39, 0, 39, 39, }; const short yycheck[] = { 34, 0, 49, 0, 0, 0, 266, 2, 302, 269, 271, 271, 4, 5, 302, 10, 8, 9, 271, 11, 0, 13, 76, 18, 274, 20, 271, 81, 264, 265, 25, 281, 293, 87, 274, 271, 262, 263, 18, 34, 264, 302, 302, 90, 270, 259, 264, 273, 272, 302, 289, 296, 44, 48, 268, 47, 14, 302, 264, 259, 259, 289, 116, 277, 302, 264, 302, 264, 268, 283, 28, 29, 64, 264, 128, 67, 130, 277, 125, 293, 273, 76, 259, 283, 265, 264, 81, 285, 80, 272, 288, 145, 87, 302, 292, 279, 294, 295, 93, 265, 273, 299, 300, 281, 302, 97, 264, 274, 142, 273, 68, 69, 70, 71, 72, 73, 74, 75, 273, 77, 78, 116, 264, 274, 257, 258, 259, 260, 261, 121, 262, 263, 124, 128, 267, 130, 274, 271, 270, 273, 302, 273, 275, 276, 278, 284, 280, 142, 282, 274, 145, 265, 286, 287, 264, 303, 290, 291, 274, 293, 0, 274, 296, 297, 298, 274, 273, 301, 302, 271, 273, 273, 273, 89, 274, 119, 278, 115, 280, -1, 282, -1, -1, -1, 286, 287, 257, 258, 290, 260, 261, 293, -1, -1, 296, 297, 298, -1, -1, 301, 302, 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, -1, 272, 273, -1, 275, 276, 277, -1, -1, -1, -1, -1, 283, 257, 258, 259, 260, 261, 262, 263, -1, -1, -1, 267, -1, -1, 270, -1, -1, 273, -1, 275, 276, 257, 258, 259, 260, 261, 262, 263, -1, -1, -1, 267, 257, 258, 259, 260, 261, 273, -1, 275, 276, -1, 267, -1, -1, 271, -1, 273, 274, -1, 274, 274, 278, -1, 280, 281, 282, 281, 281, -1, 286, 287, -1, -1, 290, 291, -1, 293, -1, -1, 296, 297, 298, -1, -1, 301, 302, 257, 258, 259, 260, 261, 262, 263, -1, -1, -1, 267, -1, -1, -1, -1, -1, 273, -1, 275, 276, 257, 258, 259, 260, 261, 262, 263, -1, -1, -1, 267, -1, 259, 270, -1, 262, 263, -1, 275, 276, 267, -1, -1, 270, -1, -1, 273, 259, 275, 276, 262, 263, -1, -1, -1, 267, -1, -1, 270, 262, 263, 273, -1, 275, 276, -1, -1, 270, 262, 263, 273, -1, 275, 276, -1, -1, 270, -1, -1, 273, -1, 275, 276, }; #define YYFINAL 16 #ifndef YYDEBUG #define YYDEBUG 0 #endif #define YYMAXTOKEN 303 #if YYDEBUG const char * const yyname[] = { "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"_LANGLE_t","_LANGLE_EQUALS_t", "_EQUALS_t","_RANGLE_t","_RANGLE_EQUALS_t","_BAR_t","_BARBAR_t","_SEMIC_t", "_COLON_t","_BANG_t","_BANG_EQUALS_t","_QUESTION_EQUALS_t","_LPAREN_t", "_RPAREN_t","_LBRACKET_t","_RBRACKET_t","_LBRACE_t","_RBRACE_t","_AMPER_t", "_AMPERAMPER_t","_PLUS_EQUALS_t","ACTIONS_t","BIND_t","BREAK_t","CASE_t", "CONTINUE_t","DEFAULT_t","ELSE_t","EXISTING_t","FOR_t","IF_t","IGNORE_t","IN_t", "INCLUDE_t","LOCAL_t","MAXLINE_t","ON_t","PIECEMEAL_t","QUIETLY_t","RETURN_t", "RULE_t","SWITCH_t","TOGETHER_t","UPDATED_t","WHILE_t","ARG","STRING", }; const char * const yyrule[] = { "$accept : run", "run :", "run : rules", "block :", "block : rules", "rules : rule", "rules : rule rules", "rules : LOCAL_t list _SEMIC_t block", "rules : LOCAL_t list _EQUALS_t list _SEMIC_t block", "rule : _LBRACE_t block _RBRACE_t", "rule : INCLUDE_t list _SEMIC_t", "rule : arg lol _SEMIC_t", "rule : arg assign list _SEMIC_t", "rule : arg ON_t list assign list _SEMIC_t", "rule : BREAK_t list _SEMIC_t", "rule : CONTINUE_t list _SEMIC_t", "rule : RETURN_t list _SEMIC_t", "rule : FOR_t ARG IN_t list _LBRACE_t block _RBRACE_t", "rule : SWITCH_t list _LBRACE_t cases _RBRACE_t", "rule : IF_t expr _LBRACE_t block _RBRACE_t", "rule : IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule", "rule : WHILE_t expr _LBRACE_t block _RBRACE_t", "rule : RULE_t ARG params _LBRACE_t block _RBRACE_t", "rule : ON_t arg rule", "$$1 :", "$$2 :", "rule : ACTIONS_t eflags ARG bindlist _LBRACE_t $$1 STRING $$2 _RBRACE_t", "assign : _EQUALS_t", "assign : _PLUS_EQUALS_t", "assign : _QUESTION_EQUALS_t", "assign : DEFAULT_t _EQUALS_t", "expr : arg", "expr : expr _EQUALS_t expr", "expr : expr _BANG_EQUALS_t expr", "expr : expr _LANGLE_t expr", "expr : expr _LANGLE_EQUALS_t expr", "expr : expr _RANGLE_t expr", "expr : expr _RANGLE_EQUALS_t expr", "expr : expr _AMPER_t expr", "expr : expr _AMPERAMPER_t expr", "expr : expr _BAR_t expr", "expr : expr _BARBAR_t expr", "expr : arg IN_t list", "expr : _BANG_t expr", "expr : _LPAREN_t expr _RPAREN_t", "cases :", "cases : case cases", "case : CASE_t ARG _COLON_t block", "params :", "params : ARG _COLON_t params", "params : ARG", "lol : list", "lol : list _COLON_t lol", "list : listp", "listp :", "listp : listp arg", "arg : ARG", "$$3 :", "arg : _LBRACKET_t $$3 func _RBRACKET_t", "func : arg lol", "func : ON_t arg arg lol", "func : ON_t arg RETURN_t list", "eflags :", "eflags : eflags eflag", "eflag : UPDATED_t", "eflag : TOGETHER_t", "eflag : IGNORE_t", "eflag : QUIETLY_t", "eflag : PIECEMEAL_t", "eflag : EXISTING_t", "eflag : MAXLINE_t ARG", "bindlist :", "bindlist : BIND_t list", }; #endif #ifndef YYSTYPE typedef int YYSTYPE; #endif #if YYDEBUG #include #endif #ifdef YYSTACKSIZE #undef YYMAXDEPTH #define YYMAXDEPTH YYSTACKSIZE #else #ifdef YYMAXDEPTH #define YYSTACKSIZE YYMAXDEPTH #else #define YYSTACKSIZE 10000 #define YYMAXDEPTH 10000 #endif #endif #define YYINITSTACKSIZE 200 int yydebug; int yynerrs; int yyerrflag; int yychar; short *yyssp; YYSTYPE *yyvsp; YYSTYPE yyval; YYSTYPE yylval; short *yyss; short *yysslim; YYSTYPE *yyvs; int yystacksize; /* allocate initial stack or double stack size, up to YYMAXDEPTH */ static int yygrowstack() { int newsize, i; short *newss; YYSTYPE *newvs; if ((newsize = yystacksize) == 0) newsize = YYINITSTACKSIZE; else if (newsize >= YYMAXDEPTH) return -1; else if ((newsize *= 2) > YYMAXDEPTH) newsize = YYMAXDEPTH; i = yyssp - yyss; newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) : (short *)malloc(newsize * sizeof *newss); if (newss == NULL) return -1; yyss = newss; yyssp = newss + i; newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) : (YYSTYPE *)malloc(newsize * sizeof *newvs); if (newvs == NULL) return -1; yyvs = newvs; yyvsp = newvs + i; yystacksize = newsize; yysslim = yyss + newsize - 1; return 0; } #define YYABORT goto yyabort #define YYREJECT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab #ifndef YYPARSE_PARAM #if defined(__cplusplus) || __STDC__ #define YYPARSE_PARAM_ARG void #define YYPARSE_PARAM_DECL #else /* ! ANSI-C/C++ */ #define YYPARSE_PARAM_ARG #define YYPARSE_PARAM_DECL #endif /* ANSI-C/C++ */ #else /* YYPARSE_PARAM */ #ifndef YYPARSE_PARAM_TYPE #define YYPARSE_PARAM_TYPE void * #endif #if defined(__cplusplus) || __STDC__ #define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM #define YYPARSE_PARAM_DECL #else /* ! ANSI-C/C++ */ #define YYPARSE_PARAM_ARG YYPARSE_PARAM #define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM; #endif /* ANSI-C/C++ */ #endif /* ! YYPARSE_PARAM */ int yyparse (YYPARSE_PARAM_ARG) YYPARSE_PARAM_DECL { register int yym, yyn, yystate; #if YYDEBUG register const char *yys; if ((yys = getenv("YYDEBUG"))) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif yynerrs = 0; yyerrflag = 0; yychar = (-1); if (yyss == NULL && yygrowstack()) goto yyoverflow; yyssp = yyss; yyvsp = yyvs; *yyssp = yystate = 0; yyloop: if ((yyn = yydefred[yystate])) goto yyreduce; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif } if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, shifting to state %d\n", YYPREFIX, yystate, yytable[yyn]); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; yychar = (-1); if (yyerrflag > 0) --yyerrflag; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag) goto yyinrecovery; #if defined(lint) || defined(__GNUC__) goto yynewerror; #endif yynewerror: yyerror("syntax error"); #if defined(lint) || defined(__GNUC__) goto yyerrlab; #endif yyerrlab: ++yynerrs; yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, error recovery shifting\ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; goto yyloop; } else { #if YYDEBUG if (yydebug) printf("%sdebug: error recovery discarding state %d\n", YYPREFIX, *yyssp); #endif if (yyssp <= yyss) goto yyabort; --yyssp; --yyvsp; } } } else { if (yychar == 0) goto yyabort; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, error recovery discards token %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif yychar = (-1); goto yyloop; } yyreduce: #if YYDEBUG if (yydebug) printf("%sdebug: state %d, reducing by rule %d (%s)\n", YYPREFIX, yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; yyval = yyvsp[1-yym]; switch (yyn) { case 2: #line 130 "jamgram.y" { parse_save( yyvsp[0].parse ); } break; case 3: #line 141 "jamgram.y" { yyval.parse = pnull(); } break; case 4: #line 143 "jamgram.y" { yyval.parse = yyvsp[0].parse; } break; case 5: #line 147 "jamgram.y" { yyval.parse = yyvsp[0].parse; } break; case 6: #line 149 "jamgram.y" { yyval.parse = prules( yyvsp[-1].parse, yyvsp[0].parse ); } break; case 7: #line 151 "jamgram.y" { yyval.parse = plocal( yyvsp[-2].parse, pnull(), yyvsp[0].parse ); } break; case 8: #line 153 "jamgram.y" { yyval.parse = plocal( yyvsp[-4].parse, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 9: #line 157 "jamgram.y" { yyval.parse = yyvsp[-1].parse; } break; case 10: #line 159 "jamgram.y" { yyval.parse = pincl( yyvsp[-1].parse ); } break; case 11: #line 161 "jamgram.y" { yyval.parse = prule( yyvsp[-2].parse, yyvsp[-1].parse ); } break; case 12: #line 163 "jamgram.y" { yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); } break; case 13: #line 165 "jamgram.y" { yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); } break; case 14: #line 167 "jamgram.y" { yyval.parse = pbreak( yyvsp[-1].parse, JMP_BREAK ); } break; case 15: #line 169 "jamgram.y" { yyval.parse = pbreak( yyvsp[-1].parse, JMP_CONTINUE ); } break; case 16: #line 171 "jamgram.y" { yyval.parse = pbreak( yyvsp[-1].parse, JMP_RETURN ); } break; case 17: #line 173 "jamgram.y" { yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse ); } break; case 18: #line 175 "jamgram.y" { yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); } break; case 19: #line 177 "jamgram.y" { yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); } break; case 20: #line 179 "jamgram.y" { yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); } break; case 21: #line 181 "jamgram.y" { yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); } break; case 22: #line 183 "jamgram.y" { yyval.parse = psetc( yyvsp[-4].string, yyvsp[-3].parse, yyvsp[-1].parse ); } break; case 23: #line 185 "jamgram.y" { yyval.parse = pon( yyvsp[-1].parse, yyvsp[0].parse ); } break; case 24: #line 187 "jamgram.y" { yymode( SCAN_STRING ); } break; case 25: #line 189 "jamgram.y" { yymode( SCAN_NORMAL ); } break; case 26: #line 191 "jamgram.y" { yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); } break; case 27: #line 199 "jamgram.y" { yyval.number = VAR_SET; } break; case 28: #line 201 "jamgram.y" { yyval.number = VAR_APPEND; } break; case 29: #line 203 "jamgram.y" { yyval.number = VAR_DEFAULT; } break; case 30: #line 205 "jamgram.y" { yyval.number = VAR_DEFAULT; } break; case 31: #line 213 "jamgram.y" { yyval.parse = peval( EXPR_EXISTS, yyvsp[0].parse, pnull() ); } break; case 32: #line 215 "jamgram.y" { yyval.parse = peval( EXPR_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 33: #line 217 "jamgram.y" { yyval.parse = peval( EXPR_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 34: #line 219 "jamgram.y" { yyval.parse = peval( EXPR_LESS, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 35: #line 221 "jamgram.y" { yyval.parse = peval( EXPR_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 36: #line 223 "jamgram.y" { yyval.parse = peval( EXPR_MORE, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 37: #line 225 "jamgram.y" { yyval.parse = peval( EXPR_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 38: #line 227 "jamgram.y" { yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 39: #line 229 "jamgram.y" { yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 40: #line 231 "jamgram.y" { yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 41: #line 233 "jamgram.y" { yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 42: #line 235 "jamgram.y" { yyval.parse = peval( EXPR_IN, yyvsp[-2].parse, yyvsp[0].parse ); } break; case 43: #line 237 "jamgram.y" { yyval.parse = peval( EXPR_NOT, yyvsp[0].parse, pnull() ); } break; case 44: #line 239 "jamgram.y" { yyval.parse = yyvsp[-1].parse; } break; case 45: #line 249 "jamgram.y" { yyval.parse = P0; } break; case 46: #line 251 "jamgram.y" { yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); } break; case 47: #line 255 "jamgram.y" { yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); } break; case 48: #line 264 "jamgram.y" { yyval.parse = P0; } break; case 49: #line 266 "jamgram.y" { yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); } break; case 50: #line 268 "jamgram.y" { yyval.parse = psnode( yyvsp[0].string, P0 ); } break; case 51: #line 277 "jamgram.y" { yyval.parse = pnode( P0, yyvsp[0].parse ); } break; case 52: #line 279 "jamgram.y" { yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); } break; case 53: #line 289 "jamgram.y" { yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); } break; case 54: #line 293 "jamgram.y" { yyval.parse = pnull(); yymode( SCAN_PUNCT ); } break; case 55: #line 295 "jamgram.y" { yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); } break; case 56: #line 299 "jamgram.y" { yyval.parse = plist( yyvsp[0].string ); } break; case 57: #line 300 "jamgram.y" { yymode( SCAN_NORMAL ); } break; case 58: #line 301 "jamgram.y" { yyval.parse = yyvsp[-1].parse; } break; case 59: #line 310 "jamgram.y" { yyval.parse = prule( yyvsp[-1].parse, yyvsp[0].parse ); } break; case 60: #line 312 "jamgram.y" { yyval.parse = pon( yyvsp[-2].parse, prule( yyvsp[-1].parse, yyvsp[0].parse ) ); } break; case 61: #line 314 "jamgram.y" { yyval.parse = pon( yyvsp[-2].parse, yyvsp[0].parse ); } break; case 62: #line 323 "jamgram.y" { yyval.number = 0; } break; case 63: #line 325 "jamgram.y" { yyval.number = yyvsp[-1].number | yyvsp[0].number; } break; case 64: #line 329 "jamgram.y" { yyval.number = RULE_UPDATED; } break; case 65: #line 331 "jamgram.y" { yyval.number = RULE_TOGETHER; } break; case 66: #line 333 "jamgram.y" { yyval.number = RULE_IGNORE; } break; case 67: #line 335 "jamgram.y" { yyval.number = RULE_QUIETLY; } break; case 68: #line 337 "jamgram.y" { yyval.number = RULE_PIECEMEAL; } break; case 69: #line 339 "jamgram.y" { yyval.number = RULE_EXISTING; } break; case 70: #line 341 "jamgram.y" { yyval.number = atoi( yyvsp[0].string ) * RULE_MAXLINE; } break; case 71: #line 350 "jamgram.y" { yyval.parse = pnull(); } break; case 72: #line 352 "jamgram.y" { yyval.parse = yyvsp[0].parse; } break; #line 877 "y.tab.c" } yyssp -= yym; yystate = *yyssp; yyvsp -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state 0 to\ state %d\n", YYPREFIX, YYFINAL); #endif yystate = YYFINAL; *++yyssp = YYFINAL; *++yyvsp = yyval; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, YYFINAL, yychar, yys); } #endif } if (yychar == 0) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yystate) yystate = yytable[yyn]; else yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state %d \ to state %d\n", YYPREFIX, *yyssp, yystate); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate; *++yyvsp = yyval; goto yyloop; yyoverflow: yyerror("yacc stack overflow"); yyabort: return (1); yyaccept: return (0); } ftjam-2.5.2/headers.h0000744000424500003730000000033110441006336014172 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * headers.h - handle #includes in source files */ void headers( TARGET *t ); ftjam-2.5.2/newstr.c0000744000424500003730000000372010441006336014101 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * newstr.c - string manipulation routines * * To minimize string copying, string creation, copying, and freeing * is done through newstr. * * External functions: * * newstr() - return a malloc'ed copy of a string * copystr() - return a copy of a string previously returned by newstr() * freestr() - free a string returned by newstr() or copystr() * donestr() - free string tables * * Once a string is passed to newstr(), the returned string is readonly. * * This implementation builds a hash table of all strings, so that multiple * calls of newstr() on the same string allocate memory for the string once. * Strings are never actually freed. * * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "newstr.h" # include "hash.h" typedef const char *STRING; static struct hash *strhash = 0; static int strtotal = 0; /* * newstr() - return a malloc'ed copy of a string */ const char * newstr( const char *string ) { STRING str, *s = &str; if( !strhash ) strhash = hashinit( sizeof( STRING ), "strings" ); *s = string; if( hashenter( strhash, (HASHDATA **)&s ) ) { int l = strlen( string ); char *m = (char *)malloc( l + 1 ); if (DEBUG_MEM) printf("newstr: allocating %d bytes\n", l + 1 ); strtotal += l + 1; memcpy( m, string, l + 1 ); *s = m; } return *s; } /* * copystr() - return a copy of a string previously returned by newstr() */ const char * copystr( const char *s ) { return s; } /* * freestr() - free a string returned by newstr() or copystr() */ void freestr( const char *s ) { } /* * donestr() - free string tables */ void donestr() { hashdone( strhash ); if( DEBUG_MEM ) printf( "%dK in strings\n", strtotal / 1024 ); } ftjam-2.5.2/pathvms.c0000744000424500003730000002213510441006337014243 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * pathvms.c - manipulate file names on VMS * * External routines: * * path_parse() - split a file name into dir/base/suffix/member * path_build() - build a filename given dir/base/suffix/member * path_parent() - make a PATHNAME point to its parent dir * * File_parse() and path_build() just manipuate a string and a structure; * they do not make system calls. * * WARNING! This file contains voodoo logic, as black magic is * necessary for wrangling with VMS file name. Woe be to people * who mess with this code. * * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length! * 05/03/96 (seiwald) - split from filevms.c * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "pathsys.h" # ifdef OS_VMS # define DEBUG /* * path_parse() - split a file name into dir/base/suffix/member */ void path_parse( const char *file, PATHNAME *f ) { const char *p, *q; const char *end; memset( (char *)f, 0, sizeof( *f ) ); /* Look for */ if( file[0] == '<' && ( p = strchr( file, '>' ) ) ) { f->f_grist.ptr = file; f->f_grist.len = p - file; file = p + 1; } /* Look for dev:[dir] or dev: */ if( ( p = strchr( file, ']' ) ) || ( p = strchr( file, ':' ) ) ) { f->f_dir.ptr = file; f->f_dir.len = p + 1 - file; file = p + 1; } end = file + strlen( file ); /* Look for (member) */ if( ( p = strchr( file, '(' ) ) && end[-1] == ')' ) { f->f_member.ptr = p + 1; f->f_member.len = end - p - 2; end = p; } /* Look for .suffix */ /* This would be memrchr() */ p = 0; q = file; while( q = (char *)memchr( q, '.', end - q ) ) p = q++; if( p ) { f->f_suffix.ptr = p; f->f_suffix.len = end - p; end = p; } /* Leaves base */ f->f_base.ptr = file; f->f_base.len = end - file; /* Is this a directory without a file spec? */ f->parent = 0; } /* * dir mods result * --- --- ------ * Rerooting: * * (none) :R=dev: dev: * devd: :R=dev: devd: * devd:[dir] :R=dev: devd:[dir] * [.dir] :R=dev: dev:[dir] questionable * [dir] :R=dev: dev:[dir] * * (none) :R=[rdir] [rdir] questionable * devd: :R=[rdir] devd: * devd:[dir] :R=[rdir] devd:[dir] * [.dir] :R=[rdir] [rdir.dir] questionable * [dir] :R=[rdir] [rdir] * * (none) :R=dev:[root] dev:[root] * devd: :R=dev:[root] devd: * devd:[dir] :R=dev:[root] devd:[dir] * [.dir] :R=dev:[root] dev:[root.dir] * [dir] :R=dev:[root] [dir] * * Climbing to parent: * */ # define DIR_EMPTY 0 /* empty string */ # define DIR_DEV 1 /* dev: */ # define DIR_DEVDIR 2 /* dev:[dir] */ # define DIR_DOTDIR 3 /* [.dir] */ # define DIR_DASHDIR 4 /* [-] or [-.dir] */ # define DIR_ABSDIR 5 /* [dir] */ # define DIR_ROOT 6 /* [000000] or dev:[000000] */ # define G_DIR 0 /* take just dir */ # define G_ROOT 1 /* take just root */ # define G_VAD 2 /* root's dev: + [abs] */ # define G_DRD 3 /* root's dev:[dir] + [.rel] */ # define G_VRD 4 /* root's dev: + [.rel] made [abs] */ # define G_DDD 5 /* root's dev:[dir] + . + [dir] */ static int grid[7][7] = { /* root/dir EMPTY DEV DEVDIR DOTDIR DASH, ABSDIR ROOT */ /* EMPTY */ G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, /* DEV */ G_ROOT, G_DIR, G_DIR, G_VRD, G_VAD, G_VAD, G_VAD, /* DEVDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_VAD, G_VAD, G_VAD, /* DOTDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR, /* DASHDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DDD, G_DIR, G_DIR, /* ABSDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR, /* ROOT */ G_ROOT, G_DIR, G_DIR, G_VRD, G_DIR, G_DIR, G_DIR, } ; struct dirinf { int flags; struct { char *ptr; int len; } dev, dir; } ; static char * strnchr( char *buf, int c, int len ) { while( len-- ) if( *buf && *buf++ == c ) return buf - 1; return 0; } static void dir_flags( const char *buf, int len, struct dirinf *i ) { const char *p; if( !buf || !len ) { i->flags = DIR_EMPTY; i->dev.ptr = i->dir.ptr = 0; i->dev.len = i->dir.len = 0; } else if( p = strnchr( (char *)buf, ':', len ) ) { i->dev.ptr = (char *)buf; i->dev.len = p + 1 - buf; i->dir.ptr = (char *)buf + i->dev.len; i->dir.len = len - i->dev.len; i->flags = i->dir.len && *i->dir.ptr == '[' ? DIR_DEVDIR : DIR_DEV; } else { i->dev.ptr = (char *)buf; i->dev.len = 0; i->dir.ptr = (char *)buf; i->dir.len = len; if( *buf == '[' && buf[1] == ']' ) i->flags = DIR_EMPTY; else if( *buf == '[' && buf[1] == '.' ) i->flags = DIR_DOTDIR; else if( *buf == '[' && buf[1] == '-' ) i->flags = DIR_DASHDIR; else i->flags = DIR_ABSDIR; } /* But if its rooted in any way */ if( i->dir.len == 8 && !strncmp( i->dir.ptr, "[000000]", 8 ) ) i->flags = DIR_ROOT; } /* * path_build() - build a filename given dir/base/suffix/member */ void path_build( PATHNAME *f, char *file, int binding ) { char *ofile = file; struct dirinf root, dir; int g; /* Start with the grist. If the current grist isn't */ /* surrounded by <>'s, add them. */ if( f->f_grist.len ) { if( f->f_grist.ptr[0] != '<' ) *file++ = '<'; memcpy( file, f->f_grist.ptr, f->f_grist.len ); file += f->f_grist.len; if( file[-1] != '>' ) *file++ = '>'; } /* Get info on root and dir for combining. */ dir_flags( f->f_root.ptr, f->f_root.len, &root ); dir_flags( f->f_dir.ptr, f->f_dir.len, &dir ); /* Combine */ switch( g = grid[ root.flags ][ dir.flags ] ) { case G_DIR: /* take dir */ memcpy( file, f->f_dir.ptr, f->f_dir.len ); file += f->f_dir.len; break; case G_ROOT: /* take root */ memcpy( file, f->f_root.ptr, f->f_root.len ); file += f->f_root.len; break; case G_VAD: /* root's dev + abs directory */ memcpy( file, root.dev.ptr, root.dev.len ); file += root.dev.len; memcpy( file, dir.dir.ptr, dir.dir.len ); file += dir.dir.len; break; case G_DRD: case G_DDD: /* root's dev:[dir] + rel directory */ memcpy( file, f->f_root.ptr, f->f_root.len ); file += f->f_root.len; /* sanity checks: root ends with ] */ if( file[-1] == ']' ) --file; /* Add . if separating two -'s */ if( g == G_DDD ) *file++ = '.'; /* skip [ of dir */ memcpy( file, dir.dir.ptr + 1, dir.dir.len - 1 ); file += dir.dir.len - 1; break; case G_VRD: /* root's dev + rel directory made abs */ memcpy( file, root.dev.ptr, root.dev.len ); file += root.dev.len; *file++ = '['; /* skip [. of rel dir */ memcpy( file, dir.dir.ptr + 2, dir.dir.len - 2 ); file += dir.dir.len - 2; break; } # ifdef DEBUG if( DEBUG_SEARCH && ( root.flags || dir.flags ) ) { *file = 0; printf( "%d x %d = %d (%s)\n", root.flags, dir.flags, grid[ root.flags ][ dir.flags ], ofile ); } # endif /* * Now do the special :P modifier when no file was present. * (none) (none) * [dir1.dir2] [dir1] * [dir] [000000] * [.dir] [] * [] [] */ if( file[-1] == ']' && f->parent ) { while( file-- > ofile ) { if( *file == '.' ) { *file++ = ']'; break; } else if( *file == '-' ) { /* handle .- or - */ if( file > ofile && file[-1] == '.' ) --file; *file++ = ']'; break; } else if( *file == '[' ) { if( file[1] == ']' ) { file += 2; } else { strcpy( file, "[000000]" ); file += 8; } break; } } } /* Now copy the file pieces. */ if( f->f_base.len ) { memcpy( file, f->f_base.ptr, f->f_base.len ); file += f->f_base.len; } /* If there is no suffix, we append a "." onto all generated */ /* names. This keeps VMS from appending its own (wrong) idea */ /* of what the suffix should be. */ if( f->f_suffix.len ) { memcpy( file, f->f_suffix.ptr, f->f_suffix.len ); file += f->f_suffix.len; } else if( binding && f->f_base.len ) { *file++ = '.'; } if( f->f_member.len ) { *file++ = '('; memcpy( file, f->f_member.ptr, f->f_member.len ); file += f->f_member.len; *file++ = ')'; } *file = 0; # ifdef DEBUG if( DEBUG_SEARCH ) printf("built %.*s + %.*s / %.*s suf %.*s mem %.*s -> %s\n", f->f_root.len, f->f_root.ptr, f->f_dir.len, f->f_dir.ptr, f->f_base.len, f->f_base.ptr, f->f_suffix.len, f->f_suffix.ptr, f->f_member.len, f->f_member.ptr, ofile ); # endif } /* * path_parent() - make a PATHNAME point to its parent dir */ void path_parent( PATHNAME *f ) { if( f->f_base.len ) { f->f_base.ptr = f->f_suffix.ptr = f->f_member.ptr = ""; f->f_base.len = f->f_suffix.len = f->f_member.len = 0; } else { f->parent = 1; } } # endif /* VMS */ ftjam-2.5.2/jamgram.h0000744000424500003730000000205710441006337014205 0ustar dturnermhpsys#ifndef YYERRCODE #define YYERRCODE 256 #endif #define _LANGLE_t 257 #define _LANGLE_EQUALS_t 258 #define _EQUALS_t 259 #define _RANGLE_t 260 #define _RANGLE_EQUALS_t 261 #define _BAR_t 262 #define _BARBAR_t 263 #define _SEMIC_t 264 #define _COLON_t 265 #define _BANG_t 266 #define _BANG_EQUALS_t 267 #define _QUESTION_EQUALS_t 268 #define _LPAREN_t 269 #define _RPAREN_t 270 #define _LBRACKET_t 271 #define _RBRACKET_t 272 #define _LBRACE_t 273 #define _RBRACE_t 274 #define _AMPER_t 275 #define _AMPERAMPER_t 276 #define _PLUS_EQUALS_t 277 #define ACTIONS_t 278 #define BIND_t 279 #define BREAK_t 280 #define CASE_t 281 #define CONTINUE_t 282 #define DEFAULT_t 283 #define ELSE_t 284 #define EXISTING_t 285 #define FOR_t 286 #define IF_t 287 #define IGNORE_t 288 #define IN_t 289 #define INCLUDE_t 290 #define LOCAL_t 291 #define MAXLINE_t 292 #define ON_t 293 #define PIECEMEAL_t 294 #define QUIETLY_t 295 #define RETURN_t 296 #define RULE_t 297 #define SWITCH_t 298 #define TOGETHER_t 299 #define UPDATED_t 300 #define WHILE_t 301 #define ARG 302 #define STRING 303 ftjam-2.5.2/INSTALL0000744000424500003730000000717610441006337013456 0ustar dturnermhpsysI. Compiling FT Jam: -------------------- 1. With a previous version of Jam: ---------------------------------- The easiest way to compile Jam is to use a previous version of the program. If you already have one installed on your system, simply type "jam" in this directory. This will create a new executable named "jam" or "jam.exe", located in a new system-dependent directory, whose name can be: bin.ntx86\jam.exe bin.linux86\jam etc.. 1. On Unix and Cygwin: ---------------------- FTJam supports the traditionnal Unix build & installation sequences, you can simply type: ./configure --prefix= make make install note that only the jam executable will be installed. No documentation is provided for now... 2. With toolset-specific makefiles: ----------------------------------- You can also use one of the Makefiles located in the "builds" directory. Here's what you need to type on the command line, depending on your system and compiler: a. Windows + Visual C++: set VISUALC=/install/path/to/visual/compiler set JAM_TOOLSET=VISUALC nmake -f builds\win32-visualc.mk b. Windows + Borland C++: (be sure to use the Borland "make" tool) set BORLANDC=/install/path/to/borland/compiler set JAM_TOOLSET=BORLANDC make -fbuilds\win32-visualc.mk c. Windows + Mingw (gcc): set BORLANDC=/install/path/to/borland/compiler set JAM_TOOLSET=BORLANDC make -f builds\win32-visualc.mk WE DO NOT PROVIDE PROJECT FILES FOR ANY SPECIFIC COMPILER/TOOLSET 3. Without jam: --------------- If you don't have a jam binary installed, you can still compile the program using the following method: - copy the file "Makefile0" to "Makefile" - edit the new "Makefile" and adapt it to your OS. Simply uncomment the lines specific to your system - invoke your make tool Note that the Makefile is used to build a boot-strap version of jam, called "jam0". Once it is built, the "jam0" executable is called to re-build itself. If this second pass doesn't work, this is probably because you didn't set some environment variable that indicates which compiler to use to Jam. Read the Jam documentation for more information on this.. II. Installation: ----------------- Except for Unix, we do not provide any sophisticated installation pass. Simply copy the new jam executable to any directory in your current path.. and start using it !! III. Default files: ------------------- All default files for Jam are compiled within the executable itself. There are no special configuration directory to place global or user preferences. Until further notice, all defaults can only be changed by using command line switches and setting environment variables.. IV. Windows and OS/2 Binary packages: ------------------------------------- It's possible to create zip files of the binaries on Windows and OS/2 system by following these simple steps (you need to have the "zip" utility in your path !!): 1. build jam 2. strip the jam.exe executable in bin.ntx86 when possible 3. call "jam package" you should see a file named "ftjam-xxxxx-win32.zip" or "ftjam-xxxxx-os2.zip" in the current directory, as well as "ftjam-xxxxx.zip" (containing the sources) Good luck, - David Turner, 28 Jul 2001 ftjam-2.5.2/Jamfile0000744000424500003730000001362010441006340013700 0ustar dturnermhpsys# # Jamfile to build Jam (a make(1)-like program) # # There are no user-serviceable parts in this file. # # Put executables in platform-specific subdirectory. include Jamrules ; # note that we use the target directory 'bin.unix' to ensure that # 'make install' and 'make uninstall' work correctly # if $(VMS) { LOCATE_TARGET ?= [.binvms] ; } else if $(MAC) { LOCATE_TARGET ?= :bin.mac ; } else if $(UNIX) { LOCATE_TARGET ?= bin.unix ; } else { LOCATE_TARGET ?= bin.$(OSFULL[1]:L) ; } # Leave generated source in current directory; it would be nice to use # these lines below to build the source into the platform-specific # directory, but getting scan.c to include the right jambase.h is # hard: with ""'s, it always gets the bootstrap version; with <>'s, # it won't find the bootstrap version. # SEARCH_SOURCE ?= $(LOCATE_TARGET) $(DOT) ; # LOCATE_SOURCE ?= $(LOCATE_TARGET) ; # # We have some different files for UNIX, VMS, and NT. # # # For some really stupid reason, classic Jam doesn't define NT # when compiling with Mingw, but the variable MINGW instead.. # if ! $(NT) && $(MINGW) { NT = 1 ; JAM_TOOLSET = MINGW ; } if $(NT) { code = execunix.c filent.c pathunix.c ; } else if $(OS2) { # special case for OS/2: when compiling with GCC/EMX, we use # "fileunix.c" instead of "fileos2.c" code = execunix.c pathunix.c ; if $(JAM_TOOLSET) = EMX { CCFLAGS += -D__OS2__ ; code += fileunix.c ; } else { code += fileos2.c ; } } else if $(VMS) { code = execvms.c filevms.c pathvms.c ; } else if $(MAC) { code = execmac.c filemac.c pathmac.c ; } else { code = execunix.c fileunix.c pathunix.c ; } if $(UNIX) && $(OS) = CYGWIN { CCFLAGS += -D__cygwin__ ; } # For jam profiling/debugging. if $(PROFILE) { CCFLAGS += -pg ; LINKFLAGS += -pg ; LOCATE_TARGET = $(LOCATE_TARGET)/pg ; } if $(DEBUG) { CCFLAGS += -g ; LINKFLAGS += -g ; LOCATE_TARGET = $(LOCATE_TARGET)/g ; } # We have to signal jam.h for these if $(OS) = NT { switch $(JAM_TOOLSET) { case MINGW : CCFLAGS += -DNT ; case LCC : CCFLAGS += -DNT ; case DIGITALMARS : CCFLAGS += -DNT ; case * : CCFLAGS += /DNT ; } } # Do we know yacc? if $(YACC) { code += jamgram.y ; } else { code += jamgram.c ; } # # Build the jamgram.y from the jamgram.yy # yyacc is a slippery script that makes grammars a little # easier to read/maintain. # if $(YACC) && $(SUFEXE) = "" { GenFile jamgram.y jamgramtab.h : ./yyacc jamgram.yy ; } # # How to build the compiled in jambase. # Main mkjambase : mkjambase.c ; if $(VMS) { CC = cxx ; LINK = cxxlink ; CCFLAGS += /define=VMS ; } # # The guts of the Jamfile: how to build Jam # Main jam : jam.c jambase.c ; LinkLibraries jam : libjam.a ; GenFile jambase.c : mkjambase Jambase ; if $(UNIX) { actions Strip { strip $(1) } Strip jam ; } Library libjam.a : builtins.c command.c compile.c $(code) expand.c glob.c hash.c headers.c lists.c make.c make1.c newstr.c option.c parse.c regexp.c rules.c scan.c search.c timestamp.c variable.c hdrmacro.c ; # Strip the Jam executable on Mingw # if $(JAM_TOOLSET) = MINGW { actions Strip { strip $(1) } Strip jam$(SUFEXE) ; } if $(BINDIR) { InstallBin $(BINDIR) : jam ; } # # Distribution making from here on out. # ALLSOURCE = Build.com Build.mpw Jam.html Jambase Jambase.html Jamfile Jamfile.html Porting README RELNOTES builtins.c builtins.h command.c command.h compile.c compile.h execcmd.h execmac.c execnt.c execunix.c execvms.c expand.c expand.h filemac.c filent.c fileos2.c filesys.h fileunix.c filevms.c glob.c hash.c hash.h hdrmacro.c hdrmacro.h headers.c headers.h jam.c jam.h jambase.c jambase.h jamgram.c jamgram.h jamgram.y jamgram.yy jamgramtab.h lists.c lists.h make.c make.h make1.c mkjambase.c newstr.c newstr.h option.c option.h parse.c parse.h patchlevel.h pathmac.c pathsys.h pathunix.c pathvms.c regexp.c regexp.h rules.c rules.h scan.c scan.h search.c search.h timestamp.c timestamp.h variable.c variable.h yyacc hdrmacro.c INSTALL README.ORG CHANGES common.mk [ GLOB builds : *.mk ] [ GLOB builds/unix : *.in ] builds/unix/configure builds/unix/configure.ac builds/unix/config.sub builds/unix/config.guess builds/unix/install-sh builds/unix/mkinstalldirs configure ; rule Binary { NotFile package ; Depends package : $(<) ; DEPENDS $(<) : $(>) ; switch $(<) { case *-win32.zip : Zip-Exe $(<) : $(>) ; case *-os2.zip : Zip-Exe $(<) : $(>) ; case *-linux-libc6.tar : GZip-Exe $(<) : $(>) ; } } rule Package { NotFile package ; Depends package : $(<) ; DEPENDS $(<) : $(>) ; switch $(<) { case *.tar : { Tar-Gz $(<) : $(>) ; Tar-Bz2 $(<) : $(>) ; } case *.zip : Zip $(<) : $(>) ; } } VERSION = ftjam-2.5.2 ; actions Tar-Gz { ln -s . $(VERSION) tar cvhf $(<) $(VERSION)/$(>) rm -f $(VERSION) gzip -9f $(<) } actions Tar-Bz2 { ln -s . $(VERSION) tar cvhf $(<) $(VERSION)/$(>) bzip2 -9f $(<) rm -f $(<) } if $(UNIX) { actions Zip { rm -f $(<) ln -s . $(VERSION) zip -9rl $(<) $(VERSION)/$(>) rm -f $(VERSION) } } else { actions Zip { $(RMF) $(<) zip -9rl $(<) $(>) } } actions Zip-Exe { zip -9j $(<) $(LOCATE_TARGET)\jam.exe } actions GZip-Exe { ln -s $(LOCATE_TARGET)/jam jam tar chf $(<) jam rm -f jam gzip -9f $(<) } if $(NT) { Binary $(VERSION)-win32.zip : $(ALLSOURCE) ; Package $(VERSION).zip : $(ALLSOURCE) ; } else if $(OS2) { Binary $(VERSION)-os2.zip : $(ALLSOURCE) ; Package $(VERSION).zip : $(ALLSOURCE) ; } else if $(UNIX) { # how can we detect the C library version reliably ?? # for now, this should only be used for convenience # purposes, until we add .rpm and .deb support in.. # if $(OS) = LINUX { Binary $(VERSION)-linux-libc6.tar : jam ; } Package $(VERSION).tar : $(ALLSOURCE) ; Package $(VERSION).zip : $(ALLSOURCE) ; } ftjam-2.5.2/CHANGES0000744000424500003730000001627710441006340013414 0ustar dturnermhpsysChanges between FT-Jam 2.5.2 and 2.5.1: ======================================= I. Engine Improvement: Integration of Kai Backman's fix to dependency computations. When an included file is newer than the file including it, the later must also be part of the list of 'updated' actions. II. Installation fixes: On Unix, building Jam will not longer complain that 'bin.unix' was skipped. This generally needed to 'make' or 'jam' invokation to properly generate the binary Also, the binary is now automatically stripped on Unix systems 'jam package' now works correctly to generate package files on Unix Changes between FT-Jam 2.5.1 and Jam 2.5: ========================================= I. Building Jam: ---------------- On Unix, FTJam can now be built with the traditionnal mantra, that is: ./configure --prefix= make make install some simple Makefiles are also provided for a small number of selected platforms (mainly Windows and OS/2). For more information, please read the INSTALL file. II. Command line processing: ---------------------------- command line options can now be placed anywhere. In classic Jam, they must always appear before the target names. additionnally, if a command line argument includes, but doesn't start with a '=', it it treated as an implicit '-s' option (variable definition). this means that you can write things like: jam install DEFINES=DEBUG instead of: jam -sDEFINES=DEBUG install III. Engine improvements: ----------------------- III.1. The JAMCMDARGS: A new builting variable has been defined. When FT-Jam start, it defines the variable JAMCMDARGS which contains the list of targets used on the command line when Jam was invoked. This is useful to provide richer control flow in the Jambase depending on command line arguments. III.1. Expansion Modifiers: A new modifier 'Q' has been added in order to quote the result of an expansion. This basically replaces \ by \\ in expansions. this is mainly useful within Actions block to prevent shells from doing stupid things to your parameters when they contain a back-slash. III.2. HdrMacro built-in rule: Jam's automatic header inclusion scanner now supports the current ISO C89 construct: #include MY_HEADER_H to do this, you need to use the new HdrMacro built-in, and give it the name of one or more header files containing the definition of MY_HEADER_H. This will only record those definitions that look like valid header inclusion paths, like: #define MY_HEADER_H #define MY_HEADER_H "myheader.h" These macro definitions are recorded by Jam, and used later during the header scanning process to add the corresponding file(s) to the dependency graph. III.3. Variable import: When Jam starts, it begins by importing all variables from the environment. Classic Jam had a bug that made it crash when very long variables where defined in Unix. Additionnaly, variables whose content begins with "()" are ignored since they correspond to function variables in Unix shells like BASH, and don't have any meaning in the context of Jam III.4. mkjambase now supports DOS text files: the 'mkjambase' file didn't support DOS text files well. It created a corrupted image of the Jambase within the Jam executable. III.5. Library scanning bug fix: Jam couldn't see object files with long file names within library files on Windows when they were generated with Mingw. This caused the corresponding object files to always be re-built. IV. Jambase improvements: ------------------------- IV.1. Compiler selection through the JAM_TOOLSET: ------------------------------------------------- on Windows and OS/2 only, FTJam selects the compiler like Classic Jam by exploring the environment, looking for specific variables. However, it none is found, it looks for the JAM_TOOLSET variable and use it to select the toolset being used. This list is displayed by Jam when JAM_TOOLSET is undefined or set to an unsupported value (see next chapter). Nothing is changed on Unix and other platforms. IV.2. Improved compiler support: --------------------------------- FTJam supports a lot more compiler than Classic Jam. Here's a table that maps values of JAM_TOOLSET to the corresponding compiler on Windows: JAM_TOOLSET Toolset Description BORLANDC Borland C++ VISUALC Microsoft Visual C++ VISUALC16 Microsoft Visual C++ 16 bit INTELC Intel C/C++ WATCOM Watcom C/C++ MINGW MinGW (gcc) LCC Win32-LCC DIGITALMARS Digital Mars C/C++ PELLESC Pelles C the same table for OS/2 is: WATCOM Watcom C/C++ EMX EMX (gcc) Nothing is changed for other paltforms. on Unix, including Cygwin, selection is performed through the CC environment variable, which defaults to 'cc'. IMPORTANT: if you're using a Unix emulation layer like Cygwin or MSys, you should use a version of FTJam specially compiled for them, which will act exactly like the Unix version. IV.3. Support for building and linking shared libraries & DLLs: ---------------------------------------------------------------- Some new rules have been defined to be able to build and link with shared libraries (on Unix) and DLLs (on Windows only). NOTE THAT THIS SUPPORT IS STILL EXPERIMENTAL AT THE MOMENT. These rules are: SharedLibrary library : sources : import : def ; Compiles 'sources' and generates a shared 'library' (i.e. DLL on Windows, or shared object on Unix). Calls SharedObjects and SharedLibraryFromObjects If SharedLibrary is invoked with no suffix on 'library', then $(SUFLIBSHR) suffix is used (.so on Unix, .dll on Windows) 'import' is the name of the corresponding import library for Windows and OS/2 platforms (ignored otherwise). If it is not defined, it will default to 'library' with the $(SUFLIB) suffix. 'def' is the name of the corresponding definition file used to generate the library on Windows and OS/2 (ignored otherwise). SharedLibraryFromObjects library : objects : import : defs Equivalent to LibraryFromObjects for shared libraries and DLLs. See above for the description of parameters LinkSharedLibraries program : library ; Used to link a program to a shared library generated through 'SharedLibrary'. Equivalent to 'LinkLibraries'. NOTICE THAT IT IS NOT CURRENTLY POSSIBLE TO BUILD BOTH A NORMAL AND A SHARED LIBRARY WITH THE SAME NAME. We'll try to fix this in a later release. IV.4. Experimental Package Management: --------------------------------------- The end of our Jambase contains the definitions of several new rules that can be used to define independent software packages and manage their installation, deinstallation and dependencies on various platforms. This code is highly experimental at the moment and we will not describe it here in detail. If you're interested, look at the end of the Jambase for rules whose name begin in Pkg (e.g. PkgBegin, PkgEnd, PkgUses, etc...) ftjam-2.5.2/newstr.h0000744000424500003730000000056610441006340014106 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * newstr.h - string manipulation routines * * 11/04/02 (seiwald) - const-ing for string literals */ const char *newstr( const char *string ); const char *copystr( const char *s ); void freestr( const char *s ); void donestr(); ftjam-2.5.2/compile.c0000744000424500003730000005114310441006341014205 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * compile.c - compile parsed jam statements * * External routines: * * compile_append() - append list results of two statements * compile_break() - compile 'break/continue/return' rule * compile_eval() - evaluate if to determine which leg to compile * compile_foreach() - compile the "for x in y" statement * compile_if() - compile 'if' rule * compile_include() - support for 'include' - call include() on file * compile_list() - expand and return a list * compile_local() - declare (and set) local variables * compile_null() - do nothing -- a stub for parsing * compile_on() - run rule under influence of on-target variables * compile_rule() - compile a single user defined rule * compile_rules() - compile a chain of rules * compile_set() - compile the "set variable" statement * compile_setcomp() - support for `rule` - save parse tree * compile_setexec() - support for `actions` - save execution string * compile_settings() - compile the "on =" (set variable on exec) statement * compile_switch() - compile 'switch' rule * * Internal routines: * * debug_compile() - printf with indent to show rule expansion. * evaluate_rule() - execute a rule invocation * * 02/03/94 (seiwald) - Changed trace output to read "setting" instead of * the awkward sounding "settings". * 04/12/94 (seiwald) - Combined build_depends() with build_includes(). * 04/12/94 (seiwald) - actionlist() now just appends a single action. * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 05/13/94 (seiwald) - include files are now bound as targets, and thus * can make use of $(SEARCH) * 06/01/94 (seiwald) - new 'actions existing' does existing sources * 08/23/94 (seiwald) - Support for '+=' (append to variable) * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. * 01/22/95 (seiwald) - Exit rule. * 02/02/95 (seiwald) - Always rule; LEAVES rule. * 02/14/95 (seiwald) - NoUpdate rule. * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C * 09/07/00 (seiwald) - stop crashing when a rule redefines itself * 09/11/00 (seiwald) - new evaluate_rule() for headers(). * 09/11/00 (seiwald) - rules now return values, accessed via [ rule arg ... ] * 09/12/00 (seiwald) - don't complain about rules invoked without targets * 01/13/01 (seiwald) - fix case where rule is defined within another * 01/10/01 (seiwald) - built-ins split out to builtin.c. * 01/11/01 (seiwald) - optimize compile_rules() for tail recursion * 01/21/01 (seiwald) - replace evaluate_if() with compile_eval() * 01/24/01 (seiwald) - 'while' statement * 03/23/01 (seiwald) - "[ on target rule ]" support * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx * 03/02/02 (seiwald) - rules can be invoked via variable names * 03/12/02 (seiwald) - &&,&,||,|,in now short-circuit again * 03/25/02 (seiwald) - if ( "" a b ) one again returns true * 06/21/02 (seiwald) - support for named parameters * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 10/22/02 (seiwald) - working return/break/continue statements * 11/04/02 (seiwald) - const-ing for string literals * 11/18/02 (seiwald) - remove bogus search() in 'on' statement. * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars */ # include "jam.h" # include "lists.h" # include "parse.h" # include "compile.h" # include "variable.h" # include "expand.h" # include "rules.h" # include "newstr.h" # include "search.h" static const char *set_names[] = { "=", "+=", "?=" }; static void debug_compile( int which, const char *s ); int glob( const char *s, const char *c ); /* * compile_append() - append list results of two statements * * parse->left more compile_append() by left-recursion * parse->right single rule */ LIST * compile_append( PARSE *parse, LOL *args, int *jmp ) { /* Append right to left. */ return list_append( (*parse->left->func)( parse->left, args, jmp ), (*parse->right->func)( parse->right, args, jmp ) ); } /* * compile_break() - compile 'break/continue/return' rule * * parse->left results * parse->num JMP_BREAK/CONTINUE/RETURN */ LIST * compile_break( PARSE *parse, LOL *args, int *jmp ) { LIST *lv = (*parse->left->func)( parse->left, args, jmp ); *jmp = parse->num; return lv; } /* * compile_eval() - evaluate if to determine which leg to compile * * Returns: * list if expression true - compile 'then' clause * L0 if expression false - compile 'else' clause */ static int lcmp( LIST *t, LIST *s ) { int status = 0; while( !status && ( t || s ) ) { const char *st = t ? t->string : ""; const char *ss = s ? s->string : ""; status = strcmp( st, ss ); t = t ? list_next( t ) : t; s = s ? list_next( s ) : s; } return status; } LIST * compile_eval( PARSE *parse, LOL *args, int *jmp ) { LIST *ll, *lr, *s, *t; int status = 0; /* Short circuit lr eval for &&, ||, and 'in' */ ll = (*parse->left->func)( parse->left, args, jmp ); lr = 0; switch( parse->num ) { case EXPR_AND: case EXPR_IN: if( ll ) goto eval; break; case EXPR_OR: if( !ll ) goto eval; break; default: eval: lr = (*parse->right->func)( parse->right, args, jmp ); } /* Now eval */ switch( parse->num ) { case EXPR_NOT: if( !ll ) status = 1; break; case EXPR_AND: if( ll && lr ) status = 1; break; case EXPR_OR: if( ll || lr ) status = 1; break; case EXPR_IN: /* "a in b": make sure each of */ /* ll is equal to something in lr. */ for( t = ll; t; t = list_next( t ) ) { for( s = lr; s; s = list_next( s ) ) if( !strcmp( t->string, s->string ) ) break; if( !s ) break; } /* No more ll? Success */ if( !t ) status = 1; break; case EXPR_EXISTS: if( lcmp( ll, L0 ) != 0 ) status = 1; break; case EXPR_EQUALS: if( lcmp( ll, lr ) == 0 ) status = 1; break; case EXPR_NOTEQ: if( lcmp( ll, lr ) != 0 ) status = 1; break; case EXPR_LESS: if( lcmp( ll, lr ) < 0 ) status = 1; break; case EXPR_LESSEQ: if( lcmp( ll, lr ) <= 0 ) status = 1; break; case EXPR_MORE: if( lcmp( ll, lr ) > 0 ) status = 1; break; case EXPR_MOREEQ: if( lcmp( ll, lr ) >= 0 ) status = 1; break; } if( DEBUG_IF ) { debug_compile( 0, "if" ); list_print( ll ); printf( "(%d) ", status ); list_print( lr ); printf( "\n" ); } /* Find something to return. */ /* In odd circumstances (like "" = "") */ /* we'll have to return a new string. */ if( !status ) t = 0; else if( ll ) t = ll, ll = 0; else if( lr ) t = lr, lr = 0; else t = list_new( L0, "1", 0 ); if( ll ) list_free( ll ); if( lr ) list_free( lr ); return t; } /* * compile_foreach() - compile the "for x in y" statement * * Compile_foreach() resets the given variable name to each specified * value, executing the commands enclosed in braces for each iteration. * * parse->string index variable * parse->left variable values * parse->right rule to compile */ LIST * compile_foreach( PARSE *p, LOL *args, int *jmp ) { LIST *nv = (*p->left->func)( p->left, args, jmp ); LIST *result = 0; LIST *l; /* for each value for var */ for( l = nv; l && *jmp == JMP_NONE; l = list_next( l ) ) { /* Reset $(p->string) for each val. */ var_set( p->string, list_new( L0, l->string, 1 ), VAR_SET ); /* Keep only last result. */ list_free( result ); result = (*p->right->func)( p->right, args, jmp ); /* continue loop? */ if( *jmp == JMP_CONTINUE ) *jmp = JMP_NONE; } /* Here by break/continue? */ if( *jmp == JMP_BREAK || *jmp == JMP_CONTINUE ) *jmp = JMP_NONE; list_free( nv ); /* Returns result of last loop */ return result; } /* * compile_if() - compile 'if' rule * * parse->left condition tree * parse->right then tree * parse->third else tree */ LIST * compile_if( PARSE *p, LOL *args, int *jmp ) { LIST *l = (*p->left->func)( p->left, args, jmp ); p = l ? p->right : p->third; list_free( l ); return (*p->func)( p, args, jmp ); } /* * compile_include() - support for 'include' - call include() on file * * parse->left list of files to include (can only do 1) */ LIST * compile_include( PARSE *parse, LOL *args, int *jmp ) { LIST *nt = (*parse->left->func)( parse->left, args, jmp ); if( DEBUG_COMPILE ) { debug_compile( 0, "include" ); list_print( nt ); printf( "\n" ); } if( nt ) { TARGET *t = bindtarget( nt->string ); /* Bind the include file under the influence of */ /* "on-target" variables. Though they are targets, */ /* include files are not built with make(). */ /* Needn't copysettings(), as search sets no vars. */ pushsettings( t->settings ); t->boundname = search( t->name, &t->time ); popsettings( t->settings ); /* Don't parse missing file if NOCARE set */ if( t->time || !( t->flags & T_FLAG_NOCARE ) ) parse_file( t->boundname ); } list_free( nt ); return L0; } /* * compile_list() - expand and return a list * * parse->string - character string to expand */ LIST * compile_list( PARSE *parse, LOL *args, int *jmp ) { /* voodoo 1 means: s is a copyable string */ const char *s = parse->string; return var_expand( L0, s, s + strlen( s ), args, 1 ); } /* * compile_local() - declare (and set) local variables * * parse->left list of variables * parse->right list of values * parse->third rules to execute */ LIST * compile_local( PARSE *parse, LOL *args, int *jmp ) { LIST *l; SETTINGS *s = 0; LIST *nt = (*parse->left->func)( parse->left, args, jmp ); LIST *ns = (*parse->right->func)( parse->right, args, jmp ); LIST *result; if( DEBUG_COMPILE ) { debug_compile( 0, "local" ); list_print( nt ); printf( " = " ); list_print( ns ); printf( "\n" ); } /* Initial value is ns */ for( l = nt; l; l = list_next( l ) ) s = addsettings( s, 0, l->string, list_copy( (LIST*)0, ns ) ); list_free( ns ); list_free( nt ); /* Note that callees of the current context get this "local" */ /* variable, making it not so much local as layered. */ pushsettings( s ); result = (*parse->third->func)( parse->third, args, jmp ); popsettings( s ); freesettings( s ); return result; } /* * compile_null() - do nothing -- a stub for parsing */ LIST * compile_null( PARSE *parse, LOL *args, int *jmp ) { return L0; } /* * compile_on() - run rule under influence of on-target variables * * parse->left target list; only first used * parse->right rule to run */ LIST * compile_on( PARSE *parse, LOL *args, int *jmp ) { LIST *nt = (*parse->left->func)( parse->left, args, jmp ); LIST *result = 0; if( DEBUG_COMPILE ) { debug_compile( 0, "on" ); list_print( nt ); printf( "\n" ); } /* * Copy settings, so that 'on target var on target = val' * doesn't set var globally. */ if( nt ) { TARGET *t = bindtarget( nt->string ); SETTINGS *s = copysettings( t->settings ); pushsettings( s ); result = (*parse->right->func)( parse->right, args, jmp ); popsettings( s ); freesettings( s ); } list_free( nt ); return result; } /* * compile_rule() - compile a single user defined rule * * parse->left list of rules to run * parse->right parameters (list of lists) to rule, recursing left * * Wrapped around evaluate_rule() so that headers() can share it. */ LIST * compile_rule( PARSE *parse, LOL *args, int *jmp ) { LOL nargs[1]; LIST *result = 0; LIST *ll, *l; PARSE *p; /* list of rules to run -- normally 1! */ ll = (*parse->left->func)( parse->left, args, jmp ); /* Build up the list of arg lists */ lol_init( nargs ); for( p = parse->right; p; p = p->left ) lol_add( nargs, (*p->right->func)( p->right, args, jmp ) ); /* Run rules, appending results from each */ for( l = ll; l; l = list_next( l ) ) result = evaluate_rule( l->string, nargs, result ); list_free( ll ); lol_free( nargs ); return result; } /* * evaluate_rule() - execute a rule invocation */ LIST * evaluate_rule( const char *rulename, LOL *args, LIST *result ) { RULE *rule = bindrule( rulename ); if( DEBUG_COMPILE ) { debug_compile( 1, rulename ); lol_print( args ); printf( "\n" ); } /* Check traditional targets $(<) and sources $(>) */ if( !rule->actions && !rule->procedure ) printf( "warning: unknown rule %s\n", rule->name ); /* If this rule will be executed for updating the targets */ /* then construct the action for make(). */ if( rule->actions ) { TARGETS *t; ACTION *action; /* The action is associated with this instance of this rule */ action = (ACTION *)malloc( sizeof( ACTION ) ); memset( (char *)action, '\0', sizeof( *action ) ); action->rule = rule; action->targets = targetlist( (TARGETS *)0, lol_get( args, 0 ) ); action->sources = targetlist( (TARGETS *)0, lol_get( args, 1 ) ); /* Append this action to the actions of each target */ for( t = action->targets; t; t = t->next ) t->target->actions = actionlist( t->target->actions, action ); } /* Now recursively compile any parse tree associated with this rule */ if( rule->procedure ) { PARSE *parse = rule->procedure; SETTINGS *s = 0; int jmp = JMP_NONE; LIST *l; int i; /* build parameters as local vars */ for( l = rule->params, i = 0; l; l = l->next, i++ ) s = addsettings( s, 0, l->string, list_copy( L0, lol_get( args, i ) ) ); /* Run rule. */ /* Bring in local params. */ /* refer/free to ensure rule not freed during use. */ parse_refer( parse ); pushsettings( s ); result = list_append( result, (*parse->func)( parse, args, &jmp ) ); popsettings( s ); freesettings( s ); parse_free( parse ); } if( DEBUG_COMPILE ) debug_compile( -1, 0 ); return result; } /* * compile_rules() - compile a chain of rules * * parse->left single rule * parse->right more compile_rules() by right-recursion */ LIST * compile_rules( PARSE *parse, LOL *args, int *jmp ) { /* Ignore result from first statement; return the 2nd. */ /* Optimize recursion on the right by looping. */ LIST *result = 0; while( *jmp == JMP_NONE && parse->func == compile_rules ) { list_free( result ); result = (*parse->left->func)( parse->left, args, jmp ); parse = parse->right; } if( *jmp == JMP_NONE ) { list_free( result ); result = (*parse->func)( parse, args, jmp ); } return result; } /* * compile_set() - compile the "set variable" statement * * parse->left variable names * parse->right variable values * parse->num VAR_SET/APPEND/DEFAULT */ LIST * compile_set( PARSE *parse, LOL *args, int *jmp ) { LIST *nt = (*parse->left->func)( parse->left, args, jmp ); LIST *ns = (*parse->right->func)( parse->right, args, jmp ); LIST *l; if( DEBUG_COMPILE ) { debug_compile( 0, "set" ); list_print( nt ); printf( " %s ", set_names[ parse->num ] ); list_print( ns ); printf( "\n" ); } /* Call var_set to set variable */ /* var_set keeps ns, so need to copy it */ for( l = nt; l; l = list_next( l ) ) var_set( l->string, list_copy( L0, ns ), parse->num ); list_free( nt ); return ns; } /* * compile_setcomp() - support for `rule` - save parse tree * * parse->string rule name * parse->left list of argument names * parse->right rules for rule */ LIST * compile_setcomp( PARSE *parse, LOL *args, int *jmp ) { RULE *rule = bindrule( parse->string ); LIST *params = 0; PARSE *p; /* Build param list */ for( p = parse->left; p; p = p->left ) params = list_new( params, p->string, 1 ); if( DEBUG_COMPILE ) { debug_compile( 0, "rule" ); printf( "%s ", parse->string ); list_print( params ); printf( "\n" ); } /* Free old one, if present */ if( rule->procedure ) parse_free( rule->procedure ); if( rule->params ) list_free( rule->params ); rule->procedure = parse->right; rule->params = params; /* we now own this parse tree */ /* don't let parse_free() release it */ parse_refer( parse->right ); return L0; } /* * compile_setexec() - support for `actions` - save execution string * * parse->string rule name * parse->string1 OS command string * parse->num flags * parse->left `bind` variables * * Note that the parse flags (as defined in compile.h) are transfered * directly to the rule flags (as defined in rules.h). */ LIST * compile_setexec( PARSE *parse, LOL *args, int *jmp ) { RULE *rule = bindrule( parse->string ); LIST *bindlist = (*parse->left->func)( parse->left, args, jmp ); /* Free old one, if present */ if( rule->actions ) { freestr( rule->actions ); list_free( rule->bindlist ); } rule->actions = copystr( parse->string1 ); rule->bindlist = bindlist; rule->flags = parse->num; return L0; } /* * compile_settings() - compile the "on =" (set variable on exec) statement * * parse->left variable names * parse->right target name * parse->third variable value * parse->num VAR_SET/APPEND/DEFAULT */ LIST * compile_settings( PARSE *parse, LOL *args, int *jmp ) { LIST *nt = (*parse->left->func)( parse->left, args, jmp ); LIST *ns = (*parse->third->func)( parse->third, args, jmp ); LIST *targets = (*parse->right->func)( parse->right, args, jmp ); LIST *ts; if( DEBUG_COMPILE ) { debug_compile( 0, "set" ); list_print( nt ); printf( "on " ); list_print( targets ); printf( " %s ", set_names[ parse->num ] ); list_print( ns ); printf( "\n" ); } /* Call addsettings to save variable setting */ /* addsettings keeps ns, so need to copy it */ /* Pass append flag to addsettings() */ for( ts = targets; ts; ts = list_next( ts ) ) { TARGET *t = bindtarget( ts->string ); LIST *l; for( l = nt; l; l = list_next( l ) ) t->settings = addsettings( t->settings, parse->num, l->string, list_copy( (LIST*)0, ns ) ); } list_free( nt ); list_free( targets ); return ns; } /* * compile_switch() - compile 'switch' rule * * parse->left switch value (only 1st used) * parse->right cases * * cases->left 1st case * cases->right next cases * * case->string argument to match * case->left parse tree to execute */ LIST * compile_switch( PARSE *parse, LOL *args, int *jmp ) { LIST *nt = (*parse->left->func)( parse->left, args, jmp ); LIST *result = 0; if( DEBUG_COMPILE ) { debug_compile( 0, "switch" ); list_print( nt ); printf( "\n" ); } /* Step through cases */ for( parse = parse->right; parse; parse = parse->right ) { if( !glob( parse->left->string, nt ? nt->string : "" ) ) { /* Get & exec parse tree for this case */ parse = parse->left->left; result = (*parse->func)( parse, args, jmp ); break; } } list_free( nt ); return result; } /* * compile_while() - compile 'while' rule * * parse->left condition tree * parse->right execution tree */ LIST * compile_while( PARSE *p, LOL *args, int *jmp ) { LIST *result = 0; LIST *l; /* Returns the value from the last execution of the block */ while( ( *jmp == JMP_NONE ) && ( l = (*p->left->func)( p->left, args, jmp ) ) ) { /* Always toss while's expression */ list_free( l ); /* Keep only last result. */ list_free( result ); result = (*p->right->func)( p->right, args, jmp ); /* continue loop? */ if( *jmp == JMP_CONTINUE ) *jmp = JMP_NONE; } /* Here by break/continue? */ if( *jmp == JMP_BREAK || *jmp == JMP_CONTINUE ) *jmp = JMP_NONE; /* Returns result of last loop */ return result; } /* * debug_compile() - printf with indent to show rule expansion. */ static void debug_compile( int which, const char *s ) { static int level = 0; static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|"; int i = ((1+level) * 2) % 35; if( which >= 0 ) printf( "%*.*s ", i, i, indent ); if( s ) printf( "%s ", s ); level += which; } ftjam-2.5.2/Jamfile.html0000744000424500003730000014457210441006341014657 0ustar dturnermhpsys Jamfiles and Jambase

Jam

Using Jamfiles and Jambase

This document describes how to write Jamfiles using the Jam Jambase rules to build software products. Related documents of interest are:

Jam documentation and source are available from the Perforce Public Depot.


Overview

jam, the Jam executable program, recursively builds target files from source files using dependency and build specifications defined in Jam rules files. jam parses the rules files to identify targets and sources, examines the filesystem to determine which targets need updating, and issues OS commands to update targets.

A base rules file called "Jambase" is provided with the Jam distribution. The Jambase file defines rules and variables which support standard software build operations, like compiling, linking, etc.

When the Jambase rules are used, jam reads Jambase, then reads a file called "Jamfile" in the current directory. The Jamfile describes what to do with the source files in its directory. It may also cause Jamfiles in other directories to be read.

Under certain circumstances, the first Jamfile read also causes a site-specific "Jamrules" file to be read. The Jamrules file is an optional set of rule and variable definitions used to define site-specific processing.

The Basic Jamfile

Jamfiles contain rule invocations, which usually look like:

	RuleName targets : targets ;
The target(s) to the left of the colon usually indicate what gets built, and the target(s) to the right of the colon usually indicate what it is built from.

A Jamfile can be as simple as this:

	Main myprog : main.c util.c ;
This specifies that there is a main.c and util.c file in the same directory as the Jamfile, and that those source files should be compiled and linked into an executable called myprog. If you cd to the directory where this Jamfile lives, you can see the exactly how jam would build myprog with:
	jam -n
Or, you can actually build myprog with the command:
	jam

Whitespace

Jamfile elements are delimited by whitespace (blanks, tabs, or newlines). Elements to be delimited include rule names, targets, colons, and semicolons. A common mistake users make is to forget the whitespace, e.g.,
	Main myprog: main.c util.c ; #WRONG!
Jam doesn't distinguish between a typo and a target called "myprog:", so if you get strange results, the first thing you should check for in your Jamfile is missing whitespace.

Filenames, Target Identifiers, and Buildable Targets

Consider this Jamfile:

	Main myprog : main.c util.c ;                   
	LinkLibraries myprog : libtree ;     
	Library libtree : treemake.c treetrav.c ;    

The Main rule specifies that an executable called myprog will be built. The compiled main.c and util.c objects will be linked to produce myprog. The LinkLibraries rule specifies that libtree will be linked into myprog as well. The Library rule specifies which source files will be compiled and archived into the libtree library.

The Jamfile above refers to targets like "myprog" and "libtree". However, depending on the platform you're building on, the actual filenames of those targets could be "myprog.exe" and "libtree.lib". Most Jambase rules supply the actual filenames of targets, so that Jamfiles themselves need not make any platform-specific filename references.

The jam program builds up a list of unique target identifiers. Unless you are using the SubDir rules (described later), the default identifier for a file target is its filename. In the above example, the target identifiers are the filenames: myprog.exe, libtree.lib, main.obj, etc.

While all Jambase rules refer to "targets", not all targets are buildable. There are two kinds of buildable targets: file targets and pseudotargets. File targets are objects that can be found in the filesystem. Pseudotargets are symbolic, and represent other targets.

You can use any buildable target on the jam command line to build a subset of defined targets. For example:

        jam libtree.a 
on Unix builds the libtree library and all the compiled objects that go in it.

Pseudotargets

Most Jambase rules that define file targets also define pseudotargets which are dependent on types of file targets. For example, Jambase defines a pseudotarget called "lib", which is dependent on file targets created by the Library rule. So the command:

        jam lib
used with the above example would cause the libtree library to be built. Also, there is one pseudotarget built into jam itself, called "all". Jambase sets "all" dependent on (almost) all other targets.

In the unfortunate case where you have a buildable target whose name is the same as one of the Jambase pseudotargets, you'll have problems with the conflicting target name. Your workaround choices are:

  1. Change the name of your buildable file or directory that conflicts.

  2. Modify your Jambase and change the name of the conflicting pseudotarget. (Pseudotargets are defined in Jambase using the NOTFILE rule.)

  3. Use grist on the conflicting target name in your Jamfile. E.g., instead of
        File lib : libfoo.a ;
        
    try
        File <dir>lib : libfoo.a ;
        

Dependencies

Jambase rules set dependencies on targets, so that if you update a source file, all the file targets that depend on that source file, and only the ones that depend on that source file, will be updated (rebuilt) the next time you run jam.

Here are some of the dependencies that get set when jam runs on NT using the example Jamfile above:

Target   Depends on
myprog.exemain.obj, util.obj, libtree.lib
libtree.libtreemake.obj, treetrav.obj
treetrav.objtreetrav.c

Furthermore, the Main and Library rules set up recursive header scanning on their source targets. So after jam has finished parsing the Jamfile and setting the rule-driven dependencies, it scans the source files for "#include" lines. All #include files found during this scan become dependencies of the compiled object. E.g., all header files used to compile treetrav.c would be made dependencies of treetrav.obj.

As a result, when you run jam, it will rebuild targets if either the source files change or the header files change. You can't tell by looking at a Jamfile which header files are dependencies, but you can easily display those dependencies with:

	jam -nd+3

Rule Ordering

Rules which specify dependencies, like the Main, Library, and LinkLibrary rules, can be invoked in any order. jam figures out the order in which targets are built from their dependencies.

Some rules, however, set variables which are used by subsequent rule invocations, and their ordering is important. For example, the SubDir* rules (discussed later) must be invoked in a particular order.

Detailed Jambase Specifications

This document describes how to use various Jambase rules from a functional point of view. You can see the summary of available Jambase rules in the Jambase Reference. The detailed specifications for any Jambase rule can be found by reading the rule definition itself in the Jambase file.


Handling Directory Trees

The SubDir* rules are used to define source code directory hierarchies. With SubDir and SubInclude, you can use jam to build software from source files and Jamfiles spread across many directories, as is typical for large projects. The SubDir* rules unify an entire source code tree so that jam can read in all the Jamfiles in one pass and compute dependencies across the entire project.

To use the SubDir* rules, you must:

  1. Preface the Jamfile in each directory with an invocation of the SubDir rule.

  2. Place at the root of the tree a file named Jamrules. This file could be empty, but in practice it contains user-provided rules and variable definitions that are shared throughout the tree. Examples of such definitions are library names, header directories, install directories, compiler flags, etc. This file is good candidate for automatic customizing with autoconf(GNU).

  3. Optionally, set an environment variable pointing to the root directory of the srouce tree. The variable's name is left up to you, but in these examples, we use TOP.

SubDir Rule

The SubDir rule must be invoked before any rules that refer to the contents of the directory - it is best to put it at the top of each Jamfile. For example:

	# Jamfile in $(TOP)/src/util directory.

	SubDir TOP src util ;

	Main myprog : main.c util.c ;                   
	LinkLibraries myprog : libtree ;     
	Library libtree : treemake.c treetrav.c ;    
This compiles four files in $(TOP)/src/util, archives two of the objects into libtree, and links the whole thing into myprog. Outputs are placed in the $(TOP)/src/util directory.

This doesn't appear to be any different from the previous example that didn't have a SubDir rule, but two things are happening behind the scenes:

  1. The SubDir rule causes jam to read in the $(TOP)/Jamrules file. (The Jamrules file can alternately be named by the variable $(xxxRULES), where xxx is the name of the root variable, e.g., $(TOPRULES)).

    The Jamrules file can contain variable definitions and rule definitions specific to your codeline. It allows you to completely customize your build environment without having to rewrite Jambase. Jamrules is only read in once, at the first SubDir invocation.

  2. The SubDir rule initializes a set of variables that are used by Main and other rules to uniquely identify the source files in this directory and assign locations to the targets built from files in this directory.

    When you have set a root variable, e.g., $(TOP), SubDir constructs path names rooted with $(TOP), e.g., $(TOP)/src/util. Otherwise, SubDir constructs relative pathnames to the root directory, computed from the number of arguments to the first SubDir rule, e.g., ../../src/util. In either case, the SubDir rule constructs the path names that locate source files. You'll see how this is useful later.

    The SubDir rule takes as its first argument the root variable's name and takes as subsequent arguments the directory names leading from the root to the directory of the current Jamfile. Note that the name of the subdirectory is given as individual elements: the SubDir rule does not use system-specific directory name syntax.

    SubInclude Rule

    The SubInclude rule is used in a Jamfile to cause another Jamfile to be read in. Its arguments are in the same format as SubDir's.

    The recommended practice is only to include one level of subdirectories at a time, and let the Jamfile in each subdirectory include its own subdirectories. This allows a user to sit in any arbitrary directory of the source tree and build that subtree. For example:

           # This is $(TOP)/Jamfile, top level Jamfile for mondo project.
    
           SubInclude TOP src ;
           SubInclude TOP man ;
           SubInclude TOP misc ;
           SubInclude TOP util ;
    
    If a directory has both subdirectories of its own as well as files that need building, the SubIncludes should be either before the SubDir rule or be at the end of the Jamfile - not between the SubDir and other rule invocations. For example:
    	# This is $(TOP)/src/Jamfile:
    
    	SubDir TOP src ;
    
    	Main mondo : mondo.c ;
    	LinkLibraries mondo : libmisc libutil ;
    	
    	SubInclude TOP src misc ;
    	SubInclude TOP src util ;
    

    (jam processes all the Jamfiles it reads as if it were reading one single, large Jamfile. Build rules like Main and LinkLibraries rely on the preceding SubDir rule to set up source file and output file locations, and SubIncludes rules read in Jamfiles that contain SubDir rules. So if you put a SubIncludes rule between a SubDir and a Main rule, jam will try to find the source files for the Main rule in the wrong directory.)

    Variables Used to Handle Directory Trees

    The following variables are set by the SubDir rule and used by the Jambase rules that define file targets:

    SEARCH_SOURCE The SubDir targets (e.g., "TOP src util") are used to construct a pathname (e.g., $(TOP)/src/util), and that pathname is assigned to $(SEARCH_SOURCE). Rules like Main and Library use $(SEARCH_SOURCE) to set search paths on source files.
    LOCATE_SOURCE Initialized by the SubDir rule to the same value as $(SEARCH_SOURCE), unless ALL_LOCATE_TARGET is set. $(LOCATE_SOURCE) is used by rules that build generated source files (e.g., Yacc and Lex) to set location of output files. Thus the default location of built source files is the directory of the Jamfile that defines them.
    LOCATE_TARGET Initalized by the SubDir rule to the same value as $(SEARCH_SOURCE), unless ALL_LOCATE_TARGET is set. $(LOCATE_TARGET) is used by rules that build binary objects (e.g., Main and Library) to set location of output files. Thus the default location of built binaray files is the directory of the Jamfile that defines them.
    ALL_LOCATE_TARGET If $(ALL_LOCATE_TARGET) is set, LOCATE_SOURCE and and LOCATE_TARGET are set to $(ALL_LOCATE_TARGET) instead of to $(SEARCH_SOURCE). This can be used to direct built files to be written to a location outside of the source tree, and enables building from read-only source trees.
    SOURCE_GRIST The SubDir targets are formed into a string like "src!util" and that string is assigned to SOURCE_GRIST. Rules that define file targets use $(SOURCE_GRIST) to set the "grist" attribute on targets. This is used to assure uniqueness of target identifiers where filenames themselves are not unique. For example, the target identifiers of $(TOP)/src/client/main.c and $(TOP)/src/server/main.c would be <src!client>main.c and <src!server>main.c.

    The $(LOCATE_TARGET) and $(SEARCH_SOURCE) variables are used extensively by rules in Jambase: most rules that generate targets (like Main, Object, etc.) set $(LOCATE) to $(LOCATE_TARGET) for the targets they generate, and rules that use sources (most all of them) set $(SEARCH) to be $(SEARCH_SOURCE) for the sources they use.

    $(LOCATE) and $(SEARCH) are better explained in The Jam Executable Program but in brief they tell jam where to create new targets and where to find existing ones, respectively.

    Note that you can reset these variables after SubDir sets them. For example, this Jamfile builds a program called gensrc, then runs it to create a source file called new.c:

           SubDir TOP src util ;
           Main gensrc : gensrc.c ;
           LOCATE_SOURCE = $(NEWSRC) ;
           GenFile new.c : gensrc ;
           
    By default, new.c would be written into the $(TOP)/src/util directory, but resetting LOCATE_SOURCE causes it to be written to the $(NEWSRC) directory. ($(NEWSRC) is assumed to have been set elsewhere, e.g., in Jamrules.)

    VMS Notes

    On VMS, the logical name table is not imported as is the environment on UNIX. To use the SubDir and related rules, you must set the value of the variable that names the root directory. For example:
                  TOP = USR_DISK:[JONES.SRC] ;
    
                  SubInclude TOP util ;
    
    The variable must have a value that looks like a directory or device. If you choose, you can use a concealed logical. For example:
                  TOP = TOP: ;
    
                  SubInclude TOP util ;
    
    The : at the end of TOP makes the value of $(TOP) look like a device name, which jam respects as a directory name and will use when trying to access files. TOP must then be defined from DCL:
                  $ define/job/translation=concealed TOP DK100:[USERS.JONES.SRC.]
    
    Note three things: the concealed translation allows the logical to be used as a device name; the device name in the logical (here DK100) cannot itself be concealed logical (VMS rules, man); and the directory component of the definition must end in a period (more VMS rules).

    Building Executables and Libraries

    The rules that build executables and libraries are: Main, Library, and LinkLibraries.

    Main Rule

    The Main rule compiles source files and links the resulting objects into an executable. For example:
                  Main myprog : main.c util.c ;
    
    This compiles main.c and util.c and links main.o and util.o into myprog. The object files and resulting executable are named appropriately for the platform.

    Main can also be used to build shared libraries and/or dynamic link libraries, since those are also linked objects. E.g.:

    		Main driver$(SUFSHR) : driver.c ;
    	
    Normally, Main uses $(SUFEXE) to determine the suffix on the filename of the built target. To override it, you can supply a suffix explicity. In this case, $(SUFSHR) is assumed to be the OS-specific shared library suffix, defined in Jamrules with something like:
    		if $(UNIX)      { SUFSHR = .so ; }
    		else if $(NT)   { SUFSHR = .dll ; }
    	

    Main uses the Objects rule to compile source targets.

    Library Rule

    The Library rule compiles source files, archives the resulting object files into a library, and then deletes the object files. For example:
                  Library libstring : strcmp.c strcpy.c strlen.c ;
                  Library libtree : treemake.c treetrav.c ;
    
    This compiles five source files, archives three of the object files into libstring and the other two into libtree. Actual library filenames are formed with the $(SUFLIB) suffix. Once the objects are safely in the libraries, the objects are deleted.

    Library uses the Objects rule to compile source files.

    LinkLibraries Rule

    To link executables with built libraries, use the LinkLibraries rule. For example:
                  Main myprog : main.c util.c ;
                  LinkLibraries myprog : libstring libtree ;
    
    The LinkLibraries rule does two things: it makes the libraries dependencies of the executable, so that they get built first; and it makes the libraries show up on the command line that links the executable. The ordering of the lines above is not important, because jam builds targets in the order that they are needed.

    You can put multiple libraries on a single invocation of the LinkLibraries rule, or you can provide them in multiple invocations. In both cases, the libraries appear on the link command line in the order in which they were encountered. You can also provide multiple executables to the LinkLibraries rule, if they need the same libraries, e.g.:

    		LinkLibraries prog1 prog2 prog3 : libstring libtree ;
           

    Variables Used in Building Executables and Libraries

    AR Archive command, used for Library targets.
    SUFEXE *Suffix on filenames of executables referenced by Main and LinkLibraries.
    LINK Link command, used for Main targets.
    LINKFLAGS Linker flags.
    LINKLIBS Link libraries that aren't dependencies. (See note below.)
    EXEMODE *File permissions on Main targets.
    MODE Target-specific file permissions on Main targets (set from $(EXEMODE))
    RANLIB Name of ranlib program, if any.

    Variables above marked with "*" are used by the Main, Library, and LinkLibraries rules. Their values at the time the rules are invoked are used to set target-specific variables.

    All other variables listed above are globally defined, and are used in actions that update Main and Library targets. This means that the global values of those variables are used, uness target-specific values have been set. (For instance, a target-specific MODE value is set by the Main rule.) The target-specific values always override global values.

    Note that there are two ways to specify link libraries for executables:

    • Use the LinkLibraries rule to specify built libraries; i.e., libraries that are built by Library rules. This assures that these libraries are built first, and that Main targets are rebuilt when the libraries are updated.

    • Use the LINKLIBS variable to specify external libraries; e.g., system libraries or third-party libraries. The LINKLIBS variable must be set to the the actual link command flag that specifies the libraries.

    For example:

    	#In Jamrules:
                  if $(UNIX) { X11LINKLIBS = -lXext -lX11 ; }
                  if $(NT)   { X11LINKLIBS = libext.lib libX11.lib ; }
    
    	#In Jamfile:
                  Main xprog : xprog.c ;
                  LINKLIBS on xprog$(SUFEXE) = $(X11LINKLIBS) ;
                  LinkLibraries xprog : libxutil ;
                  Library libxutil : xtop.c xbottom.c xutil.c ;
    
    This example uses the Jam syntax "variable on target" to set a target-specific variable. In this way, only xprog will be linked with this special $(X11LINKLIBS), even if other executables were going to be built by the same Jamfile. Note that when you set a variable on a target, you have to specify the target identifer exactly, which in this case is the suffixed filename of the executable. The actual link command line on Unix, for example, would look something like this:
                  cc -o xprog xprog.o libxutil.a -lXext -lX11
    

    Compiling

    Compiling of source files occurs normally as a byproduct of the Main or Library rules, which call the rules described here. These rules may also be called explicitly if the Main and Library behavior doesn't satisfy your requirements.

    Objects Rule

    The Main and Library rules call the Objects rule on source files. Compiled object files built by the Objects rule are a dependency of the obj pseudotarget, so "jam obj" will build object files used in Main and Library rules.

    Target identifiers created by the Objects rule have grist set to $(SOURCE_GRIST). So given this Jamfile:

    		SubDir TOP src lock ;
    		Main locker : lock.c ;
           
    the object file created is lock.o (or lock.obj) and its target identifier is <src!lock>lock.o (or <src!lock>lock.obj).

    You can also call Objects directly. For example:

                  Objects a.c b.c c.c ;
    
    This compiles a.c into a.o, b.c into b.o, etc. The object file suffix is supplied by the Objects rule.

    Object Rule

    Objects gets its work done by calling the Object rule on each of the source files. You could use the Object rule directly. For example, on Unix, you could use:
                  Object foo.o : foo.c ;
    
    However, the Object rule does not provide suffixes, and it does not provide the grist needed to construct target identifiers if you are using the SubDir* rules. A portable and robust Jamfile would need to invoke Object thus:
    	      Object <src!util>foo$(SUFOBJ) : <src!util>foo.c ;
    	
    which is inelegant and clearly shows why using Objects is better than using Object.

    If there's any advantage to the Object rule, it's that it doesn't require that the object name bear any relationship to the source. It is thus possible to compile the same file into different objects. For example:

                  Object a.o : foo.c ;
                  Object b.o : foo.c ;
                  Object c.o : foo.c ;
    
    This compiles foo.c (three times) into a.o, b.o, and c.o. Later examples show how this is useful.

    The Object rule looks at the suffix of the source file and calls the appropriate rules to do the actual preprocessing (if any) and compiling needed to produce the output object file. The Object rule is capable of the generating of an object file from any type of source. For example:

                  Object grammar$(SUFOBJ) : grammar.y ;
                  Object scanner$(SUFOBJ) : scanner.l ;
                  Object fastf$(SUFOBJ) : fastf.f ;
                  Object util$(SUFOBJ) : util.c ;
    
    An even more elegant way to get the same result is to let the Objects rule call Object:
                  Objects grammar.y scanner.l fastf.f util.c ;
    	

    In addition to calling the compile rules, Object sets up a bunch of variables specific to the source and target files. (See Variables Used in Compiling, below.)

    Cc, C++, Yacc, Lex, Fortran, As, etc. Rules

    The Object rule calls compile rules specific to the suffix of the source file. (You can see which suffixes are supported by looking at the Object rule definition in Jambase.) Because the extra work done by the Object rule, it is not always useful to call the compile rules directly. But the adventurous user might attempt it. For example:

                  Yacc grammar.c : grammar.y ;
                  Lex scan.c : scan.l ;
                  Cc prog.o : prog.c ;
    
    These examples individually run yacc(1), lex(1), and the C compiler on their sources.

    UserObject Rule

    Any files with suffixes not understood by the Object rule are passed to the UserObject rule. The default definition of UserObject simply emits a warning that the suffix is not understood. This Jambase rule definition is intended to be overridden in Jamrules with one that recognizes the project-specific source file suffixes. For example:
    	#In Jamrules:
    
                  rule UserObject
                  {
                      switch $(>)
                      {
                      case *.rc   : ResourceCompiler $(<) : $(>) ;
                      case *      : ECHO "unknown suffix on" $(>) ;
                      }
                  }
    
                  rule ResourceCompiler
                  {
                      DEPENDS $(<) : $(>) ;
    		  Clean clean : $(<) ;
                  }
    
                  actions ResourceCompiler
                  {
                      rc /fo $(<) $(RCFLAGS) $(>)
                  }
    
    
    	#In Jamfile:
    
                  Library liblock : lockmgr.c ;
    	      if $(NT) { Library liblock : lock.rc ; }
    

    In this example, the UserObject definition in Jamrules allows *.rc files to be handle as regular Main and Library sources. The lock.rc file is compiled into lock.obj by the "rc" command, and lock.obj is archived into a library with other compiled objects.

    LibraryFromObjects Rule

    Sometimes the Library rule's straightforward compiling of source into object modules to be archived isn't flexible enough. The LibraryFromObjects rule does the archiving (and deleting) job of the Library rule, but not the compiling. The user can make use of the Objects or Object rule for that. For example:
                  LibraryFromObjects libfoo.a : max.o min.o ;
                  Object max.o : maxmin.c ;
                  Object min.o : maxmin.c ;
                  ObjectCcFlags max.o : -DUSEMAX ;
                  ObjectCcFlags min.o : -DUSEMIN ;
    
    This Unix-specific example compiles the same source file into two different objects, with different compile flags, and archives them. (The ObjectCcFlags rule is described shortly.) Unfortunately, the portable and robust implementation of the above example is not as pleasant to read:
    	      SubDir TOP foo bar ;
                  LibraryFromObjects libfoo$(SUFLIB) : <foo!bar>max$(SUFOBJ) 
    			                           <foo!bar>min$(SUFOBJ) ;
                  Object <foo!bar>min$(SUFOBJ) : <foo!bar>maxmin.c ;
                  Object <foo!bar>max$(SUFOBJ) : <foo!bar>maxmin.c ;
    	      ObjectCcFlags <foo!bar>min$(SUFOBJ) : -DUSEMIN ;
    	      ObjectCcFlags <foo!bar>max$(SUFOBJ) : -DUSEMAX ;
           
    Note that, among other things, you must supply the library file suffix when using the LibraryFromObjects rule.

    MainFromObjects Rule

    Similar to LibraryFromObjects, MainFromObjects does the linking part of the Main rule, but not the compiling. MainFromObjects can be used when there are no objects at all, and everything is to be loaded from libraries. For example:
                  MainFromObjects testprog ;
                  LinkLibraries testprog : libprog ;
                  Library libprog : main.c util.c ;
    
    On Unix, say, this generates a link command that looks like:
                  cc -o testprog libprog.a
    
    Linking purely from libraries is something that doesn't work everywhere: it depends on the symbol "main" being undefined when the linker encounters the library that contains the definition of "main".

    Variables Used in Compiling

    The following variables control the compiling of source files:

    C++ The C++ compiler command
    CC The C compiler command
    C++FLAGS
    CCFLAGS
    Compile flags, used to create or update compiled objects
    SUBDIRC++FLAGS
    SUBDIRCCFLAGS
    Additonal compile flags for source files in this directory.
    OPTIM Compiler optimization flag. The Cc and C++ actions use this as well as C++FLAGS or CCFLAGS.
    HDRS Non-standard header directories; i.e., the directories the compiler will not look in by default and which therefore must be supplied to the compile command. These directories are also used by jam to scan for include files.
    STDHDRS Standard header directories, i.e., the directories the compiler searches automatically. These are not passed to the compiler, but they are used by jam to scan for include files.
    SUBDIRHDRS Additional paths to add to HDRS for source files in this directory.
    LEX The lex(1) command
    YACC The yacc(1) command

    The Cc rule sets a target-specific $(CCFLAGS) to the current value of $(CCFLAGS) and $(SUBDIRCCFLAGS). Similarly for the C++ rule. The Object rule sets a target-specific $(HDRS) to the current value of $(HDRS) and $(SUBDDIRHDRS).

    $(CC), $(C++), $(CCFLAGS), $(C++FLAGS), $(OPTIM), and $(HDRS) all affect the compiling of C and C++ files. $(OPTIM) is separate from $(CCFLAGS) and $(C++FLAGS) so they can be set independently.

    $(HDRS) lists the directories to search for header files, and it is used in two ways: first, it is passed to the C compiler (with the flag -I prepended); second, it is used by HdrRule to locate the header files whose names were found when scanning source files. $(STDHDRS) lists the header directories that the C compiler already knows about. It does not need passing to the C compiler, but is used by HdrRule.

    Note that these variables, if set as target-specific variables, must be set on the target, not the source file. The target file in this case is the object file to be generated. For example:

                  Library libximage : xtiff.c xjpeg.c xgif.c ;
    
                  HDRS on xjpeg$(SUFOBJ) = /usr/local/src/jpeg ;
                  CCFLAGS on xtiff$(SUFOBJ) = -DHAVE_TIFF ;
    
    This can be done more easily with the rules that follow.

    ObjectCcFlags, ObjectC++Flags, ObjectHdrs Rules

    $(CCFLAGS), $(C++FLAGS) and $(HDRS) can be set on object file targets directly, but there are rules that allow these variables to be set by referring to the original source file name, rather than to the derived object file name. ObjectCcFlags adds object-specific flags to the $(CCFLAGS) variable, ObjectC++Flags adds object-specific flags to the $(C++FLAGS) variable, and ObjectHdrs add object-specific directories to the $(HDRS) variable. For example:
    	#In Jamrules:
    		if $(NT) { CCFLAGS_X = /DXVERSION ;	
    			   HDRS_X = \\\\SPARKY\\X11\\INCLUDE\\X11 ;
    		         }
    
    	#In Jamfile:
                  Main xviewer : viewer.c ;
                  ObjectCcFlags viewer.c : $(CCFLAGS_X) ;
                  ObjectHdrs viewer.c : $(HDRS_X) ;
    
    The ObjectCcFlags and ObjectHdrs rules take .c files as targets, but actually set $(CCFLAGS) and $(HDRS) values on the .obj (or .o) files. As a result, the action that updates the target .obj file uses the target-specific values of $(CCFLAGS) and $(HDRS).

    SubDirCcFlags, SubDirC++Flags, SubDirHdrs Rules

    These rules set the values of $(SUBDIRCCFLAGS), $(SUBDIRC++FLAGS) and $(SUBDIRHDRS), which are used by the Cc, C++, and Object rules when setting the target-specific values for $(CCFLAGS), $(C++FLAGS) and $(HDRS). The SubDir rule clears these variables out, and thus they provide directory-specific values of $(CCFLAGS), $(C++FLAGS) and $(HDRS). For example:
    	#In Jamrules:
                  GZHDRS = $(TOP)/src/gz/include ;
    	      GZFLAG = -DGZ ;
    		
    	#In Jamfile:
                  SubDir TOP src gz utils ;
    
                  SubDirHdrs $(GZHDRS) ;
                  SubDirCcFlags $(GZFLAG) ;
    
    	      Library libgz : gizmo.c ;
    	      Main gizmo : main.c ;
    	      LinkLibraries gizmo : libgz ;
    
    All .c files in this directory files will be compiled with $(GZFLAG) as well as the default $(CCFLAG), and the include paths used on the compile command will be $(GZHDRS) as well as the default $(HDRS).

    Header File Processing

    One of the functions of the Object rule is set up scanning of source files for (C style) header file inclusions. To do so, it sets the special variables $(HDRSCAN) and $(HDRRULE) as target-specific variables on the source file. The presence of these variables triggers a special mechanism in jam for scanning a file for header file inclusions and invoking a rule with the results of the scan. The $(HDRSCAN) variable is set to an egrep(1) pattern that matches "#include" statements in C source files, and the $(HDRRULE) variable is set to the name of the rule that gets invoked as such:
                  $(HDRRULE) source-file : included-files ;
    
    This rule is supposed to set up the dependencies between the source file and the included files. The Object rule uses HdrRule to do the job. HdrRule itself expects another variable, $(HDRSEARCH), to be set to the list of directories where the included files can be found. Object does this as well, setting $(HDRSEARCH) to $(HDRS) and $(STDHDRS).

    The header file scanning occurs during the "file binding" phase of jam, which means that the target-specific variables (for the source file) are in effect. To accomodate nested includes, one of the HdrRule's jobs is to pass the target-specific values of $(HDRRULE), $(HDRSCAN), and $(HDRSEARCH) onto the included files, so that they will be scanned as well.

    HdrRule Rule

    Normally, HdrRule is not invoked directly; the Object rule (called by Main and Library) invokes it.

    If there are special dependencies that need to be set, and which are not set by HdrRule itself, you can define another rule and let it invoke HdrRule. For example:

    	#In Jamrules:
                  rule BuiltHeaders
                  {
                          DEPENDS $(>) : mkhdr$(SUFEXE) ;
                          HdrRule $(<) : $(>) ;
                  }
    
    	#In Jamfile:
                  Main mkhdr : mkhdr.c ;
                  Main ugly : ugly.c ;
    
                  HDRRULE on ugly.c = BuiltHeaders ;
    
    
    This example just says that the files included by "ugly.c" are generated by the program "mkhdr", which can be built from "mkhdr.c". During the binding phase, jam will scan ugly.c, and if it finds an include file, ughdr.h, for example, it will automatically invoke the rule:
                  BuiltHeaders ugly.c : ughdr.h ;
           
    By calling HdrRule at the end of BuiltHeaders, all the gadgetry of HdrRule takes effect and it doesn't need to be duplicated.

    Variables Used for Header Scanning

    HDRPATTERN Default scan pattern for "include" lines.
    HDRSCAN Scan pattern to use. This is a special variable: during binding, if both HDRSCAN and HDRRULE are set, scanning is activated on the target being bound. The HdrRule and Object rules sets this to $(HDRPATTERN) on their source targets.
    HDRRULE Name of rule to invoked on files found in header scan. The HdrRule and Object rules set this to "HdrRule" on their source targets. This is also a special variable; it's the only jam variable that can hold the name of a rule to be invoked.
    HDRSEARCH Search paths for files found during header scanning. This is set from $(HDRS) and $(STDHDRS), which are described in the Compiling section. jam will search $(HDRSEARCH) directories for the files found by header scans.

    The Object rule sets HDRRULE and HDRSCAN specifically for the source files to be scanned, rather than globally. If they were set globally, jam would attempt to scan all files, even library archives and executables, for header file inclusions. That would be slow and probably not yield desirable results.

    Copying Files

    File Rule

    The File rule copies one file to another. The target name needn't be the same as the source name. For example:
    	switch $(OS)
    	{
               case NT*  : File config.h : confignt.h ;
    	   case *    : File config.h : configunix.h ;
    	}
    	LOCATE on config.h = $(LOCATE_SOURCE) ;
    
    This creates a config.h file from either confignt.h or configunix.h, depending on the current build platform.

    The File rule does not use the LOCATE_SOURCE variable set by the SubDir rule (although it does use SEARCH_SOURCE), which means you have to set the copied file's output directory yourself. That's done by setting the special LOCATE variable on the target, as shown above, or with the MakeLocate rule described below.

    Bulk Rule

    The Bulk rule is a shorthand for many invocations of the File rule when all files are going to the same directory. For example:
    	#In Jamrules:
                  DISTRIB_GROB = d:\\distrib\\grob ;
    
    	#In Jamfile:
                  Bulk $(DISTRIB_GROB) : grobvals.txt grobvars.txt ;
    
    This causes gobvals.txt and grobvars.txt to be copied into the $(DISTRIB_GROB) directory.

    HardLink Rule

    The Unix-only HardLink rule makes a hard link (using ln(1)) from the source to the target, if there isn't one already. For example:
                  HardLink config.h : configunix.h ;
    

    Shell Rule

    The Shell rule is like the File rule, except that on Unix it makes sure the first line of the target is "#!/bin/sh" and sets the permission to make the file executable. For example:
                  Shell /usr/local/bin/add : add.sh ;
    

    You can also use $(SHELLHEADER) to dictate what the first line of the copied file will be. For example:

                  Shell /usr/local/bin/add : add.awk ;
                  SHELLHEADER on /usr/local/bin/add = "#!/bin/awk -f" ;
    
    This installs an awk(1) script.

    Variables Used When Copying Files

    FILEMODE Default file permissions for copied files
    SHELLMODE Default file permissions for Shell rule targets
    MODE File permissions set on files copied by File, Bulk, and Shell rules. File and Shell sets a target-specific MODE to the current value of $(FILEMODE) or $(SHELLMODE), respectively.
    SHELLHEADER String to write in first line of Shell targets (default is #!/bin/sh).

    Installing Files

    Jambase provides a set of Install* rules to copy files into an destination directory and set permissions on them. On Unix, the install(1) program is used. If the destination directory does not exist, jam creates it first.

    All files copied with the Install* rules are dependencies of the install pseudotarget, which means that the command "jam install" will cause the installed copies to be updated. Also, "jam uninstall" will cause the installed copies to be removed.

    The Install* rules are:

    InstallBin Copies file and sets its permission to $(EXEMODE). You must specify the suffixed executable name. E.g.:
    InstallBin $(BINDIR) : thing$(SUFEXE) ;
    		   
    InstallFile Copies file and sets its permission to $(FILEMODE). E.g.:
    InstallFile $(DESTDIR) : readme.txt ;
    		   
    InstallLib Copies file and sets its permission to $(FILEMODE). You must specify the suffixed library name. E.g.:
    InstallLib $(LIBDIR) : libzoo$(SUFLIB) ;
    		   
    InstallMan Copies file into the mann subdirectory of the target directory and sets its permission to $(FILEMODE). E.g., this copies foo.5 into the $(DESTDIR)/man5 directory:
    InstallMan $(DESTDIR) : foo.5 ;
    		   
    InstallShell Copies file and sets its permission to $(SHELLMODE). E.g.:
    InstallShell $(DESTDIR) : startup ;
    		   

    Variables

    The following variables control the installation rules:

    INSTALL The install program (Unix only)
    FILEMODE Default file permissions on readable files.
    EXEMODE Default file permission executable files.
    SHELLMODE Default file permission on shell script files.
    MODE Target-specific file permissions

    The Install rules set a target-specific MODE to the current value of $(FILEMODE), $(EXEMODE), or $(SHELLMODE), depending on which Install rule was invoked.

    The directory variables are just defined for convenience: they must be passed as the target to the appropriate Install rule. The $(INSTALL) and mode variables must be set (globally) before calling the Install rules in order to take effect.

    Miscellaneous Rules

    Clean Rule

    The Clean rule defines files to be removed when you run "jam clean". Any site-specific build rules defined in your Jamrules should invoke Clean so that outputs can be removed. E.g.,

    	rule ResourceCompiler
    	{
    	   DEPENDS $(<) : $(>) ;
    	   Clean clean : $(<) ;
    	}
    

    Most Jambase rules invoke the Clean rule on their built targets, so "jam clean" will remove all compiled objects, libraries, executables, etc.

    MakeLocate Rule

    MakeLocate is a single convenient rule that creates a directory, sets LOCATE on a target to that directory, and makes the directory a dependency of the target. It is used by many Jambase rules, and can be invoked directly, e.g.:
    		GenFile data.tbl : hxtract data.h ;
    		MakeLocate data.tbl : $(TABLEDIR) ;
          
    In this example, the File rule creates data.tbl from data.h. The MakeLocate causes data.tbl to be written into the $(TABLEDIR) directory; and if the directory doesn't exist, it is created first.

    The MakeLocate rule invokes another Jambase rule, MkDir, to (recursively) create directories. MkDir uses the $(MKDIR) variable to determine the platform-specific command that creates directories.

    RmTemps Rule

    Some intermediate files are meant to be temporary. The RmTemps rule can be used to cause jam to delete them after they are used.

    RmTemps must be:

    • the last rule invoked on the permanent file that uses the temporary file(s)
    • invoked with the permanent file as the output target and the temporary file(s) as the input target
    • invoked with the exact target identifiers of the permanent file and the temporary file(s)
    For example:
    		SubDir TOP src big ;
    		GenFile big.y : joinfiles part1.y part2.y part3.y ;
    		Main bigworld : main.c big.y ;
    		RmTemps bigworld$(SUFEXE) : <src!big>big.y ;
    	
    This causes big.y to be deleted after it has been used to create the bigworld executable. The exact target identifier of big.y is <src!big>big.y (the GenFile and Main rules tack on the grist automatically); the exact target identifier of the bigworld executable is bigworld$(SUFEXE).


    Back to top.

    Copyright 1997, 2000 Perforce Software, Inc.
    Comments to info@perforce.com
    Last updated: Dec 31, 2000
    $Id: //public/jam/src/Jamfile.html#6 $ ftjam-2.5.2/builtins.c0000744000424500003730000002010210441006342014376 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * builtins.c - builtin jam rules * * External routines: * * load_builtin() - define builtin rules * * Internal routines: * * builtin_depends() - DEPENDS/INCLUDES rule * builtin_echo() - ECHO rule * builtin_exit() - EXIT rule * builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule * builtin_glob() - GLOB rule * builtin_match() - MATCH rule * builtin_hdrmacro() - HDRMACRO rule * * 01/10/01 (seiwald) - split from compile.c * 01/08/01 (seiwald) - new 'Glob' (file expansion) builtin * 03/02/02 (seiwald) - new 'Match' (regexp match) builtin * 04/03/02 (seiwald) - Glob matches only filename, not directory * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 10/22/02 (seiwald) - working return/break/continue statements * 11/04/02 (seiwald) - const-ing for string literals * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET */ # include "jam.h" # include "lists.h" # include "parse.h" # include "builtins.h" # include "rules.h" # include "filesys.h" # include "newstr.h" # include "regexp.h" # include "pathsys.h" # include "hdrmacro.h" /* * compile_builtin() - define builtin rules */ # define P0 (PARSE *)0 # define C0 (char *)0 LIST *builtin_depends( PARSE *parse, LOL *args, int *jmp ); LIST *builtin_echo( PARSE *parse, LOL *args, int *jmp ); LIST *builtin_exit( PARSE *parse, LOL *args, int *jmp ); LIST *builtin_flags( PARSE *parse, LOL *args, int *jmp ); LIST *builtin_glob( PARSE *parse, LOL *args, int *jmp ); LIST *builtin_match( PARSE *parse, LOL *args, int *jmp ); LIST *builtin_hdrmacro( PARSE *parse, LOL *args, int *jmp ); int glob( const char *s, const char *c ); void load_builtins() { bindrule( "Always" )->procedure = bindrule( "ALWAYS" )->procedure = parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_TOUCHED ); bindrule( "Depends" )->procedure = bindrule( "DEPENDS" )->procedure = parse_make( builtin_depends, P0, P0, P0, C0, C0, 0 ); bindrule( "echo" )->procedure = bindrule( "Echo" )->procedure = bindrule( "ECHO" )->procedure = parse_make( builtin_echo, P0, P0, P0, C0, C0, 0 ); bindrule( "exit" )->procedure = bindrule( "Exit" )->procedure = bindrule( "EXIT" )->procedure = parse_make( builtin_exit, P0, P0, P0, C0, C0, 0 ); bindrule( "Glob" )->procedure = bindrule( "GLOB" )->procedure = parse_make( builtin_glob, P0, P0, P0, C0, C0, 0 ); bindrule( "Includes" )->procedure = bindrule( "INCLUDES" )->procedure = parse_make( builtin_depends, P0, P0, P0, C0, C0, 1 ); bindrule( "Leaves" )->procedure = bindrule( "LEAVES" )->procedure = parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_LEAVES ); bindrule( "Match" )->procedure = bindrule( "MATCH" )->procedure = parse_make( builtin_match, P0, P0, P0, C0, C0, 0 ); bindrule( "NoCare" )->procedure = bindrule( "NOCARE" )->procedure = parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_NOCARE ); bindrule( "NOTIME" )->procedure = bindrule( "NotFile" )->procedure = bindrule( "NOTFILE" )->procedure = parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_NOTFILE ); bindrule( "NoUpdate" )->procedure = bindrule( "NOUPDATE" )->procedure = parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_NOUPDATE ); bindrule( "Temporary" )->procedure = bindrule( "TEMPORARY" )->procedure = parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_TEMP ); bindrule( "HdrMacro" )->procedure = bindrule( "HDRMACRO" )->procedure = parse_make( builtin_hdrmacro, P0, P0, P0, C0, C0, 0 ); } /* * builtin_depends() - DEPENDS/INCLUDES rule * * The DEPENDS builtin rule appends each of the listed sources on the * dependency list of each of the listed targets. It binds both the * targets and sources as TARGETs. */ LIST * builtin_depends( PARSE *parse, LOL *args, int *jmp ) { LIST *targets = lol_get( args, 0 ); LIST *sources = lol_get( args, 1 ); int which = parse->num; LIST *l; for( l = targets; l; l = list_next( l ) ) { TARGET *t = bindtarget( l->string ); /* If doing INCLUDES, switch to the TARGET's include */ /* TARGET, creating it if needed. The internal include */ /* TARGET shares the name of its parent. */ if( parse->num ) { if( !t->includes ) t->includes = copytarget( t ); t = t->includes; } t->depends = targetlist( t->depends, sources ); } return L0; } /* * builtin_echo() - ECHO rule * * The ECHO builtin rule echoes the targets to the user. No other * actions are taken. */ LIST * builtin_echo( PARSE *parse, LOL *args, int *jmp ) { list_print( lol_get( args, 0 ) ); printf( "\n" ); return L0; } /* * builtin_exit() - EXIT rule * * The EXIT builtin rule echoes the targets to the user and exits * the program with a failure status. */ LIST * builtin_exit( PARSE *parse, LOL *args, int *jmp ) { list_print( lol_get( args, 0 ) ); printf( "\n" ); exit( EXITBAD ); /* yeech */ return L0; } /* * builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule * * Builtin_flags() marks the target with the appropriate flag, for use * by make0(). It binds each target as a TARGET. */ LIST * builtin_flags( PARSE *parse, LOL *args, int *jmp ) { LIST *l = lol_get( args, 0 ); for( ; l; l = list_next( l ) ) bindtarget( l->string )->flags |= parse->num; return L0; } /* * builtin_globbing() - GLOB rule */ struct globbing { LIST *patterns; LIST *results; } ; static void builtin_glob_back( void *closure, const char *file, int status, time_t time ) { struct globbing *globbing = (struct globbing *)closure; LIST *l; PATHNAME f; char buf[ MAXJPATH ]; /* Null out directory for matching. */ /* We wish we had file_dirscan() pass up a PATHNAME. */ path_parse( file, &f ); f.f_dir.len = 0; path_build( &f, buf, 0 ); for( l = globbing->patterns; l; l = l->next ) if( !glob( l->string, buf ) ) { globbing->results = list_new( globbing->results, file, 0 ); break; } } LIST * builtin_glob( PARSE *parse, LOL *args, int *jmp ) { LIST *l = lol_get( args, 0 ); LIST *r = lol_get( args, 1 ); struct globbing globbing; globbing.results = L0; globbing.patterns = r; for( ; l; l = list_next( l ) ) file_dirscan( l->string, builtin_glob_back, &globbing ); return globbing.results; } /* * builtin_match() - MATCH rule, regexp matching */ LIST * builtin_match( PARSE *parse, LOL *args, int *jmp ) { LIST *l, *r; LIST *result = 0; /* For each pattern */ for( l = lol_get( args, 0 ); l; l = l->next ) { regexp *re = regcomp( l->string ); /* For each string to match against */ for( r = lol_get( args, 1 ); r; r = r->next ) if( regexec( re, r->string ) ) { int i, top; /* Find highest parameter */ for( top = NSUBEXP; top-- > 1; ) if( re->startp[top] ) break; /* And add all parameters up to highest onto list. */ /* Must have parameters to have results! */ for( i = 1; i <= top; i++ ) { char buf[ MAXSYM ]; int l = re->endp[i] - re->startp[i]; memcpy( buf, re->startp[i], l ); buf[ l ] = 0; result = list_new( result, buf, 0 ); } } free( (char *)re ); } return result; } LIST * builtin_hdrmacro( PARSE *parse, LOL *args, int *jmp ) { LIST* l = lol_get( args, 0 ); for ( ; l; l = list_next(l) ) { TARGET* t = bindtarget( l->string ); /* scan file for header filename macro definitions */ if ( DEBUG_HEADER ) printf( "scanning '%s' for header file macro definitions\n", l->string ); macro_headers( t ); } return L0; } ftjam-2.5.2/mkjambase.c0000744000424500003730000000437310441006342014513 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * mkjambase.c - turn Jambase into a big C structure * * Usage: mkjambase jambase.c Jambase ... * * Results look like this: * * char *jambase[] = { * "...\n", * ... * 0 }; * * Handles \'s and "'s specially; knows to delete blank and comment lines. * * 11/04/02 (seiwald) - const-ing for string literals */ # include # include main( int argc, char **argv, char **envp ) { char buf[ 1024 ]; FILE *fin; FILE *fout; char *p; int doDotC = 0; if( argc < 3 ) { fprintf( stderr, "usage: %s jambase.c Jambase ...\n", argv[0] ); return -1; } if( !( fout = fopen( argv[1], "w" ) ) ) { perror( argv[1] ); return -1; } /* If the file ends in .c generate a C source file */ if( ( p = strrchr( argv[1], '.' ) ) && !strcmp( p, ".c" ) ) doDotC++; /* Now process the files */ argc -= 2, argv += 2; if( doDotC ) { fprintf( fout, "/* Generated by mkjambase from Jambase */\n" ); fprintf( fout, "const char *jambase[] = {\n" ); } for( ; argc--; argv++ ) { if( !( fin = fopen( *argv, "r" ) ) ) { perror( *argv ); return -1; } if( doDotC ) { fprintf( fout, "/* %s */\n", *argv ); } else { fprintf( fout, "### %s ###\n", *argv ); } while( fgets( buf, sizeof( buf ), fin ) ) { if( doDotC ) { char *p = buf; /* Strip leading whitespace. */ while( *p == ' ' || *p == '\t' || *p == '\n' ) p++; /* Drop comments and empty lines. */ if( *p == '#' || !*p ) continue; /* Copy */ putc( '"', fout ); for( ; *p && *p != '\n' && *p != '\r'; p++ ) switch( *p ) { case '\\': putc( '\\', fout ); putc( '\\', fout ); break; case '"': putc( '\\', fout ); putc( '"', fout ); break; default: putc( *p, fout ); break; } fprintf( fout, "\\n\",\n" ); } else { fprintf( fout, "%s", buf ); } } fclose( fin ); } if( doDotC ) fprintf( fout, "0 };\n" ); fclose( fout ); return 0; } ftjam-2.5.2/Build.com0000744000424500003730000000207410441006342014150 0ustar dturnermhpsys! Bootstrap build script for Jam $ cxx /define=VMS builtins.c $ cxx /define=VMS command.c $ cxx /define=VMS compile.c $ cxx /define=VMS expand.c $ cxx /define=VMS execvms.c $ cxx /define=VMS filevms.c $ cxx /define=VMS glob.c $ cxx /define=VMS hash.c $ cxx /define=VMS headers.c $ cxx /define=VMS jambase.c $ cxx /define=VMS lists.c $ cxx /define=VMS make.c $ cxx /define=VMS make1.c $ cxx /define=VMS newstr.c $ cxx /define=VMS option.c $ cxx /define=VMS parse.c $ cxx /define=VMS pathvms.c $ cxx /define=VMS regexp.c $ cxx /define=VMS rules.c $ cxx /define=VMS scan.c $ cxx /define=VMS search.c $ cxx /define=VMS timestamp.c $ cxx /define=VMS variable.c $ cxx /define=VMS jam.c $ cxx /define=VMS jamgram.c $ cxxlink/exe=jam.exe command.obj, compile.obj, execvms.obj, expand.obj, - filevms.obj, glob.obj, hash.obj, headers.obj, lists.obj, make.obj, - make1.obj, newstr.obj, option.obj, parse.obj, pathvms.obj, regexp.obj, - rules.obj, scan.obj, search.obj, timestamp.obj, variable.obj, jam.obj, - jamgram.obj, jambase.obj, builtins.obj ftjam-2.5.2/compile.h0000744000424500003730000000457310441006343014221 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * compile.h - compile parsed jam statements * * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() * 01/24/01 (seiwald) - 'while' statement * 03/02/02 (seiwald) - rules can be invoked via variable names * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx * 10/22/02 (seiwald) - working return/break/continue statements * 11/04/02 (seiwald) - const-ing for string literals */ void compile_builtins(); LIST *compile_append( PARSE *parse, LOL *args, int *jmp ); LIST *compile_break( PARSE *parse, LOL *args, int *jmp ); LIST *compile_foreach( PARSE *parse, LOL *args, int *jmp ); LIST *compile_if( PARSE *parse, LOL *args, int *jmp ); LIST *compile_eval( PARSE *parse, LOL *args, int *jmp ); LIST *compile_include( PARSE *parse, LOL *args, int *jmp ); LIST *compile_list( PARSE *parse, LOL *args, int *jmp ); LIST *compile_local( PARSE *parse, LOL *args, int *jmp ); LIST *compile_null( PARSE *parse, LOL *args, int *jmp ); LIST *compile_on( PARSE *parse, LOL *args, int *jmp ); LIST *compile_rule( PARSE *parse, LOL *args, int *jmp ); LIST *compile_rules( PARSE *parse, LOL *args, int *jmp ); LIST *compile_set( PARSE *parse, LOL *args, int *jmp ); LIST *compile_setcomp( PARSE *parse, LOL *args, int *jmp ); LIST *compile_setexec( PARSE *parse, LOL *args, int *jmp ); LIST *compile_settings( PARSE *parse, LOL *args, int *jmp ); LIST *compile_switch( PARSE *parse, LOL *args, int *jmp ); LIST *compile_while( PARSE *parse, LOL *args, int *jmp ); LIST *evaluate_rule( const char *rulename, LOL *args, LIST *result ); /* Conditions for compile_if() */ # define EXPR_NOT 0 /* ! cond */ # define EXPR_AND 1 /* cond && cond */ # define EXPR_OR 2 /* cond || cond */ # define EXPR_EXISTS 3 /* arg */ # define EXPR_EQUALS 4 /* arg = arg */ # define EXPR_NOTEQ 5 /* arg != arg */ # define EXPR_LESS 6 /* arg < arg */ # define EXPR_LESSEQ 7 /* arg <= arg */ # define EXPR_MORE 8 /* arg > arg */ # define EXPR_MOREEQ 9 /* arg >= arg */ # define EXPR_IN 10 /* arg in arg */ /* Flags for compile_return */ # define JMP_NONE 0 /* flow continues */ # define JMP_BREAK 1 /* break out of loop */ # define JMP_CONTINUE 2 /* step to end of loop */ # define JMP_RETURN 3 /* return from rule */ ftjam-2.5.2/builtins.h0000744000424500003730000000044010441006343014407 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * builtins.h - compile parsed jam statements * * 01/10/01 (seiwald) - split from compile.h */ void load_builtins(); ftjam-2.5.2/lists.c0000744000424500003730000001167210441006343013720 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * lists.c - maintain lists of strings * * This implementation essentially uses a singly linked list, but * guarantees that the head element of every list has a valid pointer * to the tail of the list, so the new elements can efficiently and * properly be appended to the end of a list. * * To avoid massive allocation, list_free() just tacks the whole freed * chain onto freelist and list_new() looks on freelist first for an * available list struct. list_free() does not free the strings in the * chain: it lazily lets list_new() do so. * * 08/23/94 (seiwald) - new list_append() * 09/07/00 (seiwald) - documented lol_*() functions * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 11/04/02 (seiwald) - const-ing for string literals * 12/09/02 (seiwald) - new list_printq() for writing lists to Jambase */ # include "jam.h" # include "newstr.h" # include "lists.h" static LIST *freelist = 0; /* junkpile for list_free() */ /* * list_append() - append a list onto another one, returning total */ LIST * list_append( LIST *l, LIST *nl ) { if( !nl ) { /* Just return l */ } else if( !l ) { l = nl; } else { /* Graft two non-empty lists. */ l->tail->next = nl; l->tail = nl->tail; } return l; } /* * list_new() - tack a string onto the end of a list of strings */ LIST * list_new( LIST *head, const char *string, int copy ) { LIST *l; if( DEBUG_LISTS ) printf( "list > %s <\n", string ); /* Copy/newstr as needed */ string = copy ? copystr( string ) : newstr( string ); /* Get list struct from freelist, if one available. */ /* Otherwise allocate. */ /* If from freelist, must free string first */ if( freelist ) { l = freelist; freestr( l->string ); freelist = freelist->next; } else { l = (LIST *)malloc( sizeof( *l ) ); } /* If first on chain, head points here. */ /* If adding to chain, tack us on. */ /* Tail must point to this new, last element. */ if( !head ) head = l; else head->tail->next = l; head->tail = l; l->next = 0; l->string = string; return head; } /* * list_copy() - copy a whole list of strings (nl) onto end of another (l) */ LIST * list_copy( LIST *l, LIST *nl ) { for( ; nl; nl = list_next( nl ) ) l = list_new( l, nl->string, 1 ); return l; } /* * list_sublist() - copy a subset of a list of strings */ LIST * list_sublist( LIST *l, int start, int count ) { LIST *nl = 0; for( ; l && start--; l = list_next( l ) ) ; for( ; l && count--; l = list_next( l ) ) nl = list_new( nl, l->string, 1 ); return nl; } /* * list_free() - free a list of strings */ void list_free( LIST *head ) { /* Just tack onto freelist. */ if( head ) { head->tail->next = freelist; freelist = head; } } /* * list_print() - print a list of strings to stdout */ void list_print( LIST *l ) { for( ; l; l = list_next( l ) ) printf( "%s ", l->string ); } /* * list_printq() - print a list of safely quoted strings to a file */ void list_printq( FILE *out, LIST *l ) { /* Dump each word, enclosed in "s */ /* Suitable for Jambase use. */ for( ; l; l = list_next( l ) ) { const char *p = l->string; const char *ep = p + strlen( p ); const char *op = p; fputc( '\n', out ); fputc( '\t', out ); fputc( '"', out ); /* Any embedded "'s? Escape them */ while( p = (char *)memchr( op, '"', ep - op ) ) { fwrite( op, p - op, 1, out ); fputc( '\\', out ); fputc( '"', out ); op = p + 1; } /* Write remainder */ fwrite( op, ep - op, 1, out ); fputc( '"', out ); fputc( ' ', out ); } } /* * list_length() - return the number of items in the list */ int list_length( LIST *l ) { int n = 0; for( ; l; l = list_next( l ), ++n ) ; return n; } /* * lol_init() - initialize a LOL (list of lists) */ void lol_init( LOL *lol ) { lol->count = 0; } /* * lol_add() - append a LIST onto an LOL */ void lol_add( LOL *lol, LIST *l ) { if( lol->count < LOL_MAX ) lol->list[ lol->count++ ] = l; } /* * lol_free() - free the LOL and its LISTs */ void lol_free( LOL *lol ) { int i; for( i = 0; i < lol->count; i++ ) list_free( lol->list[i] ); lol->count = 0; } /* * lol_get() - return one of the LISTs in the LOL */ LIST * lol_get( LOL *lol, int i ) { return i < lol->count ? lol->list[i] : 0; } /* * lol_print() - debug print LISTS separated by ":" */ void lol_print( LOL *lol ) { int i; for( i = 0; i < lol->count; i++ ) { if( i ) printf( " : " ); list_print( lol->list[i] ); } } ftjam-2.5.2/pathsys.h0000744000424500003730000000241010441006344014251 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * pathsys.h - PATHNAME struct * * 11/04/02 (seiwald) - const-ing for string literals */ /* * PATHNAME - a name of a file, broken into dir/base/suffix(member) * * is salt to distinguish between targets that otherwise would * have the same name: it never appears in the bound name of a target. * (member) is an archive member name: the syntax is arbitrary, but must * agree in path_parse(), path_build() and the Jambase. * * On VMS, we keep track of whether the original path was a directory * (without a file), so that $(VAR:D) can climb to the parent. */ typedef struct _pathname PATHNAME; typedef struct _pathpart PATHPART; struct _pathpart { const char *ptr; int len; }; struct _pathname { PATHPART part[6]; # ifdef OS_VMS int parent; # endif # define f_grist part[0] # define f_root part[1] # define f_dir part[2] # define f_base part[3] # define f_suffix part[4] # define f_member part[5] } ; void path_build( PATHNAME *f, char *file, int binding ); void path_parse( const char *file, PATHNAME *f ); void path_parent( PATHNAME *f ); ftjam-2.5.2/Jamrules0000744000424500003730000000010010441006344014104 0ustar dturnermhpsys# final binary installation directory BINDIR = /usr/local/bin ; ftjam-2.5.2/jambase.c0000744000424500003730000016042710441006344014170 0ustar dturnermhpsys/* Generated by mkjambase from Jambase */ const char *jambase[] = { /* Jambase */ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "JAMBASEDATE = 2004.10.07 ;\n", "\n", "\n", "\n", "if $(NT)\n", "{\n", "local SUPPORTED_TOOLSETS = BORLANDC\n", "VISUALC\n", "VISUALC16\n", "INTELC\n", "WATCOM\n", "MINGW\n", "LCC\n", "DIGITALMARS\n", "PELLESC\n", ";\n", "\n", "if $(JAM_TOOLSET)\n", "{\n", "if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS)\n", "{\n", "Echo \"The JAM_TOOLSET environment variable is defined but its value\" ;\n", "Echo \"is invalid, please use one of the following:\" ;\n", "Echo ;\n", "\n", "for t in $(SUPPORTED_TOOLSETS) { Echo \" \" $(t) ; }\n", "Exit ;\n", "}\n", "}\n", "\n", "if ! $(JAM_TOOLSET)\n", "{\n", "if $(BCCROOT)\n", "{\n", "JAM_TOOLSET = BORLANDC ;\n", "BORLANDC = $(BCCROOT) ;\n", "}\n", "else if $(MSVC)\n", "{\n", "JAM_TOOLSET = VISUALC16 ;\n", "VISUALC16 = $(MSVC) ;\n", "}\n", "else if $(MSVCNT)\n", "{\n", "JAM_TOOLSET = VISUALC ;\n", "VISUALC = $(MSVCNT) ;\n", "}\n", "else if $(MINGW)\n", "{\n", "JAM_TOOLSET = MINGW ;\n", "}\n", "else\n", "{\n", "Echo \"Jam cannot be run because you didn't indicate which compilation toolset\" ;\n", "Echo \"to use. To do so, define the JAM_TOOLSET environment variable with\" ;\n", "Echo \"one of the following values:\" ;\n", "Echo ;\n", "Echo \" Value Toolset Description\" ;\n", "Echo ;\n", "Echo \" BORLANDC Borland C++\" ;\n", "Echo \" VISUALC Microsoft Visual C++\" ;\n", "Echo \" VISUALC16 Microsoft Visual C++ 16 bit\" ;\n", "Echo \" INTELC Intel C/C++\" ;\n", "Echo \" WATCOM Watcom C/C++\" ;\n", "Echo \" MINGW MinGW (gcc)\" ;\n", "Echo \" LCC Win32-LCC\" ;\n", "Echo \" DIGITALMARS Digital Mars C/C++\" ;\n", "Echo \" PELLESC Pelles C\" ;\n", "Echo ;\n", "Echo \"The corresponding compiler must be in your path\" ;\n", "Echo ;\n", "Echo \" e.g.: set JAM_TOOLSET=VISUALC\" ;\n", "Exit ;\n", "}\n", "}\n", "\n", "MV ?= move /y ;\n", "CP ?= copy ;\n", "RM ?= del /f/q ;\n", "RMDIR ?= rmdir /s/q ;\n", "SLASH ?= \\\\ ;\n", "SUFLIB ?= .lib ;\n", "SUFOBJ ?= .obj ;\n", "SUFEXE ?= .exe ;\n", "\n", "SUFLIBSHR ?= .dll ;\n", "\n", "if $(JAM_TOOLSET) = BORLANDC\n", "{\n", "Echo \"Compiler is Borland C++\" ;\n", "\n", "AR ?= tlib /C /P64 ;\n", "CC ?= bcc32 ;\n", "CCFLAGS ?= -w- -q -DWIN -tWR -tWM -tWC ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= $(CCFLAGS) -P ;\n", "LINK ?= $(CC) ;\n", "ILINK ?= ilink32 -q ;\n", "IMPLIB ?= implib ;\n", "LINKFLAGS ?= $(CCFLAGS) ;\n", "STDLIBPATH ?= $(BORLANDC)\\\\lib ;\n", "STDHDRS ?= $(BORLANDC)\\\\include ;\n", "NOARSCAN ?= true ;\n", "ILINKLIBS ?= C0D32.OBJ CW32.LIB IMPORT32.LIB ;\n", "PICFLAGS ?= -tWD ;\n", "}\n", "else if $(JAM_TOOLSET) = VISUALC16\n", "{\n", "Echo \"Compiler is Microsoft Visual C++ 16 bit\" ;\n", "\n", "AR ?= lib /nologo ;\n", "CC ?= cl /nologo ;\n", "CCFLAGS ?= /D \"\\\"WIN\\\"\" ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "LINK ?= $(CC) ;\n", "LINKFLAGS ?= $(CCFLAGS) ;\n", "LINKLIBS ?=\n", "$(MSVC)\\\\lib\\\\mlibce.lib\n", "$(MSVC)\\\\lib\\\\oldnames.lib\n", ";\n", "LINKLIBS ?= ;\n", "NOARSCAN ?= true ;\n", "OPTIM ?= \"\" ;\n", "STDHDRS ?= $(VISUALC16)\\\\include ;\n", "UNDEFFLAG ?= \"/u _\" ;\n", "}\n", "else if $(JAM_TOOLSET) = VISUALC\n", "{\n", "\n", "MSVCNT ?= $(MSVCDIR) ;\n", "\n", "\n", "local I ; if $(OSPLAT) = IA64 { I = ia64\\\\ ; } else { I = \"\" ; }\n", "\n", "AR ?= lib ;\n", "AS ?= masm386 ;\n", "CC ?= cl /nologo ;\n", "CCFLAGS ?= \"\" ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "LINK ?= link /nologo ;\n", "LINKFLAGS ?= \"\" ;\n", "LINKLIBS ?=\n", "$(MSVCNT)\\\\lib\\\\$(I)libc.lib\n", "$(MSVCNT)\\\\lib\\\\$(I)oldnames.lib\n", "$(MSVCNT)\\\\lib\\\\$(I)kernel32.lib ;\n", "OPTIM ?= \"\" ;\n", "STDHDRS ?= $(VISUALC)\\\\include ;\n", "UNDEFFLAG ?= \"/u _\" ;\n", "}\n", "else if $(JAM_TOOLSET) = INTELC\n", "{\n", "Echo \"Compiler is Intel C/C++\" ;\n", "\n", "if ! $(VISUALC)\n", "{\n", "Echo \"As a special exception, when using the Intel C++ compiler, you need\" ;\n", "Echo \"to define the VISUALC environment variable to indicate the location\" ;\n", "Echo \"of your Visual C++ installation. Aborting..\" ;\n", "Exit ;\n", "}\n", "\n", "AR ?= lib ;\n", "AS ?= masm386 ;\n", "CC ?= icl /nologo ;\n", "CCFLAGS ?= \"\" ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "LINK ?= link /nologo ;\n", "LINKFLAGS ?= \"\" ;\n", "LINKLIBS ?= $(VISUALC)\\\\lib\\\\advapi32.lib\n", "$(VISUALC)\\\\lib\\\\libc.lib\n", "$(VISUALC)\\\\lib\\\\oldnames.lib\n", "$(VISUALC)\\\\lib\\\\kernel32.lib ;\n", "OPTIM ?= \"\" ;\n", "STDHDRS ?= $(INTELC)\\include $(VISUALC)\\\\include ;\n", "UNDEFFLAG ?= \"/u _\" ;\n", "}\n", "else if $(JAM_TOOLSET) = WATCOM\n", "{\n", "Echo \"Compiler is Watcom C/C++\" ;\n", "\n", "AR ?= wlib ;\n", "CC ?= wcc386 ;\n", "CCFLAGS ?= /zq /DWIN32 /I$(WATCOM)\\\\h ; # zq=quiet\n", "C++ ?= wpp386 ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "CP ?= copy ;\n", "DOT ?= . ;\n", "DOTDOT ?= .. ;\n", "LINK ?= wcl386 ;\n", "LINKFLAGS ?= /zq ; # zq=quiet\n", "LINKLIBS ?= ;\n", "MV ?= move ;\n", "NOARSCAN ?= true ;\n", "OPTIM ?= ;\n", "RM ?= del /f ;\n", "SLASH ?= \\\\ ;\n", "STDHDRS ?= $(WATCOM)\\\\h $(WATCOM)\\\\h\\\\nt ;\n", "SUFEXE ?= .exe ;\n", "SUFLIB ?= .lib ;\n", "SUFOBJ ?= .obj ;\n", "UNDEFFLAG ?= \"/u _\" ;\n", "PICFLAGS = -s ; # disable stack checks\n", "}\n", "else if $(JAM_TOOLSET) = MINGW\n", "{\n", "Echo \"Compiler is GCC with Mingw\" ;\n", "\n", "AR ?= ar -ru ;\n", "CC ?= gcc ;\n", "CCFLAGS ?= \"\" ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "LINK ?= $(CC) ;\n", "LINKFLAGS ?= \"\" ;\n", "LINKLIBS ?= \"\" ;\n", "OPTIM ?= ;\n", "SUFOBJ = .o ;\n", "SUFLIB = .a ;\n", "SLASH = / ;\n", "}\n", "else if $(JAM_TOOLSET) = LCC\n", "{\n", "Echo \"Compiler is Win32-LCC\" ;\n", "\n", "AR ?= lcclib ;\n", "CC ?= lcc ;\n", "CCFLAGS ?= \"\" ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "LINK ?= lcclnk ;\n", "LINKFLAGS ?= \"\" ;\n", "LINKLIBS ?= \"\" ;\n", "OPTIM ?= ;\n", "NOARSCAN = true ;\n", "}\n", "else if $(JAM_TOOLSET) = DIGITALMARS\n", "{\n", "Echo \"Compiler is Digital Mars C/C++\" ;\n", "\n", "AR ?= lib -c ;\n", "CC ?= dmc ;\n", "CCFLAGS ?= \"\" ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "LINK ?= link /nologo ;\n", "LINKFLAGS ?= \"/EXETYPE:NT /NOMAP\" ;\n", "LINKLIBS ?= USER32.LIB\n", "KERNEL32.LIB\n", "GDI32.LIB ;\n", "OPTIM ?= ;\n", "NOARSCAN = true ;\n", "PICFLAGS = -mn -WD ;\n", "}\n", "else if $(JAM_TOOLSET) = PELLESC\n", "{\n", "Echo \"Compiler is PellesC\" ;\n", "\n", "AR ?= polib ;\n", "CC ?= pocc ;\n", "CCFLAGS ?= \"\" ;\n", "LINK ?= polink ;\n", "LINKFLAGS ?= ;\n", "LINKLIBS ?= ;\n", "OPTIM ?= ;\n", "NOARSCAN = true ;\n", "LINKLIBS ?=\n", "crt.lib oldnames.lib Win\\\\kernel32.lib ;\n", "}\n", "else\n", "{\n", "Exit \"On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the\"\n", "\"Borland or Microsoft directories.\" ;\n", "}\n", "\n", "STDHRS ?= \"\" ;\n", "}\n", "else if $(OS2)\n", "{\n", "local SUPPORTED_TOOLSETS = \"EMX\" \"WATCOM\" ;\n", "\n", "TOOLSET = \"\" ;\n", "\n", "if $(JAM_TOOLSET)\n", "{\n", "if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS)\n", "{\n", "Echo \"The JAM_TOOLSET environment variable is defined but its value\" ;\n", "Echo \"is invalid, please use one of the following:\" ;\n", "Echo ;\n", "\n", "for t in $(SUPPORTED_TOOLSETS) { Echo \" \" $(t) ; }\n", "Exit ;\n", "}\n", "}\n", "\n", "if ! $(JAM_TOOLSET)\n", "{\n", "if $(watcom)\n", "{\n", "WATCOM = $(watcom) ;\n", "TOOLSET = WATCOM ;\n", "}\n", "else\n", "{\n", "Echo \"Jam cannot be run because you didn't indicate which compilation toolset\" ;\n", "Echo \"to use. To do so, follow these simple instructions:\" ;\n", "Echo ;\n", "Echo \" - define one of the following environment variable, with the\" ;\n", "Echo \" appropriate value according to this list:\" ;\n", "Echo ;\n", "Echo \" Variable Toolset Description\" ;\n", "Echo ;\n", "Echo \" WATCOM Watcom C/C++ Watcom install path\" ;\n", "Echo \" EMX EMX (gcc) EMX install path\" ;\n", "Echo ;\n", "Echo \" - define the JAM_TOOLSET environment variable with the *name*\" ;\n", "Echo \" of the toolset variable you want to use.\" ;\n", "Echo ;\n", "Echo \" e.g.: set WATCOM=C:\\WATCOM\" ;\n", "Echo \" set JAM_TOOLSET=WATCOM\" ;\n", "Echo ;\n", "Exit ;\n", "}\n", "}\n", "\n", "RM = del /f ;\n", "CP = copy ;\n", "MV ?= move ;\n", "DOT ?= . ;\n", "DOTDOT ?= .. ;\n", "SUFLIB ?= .lib ;\n", "SUFOBJ ?= .obj ;\n", "SUFEXE ?= .exe ;\n", "\n", "SUFLIBSHR ?= .dll ;\n", "\n", "if $(JAM_TOOLSET) = WATCOM\n", "{\n", "AR ?= wlib ;\n", "BINDIR ?= \\\\os2\\\\apps ;\n", "CC ?= wcc386 ;\n", "CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\\\h ; # zq=quiet\n", "C++ ?= wpp386 ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "CP ?= copy ;\n", "DOT ?= . ;\n", "DOTDOT ?= .. ;\n", "LINK ?= wcl386 ;\n", "LINKFLAGS ?= /zq ; # zq=quiet\n", "LINKLIBS ?= ;\n", "MV ?= move ;\n", "NOARSCAN ?= true ;\n", "OPTIM ?= ;\n", "RM ?= del /f ;\n", "SLASH ?= \\\\ ;\n", "STDHDRS ?= $(WATCOM)\\\\h ;\n", "SUFEXE ?= .exe ;\n", "SUFLIB ?= .lib ;\n", "SUFOBJ ?= .obj ;\n", "UNDEFFLAG ?= \"/u _\" ;\n", "}\n", "else if $(JAM_TOOLSET) = EMX\n", "{\n", "Echo \"Compiler is GCC-EMX\" ;\n", "AR ?= ar -ru ;\n", "CC ?= gcc ;\n", "CCFLAGS ?= \"\" ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "LINK ?= $(CC) ;\n", "LINKFLAGS ?= \"\" ;\n", "LINKLIBS ?= \"\" ;\n", "OPTIM ?= ;\n", "SUFOBJ = .o ;\n", "SUFLIB = .a ;\n", "UNDEFFLAG ?= \"-U\" ;\n", "SLASH = / ;\n", "}\n", "else\n", "{\n", "Exit \"Sorry, but the $(JAM_TOOLSET) toolset isn't supported for now\" ;\n", "}\n", "}\n", "else if $(VMS)\n", "{\n", "C++ ?= cxx ;\n", "C++FLAGS ?= ;\n", "CC ?= cc ;\n", "CCFLAGS ?= ;\n", "CHMOD ?= set file/prot= ;\n", "CP ?= copy/replace ;\n", "CRELIB ?= true ;\n", "DOT ?= [] ;\n", "DOTDOT ?= [-] ;\n", "EXEMODE ?= (w:e) ;\n", "FILEMODE ?= (w:r) ;\n", "HDRS ?= ;\n", "LINK ?= link ;\n", "LINKFLAGS ?= \"\" ;\n", "LINKLIBS ?= ;\n", "MKDIR ?= create/dir ;\n", "MV ?= rename ;\n", "OPTIM ?= \"\" ;\n", "RM ?= delete ;\n", "RUNVMS ?= mcr ;\n", "SHELLMODE ?= (w:er) ;\n", "SLASH ?= . ;\n", "STDHDRS ?= decc$library_include ;\n", "SUFEXE ?= .exe ;\n", "SUFLIB ?= .olb ;\n", "SUFOBJ ?= .obj ;\n", "\n", "switch $(OS)\n", "{\n", "case OPENVMS : CCFLAGS ?= /stand=vaxc ;\n", "case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;\n", "}\n", "}\n", "else if $(MAC)\n", "{\n", "local OPT ;\n", "\n", "CW ?= \"{CW}\" ;\n", "\n", "MACHDRS ?=\n", "\"$(UMACHDRS):Universal:Interfaces:CIncludes\"\n", "\"$(CW):MSL:MSL_C:MSL_Common:Include\"\n", "\"$(CW):MSL:MSL_C:MSL_MacOS:Include\" ;\n", "\n", "MACLIBS ?=\n", "\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib\"\n", "\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib\" ;\n", "\n", "MPWLIBS ?=\n", "\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib\"\n", "\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib\" ;\n", "\n", "MPWNLLIBS ?=\n", "\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib\"\n", "\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib\" ;\n", "\n", "SIOUXHDRS ?= ;\n", "\n", "SIOUXLIBS ?=\n", "\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib\"\n", "\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib\"\n", "\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib\" ;\n", "\n", "C++ ?= mwcppc ;\n", "C++FLAGS ?= -w off ;\n", "CC ?= mwcppc ;\n", "CCFLAGS ?= -w off ;\n", "CP ?= duplicate -y ;\n", "DOT ?= \":\" ;\n", "DOTDOT ?= \"::\" ;\n", "HDRS ?= $(MACHDRS) $(MPWHDRS) ;\n", "LINK ?= mwlinkppc ;\n", "LINKFLAGS ?= -mpwtool -warn ;\n", "LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ;\n", "MKDIR ?= newfolder ;\n", "MV ?= rename -y ;\n", "NOARSCAN ?= true ;\n", "OPTIM ?= ;\n", "RM ?= delete -y ;\n", "SLASH ?= \":\" ;\n", "STDHDRS ?= ;\n", "SUFLIB ?= .lib ;\n", "SUFOBJ ?= .o ;\n", "}\n", "else if $(OS) = BEOS && $(OSPLAT) = PPC\n", "{\n", "AR ?= mwld -xml -o ;\n", "BINDIR ?= /boot/home/config/bin ;\n", "CC ?= mwcc ;\n", "CCFLAGS ?= -nosyspath ;\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= -nosyspath ;\n", "CHMOD ?= chmod ;\n", "CHGRP ?= chgrp ;\n", "CHOWN ?= chown ;\n", "FORTRAN ?= \"\" ;\n", "LEX ?= flex ;\n", "LIBDIR ?= /boot/home/config/lib ;\n", "LINK ?= mwld ;\n", "LINKFLAGS ?= \"\" ;\n", "MANDIR ?= /boot/home/config/man ;\n", "NOARSCAN ?= true ;\n", "RANLIB ?= ranlib ;\n", "STDHDRS ?= /boot/develop/headers/posix ;\n", "YACC ?= bison -y ;\n", "YACCGEN ?= .c ;\n", "YACCFILES ?= y.tab ;\n", "YACCFLAGS ?= -d ;\n", "}\n", "else if $(OS) = BEOS\n", "{\n", "BINDIR ?= /boot/home/config/bin ;\n", "CC ?= gcc ;\n", "C++ ?= $(CC) ;\n", "CHMOD ?= chmod ;\n", "CHGRP ?= chgrp ;\n", "CHOWN ?= chown ;\n", "FORTRAN ?= \"\" ;\n", "LEX ?= flex ;\n", "LIBDIR ?= /boot/home/config/lib ;\n", "LINK ?= gcc ;\n", "MANDIR ?= /boot/home/config/man ;\n", "NOARSCAN ?= true ;\n", "RANLIB ?= ranlib ;\n", "STDHDRS ?= /boot/develop/headers/posix ;\n", "YACC ?= bison -y ;\n", "YACCGEN ?= .c ;\n", "YACCFILES ?= y.tab ;\n", "YACCFLAGS ?= -d ;\n", "}\n", "else if $(UNIX)\n", "{\n", "switch $(OS)\n", "{\n", "case AIX :\n", "LINKLIBS ?= -lbsd ;\n", "\n", "case AMIGA :\n", "CC ?= gcc ;\n", "YACC ?= bison -y ;\n", "\n", "case CYGWIN :\n", "CC ?= gcc ;\n", "CCFLAGS += -D__cygwin__ ;\n", "LEX ?= flex ;\n", "JAMSHELL ?= sh -c ;\n", "RANLIB ?= \"\" ;\n", "SUFEXE ?= .exe ;\n", "YACC ?= bison -y ;\n", "\n", "case DGUX :\n", "RANLIB ?= \"\" ;\n", "RELOCATE ?= true ;\n", "\n", "case HPUX :\n", "RANLIB ?= \"\" ;\n", "\n", "case INTERIX :\n", "CC ?= gcc ;\n", "JAMSHELL ?= sh -c ;\n", "RANLIB ?= \"\" ;\n", "\n", "case IRIX :\n", "RANLIB ?= \"\" ;\n", "\n", "case MPEIX :\n", "CC ?= gcc ;\n", "C++ ?= gcc ;\n", "CCFLAGS += -D_POSIX_SOURCE ;\n", "HDRS += /usr/include ;\n", "RANLIB ?= \"\" ;\n", "NOARSCAN ?= true ;\n", "NOARUPDATE ?= true ;\n", "\n", "case MVS :\n", "RANLIB ?= \"\" ;\n", "\n", "case NEXT :\n", "AR ?= libtool -o ;\n", "RANLIB ?= \"\" ;\n", "\n", "case MACOSX :\n", "C++ ?= c++ ;\n", "MANDIR ?= /usr/local/share/man ;\n", "\n", "case NCR :\n", "RANLIB ?= \"\" ;\n", "\n", "case PTX :\n", "RANLIB ?= \"\" ;\n", "\n", "case QNX :\n", "AR ?= wlib ;\n", "CC ?= cc ;\n", "CCFLAGS ?= -Q ; # quiet\n", "C++ ?= $(CC) ;\n", "C++FLAGS ?= -Q ; # quiet\n", "LINK ?= $(CC) ;\n", "LINKFLAGS ?= -Q ; # quiet\n", "NOARSCAN ?= true ;\n", "RANLIB ?= \"\" ;\n", "\n", "case SCO :\n", "RANLIB ?= \"\" ;\n", "RELOCATE ?= true ;\n", "\n", "case SINIX :\n", "RANLIB ?= \"\" ;\n", "\n", "case SOLARIS :\n", "RANLIB ?= \"\" ;\n", "AR ?= \"/usr/ccs/bin/ar ru\" ;\n", "\n", "case UNICOS :\n", "NOARSCAN ?= true ;\n", "OPTIM ?= -O0 ;\n", "\n", "case UNIXWARE :\n", "RANLIB ?= \"\" ;\n", "RELOCATE ?= true ;\n", "}\n", "\n", "\n", "CCFLAGS ?= ;\n", "C++FLAGS ?= $(CCFLAGS) ;\n", "CHMOD ?= chmod ;\n", "CHGRP ?= chgrp ;\n", "CHOWN ?= chown ;\n", "LEX ?= lex ;\n", "LINKFLAGS ?= $(CCFLAGS) ;\n", "LINKLIBS ?= ;\n", "OPTIM ?= -O ;\n", "RANLIB ?= ranlib ;\n", "YACC ?= yacc ;\n", "YACCGEN ?= .c ;\n", "YACCFILES ?= y.tab ;\n", "YACCFLAGS ?= -d ;\n", "\n", "SUFOBJSHR ?= .lo ;\n", "SUFLIBSHR ?= .la ;\n", "PICFLAGS ?= -fpic ;\n", "STDHDRS ?= /usr/include ;\n", "}\n", "\n", "SUFOBJSHR ?= $(SUFOBJ) ;\n", "SUFLIBSHR ?= $(SUFLIB) ;\n", "\n", "\n", "DC ?= dmd ;\n", "\n", "\n", "AR ?= ar ru ;\n", "AS ?= as ;\n", "ASFLAGS ?= ;\n", "AWK ?= awk ;\n", "BINDIR ?= /usr/local/bin ;\n", "C++ ?= cc ;\n", "C++FLAGS ?= ;\n", "CC ?= cc ;\n", "CCFLAGS ?= ;\n", "CP ?= cp -f ;\n", "CRELIB ?= ;\n", "DOT ?= . ;\n", "DOTDOT ?= .. ;\n", "EXEMODE ?= 711 ;\n", "FILEMODE ?= 644 ;\n", "FORTRAN ?= f77 ;\n", "FORTRANFLAGS ?= ;\n", "HDRS ?= ;\n", "INSTALLGRIST ?= installed ;\n", "JAMFILE ?= Jamfile ;\n", "JAMRULES ?= Jamrules ;\n", "LEX ?= ;\n", "LIBDIR ?= /usr/local/lib ;\n", "LINK ?= $(CC) ;\n", "LINKFLAGS ?= ;\n", "LINKLIBS ?= ;\n", "LN ?= ln ;\n", "MANDIR ?= /usr/local/man ;\n", "MKDIR ?= mkdir ;\n", "MV ?= mv -f ;\n", "OPTIM ?= ;\n", "RCP ?= rcp ;\n", "RM ?= rm -f ;\n", "RMDIR ?= $(RM) ;\n", "RSH ?= rsh ;\n", "SED ?= sed ;\n", "SHELLHEADER ?= \"#!/bin/sh\" ;\n", "SHELLMODE ?= 755 ;\n", "SLASH ?= / ;\n", "SUBDIRRULES ?= ;\n", "SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ;\n", "SUFEXE ?= \"\" ;\n", "SUFLIB ?= .a ;\n", "SUFOBJ ?= .o ;\n", "UNDEFFLAG ?= \"-u _\" ;\n", "YACC ?= ;\n", "YACCGEN ?= ;\n", "YACCFILES ?= ;\n", "YACCFLAGS ?= ;\n", "\n", "HDRPATTERN =\n", "\"^[ ]*#[ ]*include[ ]*[<\\\"]([^\\\">]*)[\\\">].*$\" ;\n", "\n", "OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;\n", "\n", "\n", "\n", "Depends all : shell files lib exe obj ;\n", "Depends all shell files lib exe obj : first ;\n", "NotFile all first shell files lib exe obj dirs clean uninstall ;\n", "Always clean uninstall ;\n", "\n", "\n", "rule As\n", "{\n", "Depends $(<) : $(>) ;\n", "ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;\n", "ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;\n", "}\n", "\n", "rule Bulk\n", "{\n", "local i ;\n", "\n", "for i in $(>)\n", "{\n", "File $(i:D=$(<)) : $(i) ;\n", "}\n", "}\n", "\n", "\n", "rule Dc\n", "{\n", "Depends $(<) : $(>) ;\n", "\n", "\n", "DCFLAGS on $(<) += $(DCFLAGS) $(SUBDIRDCFLAGS) ;\n", "}\n", "\n", "\n", "rule Cc\n", "{\n", "Depends $(<) : $(>) ;\n", "\n", "\n", "if $(RELOCATE)\n", "{\n", "CcMv $(<) : $(>) ;\n", "}\n", "\n", "\n", "CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;\n", "\n", "CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;\n", "CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;\n", "}\n", "\n", "rule C++\n", "{\n", "Depends $(<) : $(>) ;\n", "\n", "if $(RELOCATE)\n", "{\n", "CcMv $(<) : $(>) ;\n", "}\n", "\n", "C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;\n", "\n", "CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;\n", "CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;\n", "}\n", "\n", "rule Chmod\n", "{\n", "if $(CHMOD) { Chmod1 $(<) ; }\n", "}\n", "\n", "\n", "rule File\n", "{\n", "Depends files : $(<) ;\n", "Depends $(<) : $(>) ;\n", "SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", "MODE on $(<) = $(FILEMODE) ;\n", "Chmod $(<) ;\n", "}\n", "\n", "rule Fortran\n", "{\n", "Depends $(<) : $(>) ;\n", "}\n", "\n", "rule GenFile\n", "{\n", "local _t = [ FGristSourceFiles $(<) ] ;\n", "local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;\n", "Depends $(_t) : $(_s) $(>[2-]) ;\n", "GenFile1 $(_t) : $(_s) $(>[2-]) ;\n", "Clean clean : $(_t) ;\n", "}\n", "\n", "rule GenFile1\n", "{\n", "MakeLocate $(<) : $(LOCATE_SOURCE) ;\n", "SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", "}\n", "\n", "rule HardLink\n", "{\n", "Depends files : $(<) ;\n", "Depends $(<) : $(>) ;\n", "SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", "}\n", "\n", "rule HdrMacroFile\n", "{\n", "HDRMACRO $(<) ;\n", "}\n", "\n", "rule HdrRule\n", "{\n", "\n", "\n", "\n", "local s = $(>:G=$(HDRGRIST:E)) ;\n", "\n", "Includes $(<) : $(s) ;\n", "SEARCH on $(s) = $(HDRSEARCH) ;\n", "NoCare $(s) ;\n", "\n", "\n", "HDRSEARCH on $(s) = $(HDRSEARCH) ;\n", "HDRSCAN on $(s) = $(HDRSCAN) ;\n", "HDRRULE on $(s) = $(HDRRULE) ;\n", "HDRGRIST on $(s) = $(HDRGRIST) ;\n", "}\n", "\n", "\n", "rule InstallInto\n", "{\n", "\n", "local i t ;\n", "\n", "t = $(>:G=$(INSTALLGRIST)) ;\n", "\n", "\n", "Depends install : $(t) ;\n", "Clean uninstall : $(t) ;\n", "SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", "MakeLocate $(t) : $(<) ;\n", "\n", "\n", "for i in $(>)\n", "{\n", "local tt = $(i:G=$(INSTALLGRIST)) ;\n", "\n", "Depends $(tt) : $(i) ;\n", "Install $(tt) : $(i) ;\n", "Chmod $(tt) ;\n", "\n", "if $(OWNER) && $(CHOWN)\n", "{\n", "Chown $(tt) ;\n", "OWNER on $(tt) = $(OWNER) ;\n", "}\n", "\n", "if $(GROUP) && $(CHGRP)\n", "{\n", "Chgrp $(tt) ;\n", "GROUP on $(tt) = $(GROUP) ;\n", "}\n", "}\n", "}\n", "\n", "rule InstallBin\n", "{\n", "local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;\n", "\n", "InstallInto $(<) : $(_t) ;\n", "MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;\n", "}\n", "\n", "rule InstallFile\n", "{\n", "InstallInto $(<) : $(>) ;\n", "MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;\n", "}\n", "\n", "rule InstallLib\n", "{\n", "InstallInto $(<) : $(>) ;\n", "MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;\n", "}\n", "\n", "rule InstallMan\n", "{\n", "\n", "local i s d ;\n", "\n", "for i in $(>)\n", "{\n", "switch $(i:S)\n", "{\n", "case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;\n", "case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;\n", "case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;\n", "case .n : s = n ; case .man : s = 1 ;\n", "}\n", "\n", "d = man$(s) ;\n", "\n", "InstallInto $(d:R=$(<)) : $(i) ;\n", "}\n", "\n", "MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;\n", "}\n", "\n", "rule InstallShell\n", "{\n", "InstallInto $(<) : $(>) ;\n", "MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ;\n", "}\n", "\n", "rule Lex\n", "{\n", "LexMv $(<) : $(>) ;\n", "Depends $(<) : $(>) ;\n", "MakeLocate $(<) : $(LOCATE_SOURCE) ;\n", "Clean clean : $(<) ;\n", "}\n", "\n", "rule Library\n", "{\n", "LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", "Objects $(>) ;\n", "}\n", "\n", "rule SharedLibrary\n", "{\n", "SharedLibraryFromObjects $(<) : $(>:S=$(SUFOBJSHR)) : $(3) : $(4) ;\n", "SharedObjects $(>) ;\n", "}\n", "\n", "if $(UNIX)\n", "{\n", "rule LibToolFind\n", "{\n", "if $(LIBTOOL) { return $(LIBTOOL) ; }\n", "\n", "local matches = [ Glob $(PATH) : libtool ] ;\n", "\n", "if ! $(matches)\n", "{\n", "Exit \"could not find 'libtool' program in current path. Aborting !\" ;\n", "}\n", "LIBTOOL = $(matches[1]) ;\n", "\n", "return $(LIBTOOL) ;\n", "}\n", "}\n", "\n", "rule LibraryFromObjects\n", "{\n", "local _i _l _s ;\n", "\n", "\n", "_s = [ FGristFiles $(>) ] ;\n", "_l = $(<:S=$(SUFLIB)) ;\n", "\n", "\n", "if $(KEEPOBJS)\n", "{\n", "Depends obj : $(_s) ;\n", "}\n", "else\n", "{\n", "Depends lib : $(_l) ;\n", "}\n", "\n", "\n", "if ! $(_l:D)\n", "{\n", "MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;\n", "}\n", "\n", "if $(NOARSCAN)\n", "{\n", "\n", "Depends $(_l) : $(_s) ;\n", "}\n", "else\n", "{\n", "\n", "Depends $(_l) : $(_l)($(_s:BS)) ;\n", "\n", "for _i in $(_s)\n", "{\n", "Depends $(_l)($(_i:BS)) : $(_i) ;\n", "}\n", "}\n", "\n", "Clean clean : $(_l) ;\n", "\n", "if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }\n", "\n", "Archive $(_l) : $(_s) ;\n", "\n", "if $(RANLIB) { Ranlib $(_l) ; }\n", "\n", "\n", "if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }\n", "}\n", "\n", "\n", "rule SharedLibraryFromObjects\n", "{\n", "local _i _l _s ;\n", "\n", "\n", "_s = [ FGristFiles $(>) ] ;\n", "_l = $(<:S=$(SUFLIBSHR)) ;\n", "\n", "\n", "if $(KEEPOBJS)\n", "{\n", "Depends obj : $(_s) ;\n", "}\n", "else\n", "{\n", "Depends lib : $(_l) ;\n", "}\n", "\n", "\n", "if ! $(_l:D)\n", "{\n", "MakeLocate $(_l) : $(LOCATE_TARGET) ;\n", "}\n", "\n", "Depends $(_l) : $(_s) ;\n", "\n", "Clean clean : $(_l) ;\n", "\n", "\n", "if $(UNIX)\n", "{\n", "local libtool = [ LibToolFind ] ; # find the right libtool\n", "\n", "AR on $(_l) = \"$(libtool) --mode=link $(AR)\" ;\n", "}\n", "else if $(NT)\n", "{\n", "local _implib = $(4) ;\n", "local _def = $(3) ;\n", "\n", "_implib ?= $(_l:S=$(SUFLIBSHR)$(SUFLIB)) ;\n", "_def ?= $(_l:S=.def) ;\n", "\n", "Clean clean : $(_implib) ;\n", "Depends lib : $(_implib) $(_def) ;\n", "\n", "Depends $(_implib) : $(_def) $(_l) ;\n", "Depends $(_l) : $(_def) ;\n", "\n", "DEFFILENAME on $(_l) = $(_def) ;\n", "IMPLIBNAME on $(_l) = $(_implib) ;\n", "\n", "MakeLocate $(_implib) : $(LOCATE_TARGET) ;\n", "MakeLocate $(_implib:S=.exp) : $(LOCATE_TARGET) ;\n", "\n", "if $(JAM_TOOLSET) in VISUALC BORLANDC LCC WATCOM DIGITALMARS\n", "{\n", "SharedLink-$(JAM_TOOLSET) $(_l) : $(_s) : $(_implib) : $(_def) ;\n", "}\n", "\n", "DllLink $(_l) : $(_s) ;\n", "}\n", "else\n", "{\n", "Echo \"Sorry, I don't know how to make a shared library on your system\" ;\n", "Exit \"Please contact the FTJam maintainer for help\" ;\n", "}\n", "}\n", "\n", "\n", "\n", "rule SharedLink-VISUALC\n", "{\n", "Clean clean : $(3:S=.exp) ;\n", "}\n", "\n", "\n", "rule SharedLink-BORLANDC\n", "{\n", "local _deffile = $(4) ;\n", "local _implib = $(3) ;\n", "\n", "LINKFLAGS on $(<) += /x /Gn /Tpd ;\n", "LINKLIBS on $(<) = $(LINKLIBS) $(ILINKLIBS) ;\n", "\n", "DllImplib $(_implib) : $(<) ;\n", "Depends $(_implib) : $(_deffile) $(<) ;\n", "Depends lib : $(_implib) ;\n", "\n", "DEFFILENAME on $(_implib) = $(_deffile) ;\n", "\n", "MakeLocate $(<:S=.tds) : $(LOCATE_TARGET) ;\n", "Clean clean : $(<:S=.tds) ;\n", "}\n", "\n", "\n", "rule SharedLink-LCC\n", "{\n", "if \"\" {\n", "}\n", "\n", "\n", "Clean clean : $(4:S=.exp) ;\n", "}\n", "\n", "\n", "rule SharedLink-WATCOM\n", "{\n", "\n", "local _deffile = $(4) ;\n", "local _implib = $(3) ;\n", "\n", "IMPLIB on $(<) = $(_implib) ;\n", "DEFFILE on $(<) = $(_deffile) ;\n", "\n", "MakeLocate $(<:S=.tds) : $(LOCATE_TARGET) ;\n", "Clean clean : $(<:S=.tds) ;\n", "}\n", "\n", "\n", "rule SharedLink-DIGITALMARS\n", "{\n", "}\n", "\n", "\n", "rule Link\n", "{\n", "MODE on $(<) = $(EXEMODE) ;\n", "Chmod $(<) ;\n", "}\n", "\n", "rule LinkLibraries\n", "{\n", "\n", "local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", "\n", "Depends $(_t) : $(>:S=$(SUFLIB)) ;\n", "NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;\n", "}\n", "\n", "rule LinkSharedLibraries\n", "{\n", "\n", "local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", "local _ext = $(SUFLIBSHR) ;\n", "\n", "if $(NT) || $(OS2)\n", "{\n", "_ext = $(SUFLIBSHR)$(SUFLIB) ;\n", "}\n", "Depends $(_t) : $(>:S=$(_ext)) ;\n", "NEEDLIBS on $(_t) += $(>:S=$(_ext)) ;\n", "}\n", "\n", "rule Main\n", "{\n", "MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", "Objects $(>) ;\n", "}\n", "\n", "rule MainFromObjects\n", "{\n", "local _s _t ;\n", "\n", "\n", "_s = [ FGristFiles $(>) ] ;\n", "_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", "\n", "\n", "if $(_t) != $(<)\n", "{\n", "Depends $(<) : $(_t) ;\n", "NotFile $(<) ;\n", "}\n", "\n", "\n", "Depends exe : $(_t) ;\n", "Depends $(_t) : $(_s) ;\n", "MakeLocate $(_t) : $(LOCATE_TARGET) ;\n", "\n", "Clean clean : $(_t) ;\n", "\n", "if $(JAM_TOOLSET) = BORLANDC {\n", "MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;\n", "Clean clean : $(_t:S=.tds) ;\n", "}\n", "\n", "Link $(_t) : $(_s) ;\n", "}\n", "\n", "rule MakeLocate\n", "{\n", "\n", "if $(>)\n", "{\n", "LOCATE on $(<) = $(>) ;\n", "Depends $(<) : $(>[1]:G=dir) ;\n", "MkDir $(>[1]:G=dir) ;\n", "}\n", "}\n", "\n", "rule MkDir\n", "{\n", "\n", "NoUpdate $(<) ;\n", "\n", "\n", "if $(<:G=) != $(DOT) && ! $($(<)-mkdir)\n", "{\n", "\n", "$(<)-mkdir = true ;\n", "Depends dirs : $(<) ;\n", "MkDir1 $(<) ;\n", "\n", "\n", "local s = $(<:P) ;\n", "\n", "\n", "if $(NT)\n", "{\n", "switch $(s)\n", "{\n", "case *: : s = ;\n", "case *:\\\\ : s = ;\n", "}\n", "}\n", "\n", "if $(UNIX) && $(OS) = CYGWIN\n", "{\n", "switch $(s)\n", "{\n", "case ?: : s = ;\n", "case ?:/ : s = ;\n", "case

    /cygdrive : s = ;\n", "case /cygdrive/ : s = ;\n", "}\n", "}\n", "\n", "if $(s) = $(<)\n", "{\n", "\n", "NotFile $(s) ;\n", "}\n", "else if $(s:G=)\n", "{\n", "\n", "Depends $(<) : $(s) ;\n", "MkDir $(s) ;\n", "}\n", "}\n", "}\n", "\n", "rule Object\n", "{\n", "\n", "Clean clean : $(<) ;\n", "\n", "MakeLocate $(<) : $(LOCATE_TARGET) ;\n", "SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", "\n", "\n", "HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;\n", "\n", "\n", "\n", "HDRRULE on $(>) = HdrRule ;\n", "HDRSCAN on $(>) = $(HDRPATTERN) ;\n", "HDRSEARCH on $(>) =\n", "$(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;\n", "\n", "HDRGRIST on $(>) = $(HDRGRIST) ;\n", "\n", "\n", "DEFINES on $(<) += $(DEFINES) ;\n", "\n", "\n", "switch $(>:S)\n", "{\n", "case .asm : As $(<) : $(>) ;\n", "case .c : Cc $(<) : $(>) ;\n", "case .C : C++ $(<) : $(>) ;\n", "case .cc : C++ $(<) : $(>) ;\n", "case .cpp : C++ $(<) : $(>) ;\n", "case .cxx : C++ $(<) : $(>) ;\n", "case .c++ : C++ $(<) : $(>) ;\n", "case .C++ : C++ $(<) : $(>) ;\n", "case .d : Dc $(<) : $(>) ;\n", "case .f : Fortran $(<) : $(>) ;\n", "case .l : Cc $(<) : $(<:S=.c) ;\n", "Lex $(<:S=.c) : $(>) ;\n", "case .s : As $(<) : $(>) ;\n", "case .y : Cc $(<) : $(<:S=$(YACCGEN)) ;\n", "Yacc $(<:S=$(YACCGEN)) : $(>) ;\n", "case * : UserObject $(<) : $(>) ;\n", "}\n", "}\n", "\n", "rule ObjectCcFlags\n", "{\n", "CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", "}\n", "\n", "rule ObjectC++Flags\n", "{\n", "C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", "}\n", "\n", "rule ObjectDefines\n", "{\n", "\n", "local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;\n", "\n", "DEFINES on $(s) += $(>) ;\n", "CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;\n", "}\n", "\n", "rule ObjectHdrs\n", "{\n", "\n", "local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;\n", "\n", "HDRS on $(s) += $(>) ;\n", "CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ;\n", "}\n", "\n", "rule Objects\n", "{\n", "local _i ;\n", "\n", "for _i in [ FGristFiles $(<) ]\n", "{\n", "Object $(_i:S=$(SUFOBJ)) : $(_i) ;\n", "Depends obj : $(_i:S=$(SUFOBJ)) ;\n", "}\n", "}\n", "\n", "rule SharedObjects\n", "{\n", "local SUFOBJ = $(SUFOBJSHR) ;\n", "\n", "Objects $(<) ;\n", "\n", "ObjectCcFlags $(<) : $(PICFLAGS) ;\n", "\n", "if $(UNIX)\n", "{\n", "libtool on $(<:S=$(SUFOBJ)) = [ LibToolFind ] ;\n", "CC on $(<:S=$(SUFOBJ)) = \"$(libtool) --mode=compile $(CC) -dynamic\" ;\n", "}\n", "}\n", "\n", "\n", "rule RmTemps\n", "{\n", "Temporary $(>) ;\n", "}\n", "\n", "rule Setuid\n", "{\n", "MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;\n", "}\n", "\n", "rule Shell\n", "{\n", "Depends shell : $(<) ;\n", "Depends $(<) : $(>) ;\n", "SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", "MODE on $(<) = $(SHELLMODE) ;\n", "Clean clean : $(<) ;\n", "Chmod $(<) ;\n", "}\n", "\n", "rule SoftLink\n", "{\n", "Depends files : $(<) ;\n", "Depends $(<) : $(>) ;\n", "SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", "Clean clean : $(<) ;\n", "}\n", "\n", "rule SubDir\n", "{\n", "\n", "local _top = $(<[1]) ;\n", "local _tokens = $(<[2-]) ;\n", "\n", "\n", "if ! $(_top)\n", "{\n", "Exit SubDir syntax error ;\n", "}\n", "\n", "if ! $($(_top)-SET)\n", "{\n", "$(_top)-SET = true ;\n", "\n", "\n", "if $($(_top))\n", "{\n", "\n", "$(_top)-UP = ;\n", "$(_top)-DOWN = ;\n", "$(_top)-ROOT = $($(_top)) ;\n", "}\n", "else\n", "{\n", "\n", "\n", "\n", "_tokens = [ FReverse $(_tokens) ] ;\n", "SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;\n", "FStripCommon _tokens : SUBDIR_DOWN ;\n", "SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;\n", "_tokens = [ FReverse $(_tokens) ] ;\n", "\n", "if $(SUBDIR_DOWN) && $(_tokens)\n", "{\n", "Echo Warning: SubDir $(<) misplaced! ;\n", "}\n", "\n", "\n", "$(_top)-UP = $(SUBDIR_UP) $(_tokens) ;\n", "$(_top)-DOWN = $(SUBDIR_DOWN) ;\n", "$(_top)-ROOT = $(SUBDIR_ROOT:E=\"\") ;\n", "$(_top) = [ FSubDirPath $(_top) ] ;\n", "}\n", "\n", "\n", "SUBDIR_UP = $($(_top)-UP) ;\n", "SUBDIR_DOWN = ;\n", "SUBDIR_ROOT = $($(_top)-ROOT) ;\n", "\n", "\n", "if $($(_top)RULES) {\n", "include $($(_top)RULES) ;\n", "} else {\n", "NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;\n", "include $(JAMRULES:R=$($(_top)):G=$(_top)) ;\n", "}\n", "}\n", "\n", "\n", "SUBDIR_UP = $($(_top)-UP) ;\n", "SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;\n", "SUBDIR_ROOT = $($(_top)-ROOT) ;\n", "SUBDIR_TOKENS = $(SUBDIR_DOWN) ;\n", "\n", "SUBDIR = [ FSubDirPath $(<) ] ;\n", "\n", "\n", "SEARCH_SOURCE = $(SUBDIR) ;\n", "LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", "LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", "SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;\n", "\n", "\n", "SUBDIR$(SUBDIRRESET) = ;\n", "\n", "\n", "$(SUBDIRRULES) $(<) ;\n", "}\n", "\n", "rule FSubDirPath\n", "{\n", "\n", "\n", "\n", "local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;\n", "\n", "return $(_r:R=$($(<[1])-ROOT)) ;\n", "}\n", "\n", "rule SubDirDcFlags\n", "{\n", "SUBDIRDCFLAGS += $(<) ;\n", "}\n", "\n", "rule SubDirCcFlags\n", "{\n", "SUBDIRCCFLAGS += $(<) ;\n", "}\n", "\n", "rule SubDirC++Flags\n", "{\n", "SUBDIRC++FLAGS += $(<) ;\n", "}\n", "\n", "rule SubDirHdrs\n", "{\n", "SUBDIRHDRS += [ FDirName $(<) ] ;\n", "}\n", "\n", "rule SubInclude\n", "{\n", "\n", "\n", "if ! $($(<[1]))\n", "{\n", "Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;\n", "}\n", "\n", "SubDir $(<) ;\n", "\n", "include $(JAMFILE:D=$(SUBDIR)) ;\n", "}\n", "\n", "rule SubRules\n", "{\n", "\n", "if ! $($(<[1]))\n", "{\n", "Exit SubRules $(<[1]) without prior SubDir $(<[1]) ;\n", "}\n", "\n", "SubDir $(<) ;\n", "SubDir $(>) ;\n", "}\n", "\n", "rule Undefines\n", "{\n", "UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;\n", "}\n", "\n", "rule UserObject\n", "{\n", "Exit \"Unknown suffix on\" $(>) \"- see UserObject rule in Jamfile(5).\" ;\n", "}\n", "\n", "rule Yacc\n", "{\n", "local _h ;\n", "\n", "_h = $(<:BS=.h) ;\n", "\n", "\n", "MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;\n", "\n", "if $(YACC)\n", "{\n", "Depends $(<) $(_h) : $(>) ;\n", "Yacc1 $(<) $(_h) : $(>) ;\n", "YaccMv $(<) $(_h) : $(>) ;\n", "Clean clean : $(<) $(_h) ;\n", "}\n", "\n", "\n", "Includes $(<) : $(_h) ;\n", "}\n", "\n", "\n", "rule FGrist\n", "{\n", "return $(<:J=!) ;\n", "\n", "}\n", "\n", "\n", "rule FGristFiles\n", "{\n", "return $(<:G=$(SOURCE_GRIST:E)) ;\n", "}\n", "\n", "\n", "rule FGristSourceFiles\n", "{\n", "\n", "\n", "if ! $(SOURCE_GRIST)\n", "{\n", "return $(<) ;\n", "}\n", "else\n", "{\n", "local _i _o ;\n", "\n", "for _i in $(<)\n", "{\n", "switch $(_i)\n", "{\n", "case *.h : _o += $(_i) ;\n", "case * : _o += $(_i:G=$(SOURCE_GRIST)) ;\n", "}\n", "}\n", "\n", "return $(_o) ;\n", "}\n", "}\n", "\n", "\n", "rule FReverse\n", "{\n", "if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }\n", "}\n", "\n", "\n", "rule FSubDir\n", "{\n", "\n", "if ! $(<[1])\n", "{\n", "return $(DOT) ;\n", "}\n", "else\n", "{\n", "local _i _d ;\n", "\n", "_d = $(DOTDOT) ;\n", "\n", "for _i in $(<[2-])\n", "{\n", "_d = $(_d:R=$(DOTDOT)) ;\n", "}\n", "\n", "return $(_d) ;\n", "}\n", "}\n", "\n", "\n", "rule FStripCommon\n", "{\n", "\n", "\n", "if $($(<)[1]) && $($(<)[1]) = $($(>)[1])\n", "{\n", "$(<) = $($(<)[2-]) ;\n", "$(>) = $($(>)[2-]) ;\n", "FStripCommon $(<) : $(>) ;\n", "}\n", "}\n", "\n", "\n", "rule FRelPath\n", "{\n", "local _l _r ;\n", "\n", "\n", "_l = $(<) ;\n", "_r = $(>) ;\n", "\n", "FStripCommon _l : _r ;\n", "\n", "\n", "_l = [ FSubDir $(_l) ] ;\n", "_r = [ FDirName $(_r) ] ;\n", "\n", "\n", "\n", "if $(_r) = $(DOT) {\n", "return $(_l) ;\n", "} else {\n", "return $(_r:R=$(_l)) ;\n", "}\n", "}\n", "\n", "\n", "rule FAppendSuffix\n", "{\n", "\n", "if $(>)\n", "{\n", "local _i _o ;\n", "\n", "for _i in $(<)\n", "{\n", "if $(_i:S)\n", "{\n", "_o += $(_i) ;\n", "}\n", "else\n", "{\n", "_o += $(_i:S=$(>)) ;\n", "}\n", "}\n", "return $(_o) ;\n", "}\n", "else\n", "{\n", "return $(<) ;\n", "}\n", "}\n", "\n", "\n", "rule FQuote { return \"\\\\\\\"$(<)\\\\\\\"\" ; }\n", "rule FDefines { return -D$(<) ; }\n", "rule FIncludes { return -I$(<) ; }\n", "\n", "rule FDirName\n", "{\n", "\n", "local _i ;\n", "local _s = $(DOT) ;\n", "\n", "for _i in $(<)\n", "{\n", "_s = $(_i:R=$(_s)) ;\n", "}\n", "\n", "return $(_s) ;\n", "}\n", "\n", "if $(OS2)\n", "{\n", "rule FQuote { return \"\\\"$(<)\\\"\" ; }\n", "rule FIncludes { return /I$(<) ; }\n", "}\n", "else if $(NT) && $(JAM_TOOLSET) != MINGW && $(JAM_TOOLSET) != LCC\n", "{\n", "rule FDefines { return /D$(<) ; }\n", "rule FIncludes { return /I$(<) ; }\n", "}\n", "\n", "else if $(MAC)\n", "{\n", "rule FQuote { return \"\\\"$(<)\\\"\" ; }\n", "rule FDefines { return \"-define '$(<)'\" ; }\n", "rule FIncludes { return \"\\\"$(<:J=,)\\\"\" ; }\n", "}\n", "\n", "else if $(VMS)\n", "{\n", "rule FQuote { return \"\\\"\\\"\\\"$(<)\\\"\\\"\\\"\" ; }\n", "rule FDefines { return \"/define=( $(<:J=,) )\" ; }\n", "rule FIncludes { return \"/inc=( $(<:J=,) )\" ; }\n", "\n", "rule FDirName\n", "{\n", "local _s _i ;\n", "\n", "\n", "if ! $(<)\n", "{\n", "_s = $(DOT) ;\n", "}\n", "else\n", "{\n", "\n", "switch $(<[1])\n", "{\n", "case *:* : _s = $(<[1]) ;\n", "case \\\\[*\\\\] : _s = $(<[1]) ;\n", "case * : _s = [.$(<[1])] ;\n", "}\n", "\n", "for _i in [.$(<[2-])]\n", "{\n", "_s = $(_i:R=$(_s)) ;\n", "}\n", "}\n", "\n", "return $(_s) ;\n", "}\n", "}\n", "\n", "\n", "\n", "actions updated together piecemeal Archive\n", "{\n", "$(AR) $(<) $(>)\n", "}\n", "\n", "actions As\n", "{\n", "$(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions Dc\n", "{\n", "$(DC) -c -of$(<) $(DCFLAGS) $(DOPTIM) $(>)\n", "}\n", "\n", "actions Chgrp\n", "{\n", "$(CHGRP) $(GROUP) $(<)\n", "}\n", "\n", "actions Chmod1\n", "{\n", "$(CHMOD) $(MODE) $(<)\n", "}\n", "\n", "actions Chown\n", "{\n", "$(CHOWN) $(OWNER) $(<)\n", "}\n", "\n", "actions piecemeal together existing Clean\n", "{\n", "$(RM) $(>)\n", "}\n", "\n", "actions File\n", "{\n", "$(CP) $(>) $(<)\n", "}\n", "\n", "actions GenFile1\n", "{\n", "$(>[1]) $(<) $(>[2-])\n", "}\n", "\n", "actions Fortran\n", "{\n", "$(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)\n", "}\n", "\n", "actions HardLink\n", "{\n", "$(RM) $(<) && $(LN) $(>) $(<)\n", "}\n", "\n", "actions Install\n", "{\n", "$(CP) $(>) $(<)\n", "}\n", "\n", "actions Lex\n", "{\n", "$(LEX) $(>)\n", "}\n", "\n", "actions LexMv\n", "{\n", "$(MV) lex.yy.c $(<)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions MkDir1\n", "{\n", "$(MKDIR) $(<)\n", "}\n", "\n", "actions together Ranlib\n", "{\n", "$(RANLIB) $(<)\n", "}\n", "\n", "actions quietly updated piecemeal together RmTemps\n", "{\n", "$(RM) $(>)\n", "}\n", "\n", "actions Shell\n", "{\n", "$(AWK) '\n", "NR == 1 { print \"$(SHELLHEADER)\" }\n", "NR == 1 && /^[#:]/ { next }\n", "/^##/ { next }\n", "{ print }\n", "' < $(>) > $(<)\n", "}\n", "\n", "actions SoftLink\n", "{\n", "$(RM) $(<) && $(LN) -s $(>) $(<)\n", "}\n", "\n", "actions Yacc1\n", "{\n", "$(YACC) $(YACCFLAGS) $(>)\n", "}\n", "\n", "actions YaccMv\n", "{\n", "$(MV) $(YACCFILES).c $(<[1])\n", "$(MV) $(YACCFILES).h $(<[2])\n", "}\n", "\n", "\n", "if $(RELOCATE)\n", "{\n", "actions C++\n", "{\n", "$(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions ignore CcMv\n", "{\n", "[ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)\n", "}\n", "}\n", "\n", "\n", "if $(NOARUPDATE)\n", "{\n", "actions Archive\n", "{\n", "$(AR) $(<) $(>)\n", "}\n", "}\n", "\n", "\n", "if $(UNIX)\n", "{\n", "actions GenFile1\n", "{\n", "PATH=\"$PATH:.\"\n", "$(>[1]) $(<) $(>[2-])\n", "}\n", "}\n", "\n", "\n", "if $(NT)\n", "{\n", "if $(JAM_TOOLSET) = VISUALC || $(JAM_TOOLSET) = INTELC\n", "{\n", "actions updated together piecemeal Archive\n", "{\n", "if exist $(<) set _$(<:B)_=$(<)\n", "$(AR) /out:$(<) %_$(<:B)_% $(>)\n", "}\n", "\n", "actions As\n", "{\n", "$(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) /c /Fo$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) /c /Fo$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp$(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME\n", "{\n", "$(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "}\n", "else if $(JAM_TOOLSET) = VISUALC16\n", "{\n", "actions updated together piecemeal Archive\n", "{\n", "$(AR) $(<) -+$(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) /c /Fo$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) /c /Fo$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Tp$(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME\n", "{\n", "$(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "}\n", "else if $(JAM_TOOLSET) = BORLANDC\n", "{\n", "actions updated together piecemeal Archive\n", "{\n", "$(AR) $(<) -+$(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)\n", "}\n", "\n", "actions DllLink bind NEEDLIBS DEFFILENAME\n", "{\n", "$(ILINK) $(LINKFLAGS) $(>) , $(<) ,, $(LINKLIBS:E) $(NEEDLIBS:E) , $(DEFFILENAME)\n", "}\n", "\n", "actions DllImplib bind DEFFILENAME\n", "{\n", "$(IMPLIB) -a $(<) $(>) $(DEFFILENAME)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) -c -o$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) -c -o$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "}\n", "else if $(JAM_TOOLSET) = MINGW\n", "{\n", "actions together piecemeal Archive\n", "{\n", "$(AR) $(<) $(>:T)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)\n", "}\n", "\n", "actions DllLink bind DEFFILENAME IMPLIBNAME\n", "{\n", "$(LINK) $(LINKFLAGS) -shared -o $(<) $(>) $(DEFFILENAME) -Wl,--out-implib,$(IMPLIBNAME)\n", "}\n", "}\n", "else if $(JAM_TOOLSET) = WATCOM\n", "{\n", "actions together piecemeal Archive\n", "{\n", "$(AR) -q $(<) +-$(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo=$(<) -I$(STDHDRS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo=$(<) -I$(STDHDRS) $(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME\n", "{\n", "$(LINK) $(LINKFLAGS) -l=NT_DLL -\"export=$(DEFFILENAME) option implib=$(IMPLIBNAME)\" /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions Shell\n", "{\n", "$(CP) $(>) $(<)\n", "}\n", "}\n", "else if $(JAM_TOOLSET) = LCC\n", "{\n", "actions together piecemeal Archive\n", "{\n", "$(AR) /out:$(<) $(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -Fo$(<) -I$(STDHDRS) $(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions DllLink bind NEEDLIBS DEFFILENAME\n", "{\n", "$(LINK) $(LINKFLAGS) -DLL -o $(<) $(UNDEFS) $(>) $(DEFFILENAME) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions ignore DllLinkMv\n", "{\n", "$(MV) $(2) $(1)\n", "}\n", "\n", "actions Shell\n", "{\n", "$(CP) $(>) $(<)\n", "}\n", "}\n", "else if $(JAM_TOOLSET) = DIGITALMARS\n", "{\n", "actions together piecemeal Archive\n", "{\n", "$(AR) $(<) $(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -o$(<) -I$(STDHDRS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -o$(<) -I$(STDHDRS) $(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) $(LINKFLAGS) $(>),$(<),NUL, $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME\n", "{\n", "$(LINK) $(LINKFLAGS) /IMPLIB:$(IMPLIBNAME) $(>) , $(<) ,NUL, $(LINKLIBS:E) $(NEEDLIBS:E) , $(DEFFILENAME)\n", "}\n", "\n", "actions Shell\n", "{\n", "$(CP) $(>) $(<)\n", "}\n", "}\n", "else if $(JAM_TOOLSET) = PELLESC\n", "{\n", "actions together piecemeal Archive\n", "{\n", "$(AR) /OUT:$(<) $(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo $(<) -I$(STDHDRS) $(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) $(LINKFLAGS) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME\n", "{\n", "$(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions Shell\n", "{\n", "$(CP) $(>) $(<)\n", "}\n", "}\n", "}\n", "\n", "\n", "else if $(OS2)\n", "{\n", "if $(JAM_TOOLSET) = WATCOM\n", "{\n", "actions together piecemeal Archive\n", "{\n", "$(AR) -q $(<) +-$(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) /Fo=$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) /Fo=$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) -q $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", "}\n", "\n", "actions Shell\n", "{\n", "$(CP) $(>) $(<)\n", "}\n", "}\n", "else if $(JAM_TOOLSET) = EMX\n", "{\n", "actions together piecemeal Archive\n", "{\n", "$(AR) $(<) $(>:T)\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "}\n", "}\n", "\n", "\n", "else if $(VMS)\n", "{\n", "actions updated together piecemeal Archive\n", "{\n", "lib/replace $(<) $(>[1]) ,$(>[2-])\n", "}\n", "\n", "actions Cc\n", "{\n", "$(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)\n", "}\n", "\n", "actions piecemeal together existing Clean\n", "{\n", "$(RM) $(>[1]);* ,$(>[2-]);*\n", "}\n", "\n", "actions together quietly CreLib\n", "{\n", "if f$search(\"$(<)\") .eqs. \"\" then lib/create $(<)\n", "}\n", "\n", "actions GenFile1\n", "{\n", "mcr $(>[1]) $(<) $(>[2-])\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK)/exe=$(<) $(LINKFLAGS) $(>:J=,) ,$(NEEDLIBS)/lib ,$(LINKLIBS)\n", "}\n", "\n", "actions quietly updated piecemeal together RmTemps\n", "{\n", "$(RM) $(>[1]);* ,$(>[2-]);*\n", "}\n", "\n", "actions Shell\n", "{\n", "$(CP) $(>) $(<)\n", "}\n", "}\n", "\n", "\n", "else if $(MAC)\n", "{\n", "actions together Archive\n", "{\n", "$(LINK) -library -o $(<) $(>)\n", "}\n", "\n", "actions Cc\n", "{\n", "set -e MWCincludes $(CCHDRS)\n", "$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(>)\n", "}\n", "\n", "actions C++\n", "{\n", "set -e MWCincludes $(CCHDRS)\n", "$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(>)\n", "}\n", "\n", "actions Link bind NEEDLIBS\n", "{\n", "$(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) \"$(LINKLIBS)\"\n", "}\n", "}\n", "\n", "if $(WIN98)\n", "{\n", "actions existing Clean\n", "{\n", "del $(>)\n", "}\n", "}\n", "\n", "\n", "rule BULK { Bulk $(<) : $(>) ; }\n", "rule FILE { File $(<) : $(>) ; }\n", "rule HDRRULE { HdrRule $(<) : $(>) ; }\n", "rule INSTALL { Install $(<) : $(>) ; }\n", "rule LIBRARY { Library $(<) : $(>) ; }\n", "rule LIBS { LinkLibraries $(<) : $(>) ; }\n", "rule LINK { Link $(<) : $(>) ; }\n", "rule MAIN { Main $(<) : $(>) ; }\n", "rule SETUID { Setuid $(<) ; }\n", "rule SHELL { Shell $(<) : $(>) ; }\n", "rule UNDEFINES { Undefines $(<) : $(>) ; }\n", "\n", "\n", "rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }\n", "rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }\n", "rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }\n", "\n", "\n", "rule addDirName { $(<) += [ FDirName $(>) ] ; }\n", "rule makeCommon { FStripCommon $(<) : $(>) ; }\n", "rule _makeCommon { FStripCommon $(<) : $(>) ; }\n", "rule makeDirName { $(<) = [ FDirName $(>) ] ; }\n", "rule makeGrist { $(<) = [ FGrist $(>) ] ; }\n", "rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }\n", "rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }\n", "rule makeString { $(<) = $(>:J) ; }\n", "rule makeSubDir { $(<) = [ FSubDir $(>) ] ; }\n", "rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }\n", "\n", "\n", "\n", "rule _PkgAppend\n", "{\n", "local result = $($(1)) ;\n", "local i ;\n", "\n", "for i in $(2)\n", "{\n", "if ! $(i) in $(result)\n", "{\n", "result += $(i) ;\n", "}\n", "}\n", "$(1) = $(result) ;\n", "}\n", "\n", "\n", "rule _PkgPrepend\n", "{\n", "local result = $($(1)) ;\n", "local i ;\n", "\n", "for i in $(2)\n", "{\n", "if ! $(i) in $(result)\n", "{\n", "result = $(i) $(result) ;\n", "}\n", "}\n", "$(1) = $(result) ;\n", "}\n", "\n", "\n", "rule PkgBegin\n", "{\n", "if $(_PKG_NAME)\n", "{\n", "Echo \"nested package declarations are not allowed. please use\"\n", "Exit \"PkgEnd to finish\" $(_PKG_NAME)\"'s declaration\" ;\n", "}\n", "\n", "if ! $(PACKAGE_ROOT)\n", "{\n", "PACKAGE_ROOT = [ FDirName $(HOME) packages ] ;\n", "Echo \"PACKAGE_ROOT variable not set, using\" $(PACKAGE_ROOT) \"directory\" ;\n", "}\n", "\n", "_PKG_NAME = $(1[1]) ;\n", "_PKG_DESC = [ FDirName $(PACKAGE_ROOT) $(_PKG_NAME).pc ] ;\n", "_PKG_TOP = $(2) ;\n", "if ! $(_PKG_TOP)\n", "{\n", "_PKG_TOP = [ FDirName $(PACKAGE_ROOT) $(_PKG_NAME) ] ;\n", "}\n", "\n", "_PKG_ORG_HDRS = $(HDRS) ;\n", "_PKG_ORG_DEFINES = $(DEFINES) ;\n", "_PKG_ORG_LINKLIBS = $(LINKLIBS) ;\n", "_PKG_ORG_SUBDIRHDRS = $(SUBDIRHDRS) ;\n", "\n", "pkg-$(_PKG_NAME)-top = $(_PKG_TOP) ;\n", "\n", "_PKG_USES = ;\n", "_PKG_DEFINES = ;\n", "_PKG_INCLUDES = ;\n", "_PKG_LIBS = ;\n", "_PKG_DO_INSTALL = ;\n", "\n", "_PKG_ALL_USES = ;\n", "\n", "_PkgUpdate ;\n", "}\n", "\n", "\n", "rule PkgEnd\n", "{\n", "if $(_PKG_DO_INSTALL)\n", "{\n", "_PkgGeneratePc $(_PKG_DESC) ;\n", "PKG on $(_PKG_DESC) = $(_PKG_NAME) ;\n", "}\n", "\n", "HDRS = $(_PKG_ORG_HDRS) ;\n", "DEFINES = $(_PKG_ORG_DEFINES) ;\n", "LINKLIBS = $(_PKG_ORG_LINKLIBS) ;\n", "\n", "SUBDIRHDRS = $(_PKG_ORG_SUBDIRHDRS) ;\n", "\n", "_PKG_NAME = ;\n", "_PKG_DO_INSTALL = ;\n", "}\n", "\n", "rule _PkgReverse\n", "{\n", "local p ;\n", "\n", "result = $(1[1]) ;\n", "\n", "for p in $(1[2-])\n", "{\n", "result = $(p) $(result) ;\n", "}\n", "return $(result) ;\n", "}\n", "\n", "rule _PkgGeneratePc\n", "{\n", "MkDir $(PACKAGE_ROOT) ;\n", "Depends $(1) : $(PACKAGE_ROOT) ;\n", "Depends install : $(1) ;\n", "Clean uninstall : $(1) ;\n", "Always $(1) ; # always re-install, overwrite old version\n", "}\n", "\n", "if $(UNIX)\n", "{\n", "actions _PkgGeneratePc\n", "{\n", "echo \"# this file was generated automatically - do not edit\" > $(1)\n", "echo \"pkg-$(PKG)-uses = $(pkg-$(PKG)-uses) ;\" >> $(1)\n", "echo \"pkg-$(PKG)-libs = $(pkg-$(PKG)-libs:Q) ;\" >> $(1)\n", "echo \"pkg-$(PKG)-defines = $(pkg-$(PKG)-defines) ;\" >> $(1)\n", "echo \"pkg-$(PKG)-includes = $(pkg-$(PKG)-includes:Q) ;\" >> $(1)\n", "echo \"pkg-$(PKG)-ok = 1 ;\" >> $(1)\n", "}\n", "}\n", "else\n", "{\n", "actions _PkgGeneratePc\n", "{\n", "echo # this file was generated automatically - do not edit > $(1)\n", "echo pkg-$(PKG)-uses = $(pkg-$(PKG)-uses) ; >> $(1)\n", "echo pkg-$(PKG)-libs = $(pkg-$(PKG)-libs:Q) ; >> $(1)\n", "echo pkg-$(PKG)-defines = $(pkg-$(PKG)-defines) ; >> $(1)\n", "echo pkg-$(PKG)-includes = $(pkg-$(PKG)-includes:Q) ; >> $(1)\n", "echo pkg-$(PKG)-ok = 1 ; >> $(1)\n", "}\n", "}\n", "\n", "rule PkgInstallPc\n", "{\n", "}\n", "\n", "rule _PkgUpdate\n", "{\n", "local p z ;\n", "\n", "_PKG_ALL_DEFINES = ;\n", "_PKG_ALL_INCLUDES = ;\n", "_PKG_ALL_LIBS = ;\n", "_PKG_USE_LIBS = ;\n", "\n", "for p in $(_PKG_ALL_USES)\n", "{\n", "_PkgAppend _PKG_ALL_DEFINES : $(pkg-$(p)-defines) ;\n", "_PkgAppend _PKG_ALL_INCLUDES : $(pkg-$(p)-includes) ;\n", "}\n", "\n", "for p in [ _PkgReverse $(_PKG_ALL_USES) ]\n", "{\n", "local thelibs = $(pkg-$(p)-libs) ;\n", "\n", "_PKG_ALL_LIBS += $(thelibs) ;\n", "_PKG_USE_LIBS += $(thelibs[1]) ;\n", "}\n", "\n", "_PkgAppend _PKG_ALL_DEFINES : $(_PKG_DEFINES) ;\n", "_PkgAppend _PKG_ALL_INCLUDES : $(_PKG_INCLUDES) ;\n", "\n", "HDRS = $(_PKG_ORG_HDRS) $(_PKG_ALL_INCLUDES) ;\n", "DEFINES = $(_PKG_ORG_DEFINES) $(_PKG_ALL_DEFINES) ;\n", "LINKLIBS = $(_PKG_ORG_LINKLIBS) $(_PKG_ALL_LIBS) ;\n", "\n", "pkg-$(_PKG_NAME)-includes = $(_PKG_INCLUDES) ;\n", "pkg-$(_PKG_NAME)-defines = $(_PKG_DEFINES) ;\n", "pkg-$(_PKG_NAME)-uses = $(_PKG_USES) ;\n", "pkg-$(_PKG_NAME)-libs = $(_PKG_LIBS) ;\n", "}\n", "\n", "\n", "rule _PkgUses\n", "{\n", "local p ;\n", "\n", "for p in $(1)\n", "{\n", "if ! $(p) in $(_PKG_ALL_USES)\n", "{\n", "local pcfile = [ FDirName $(PACKAGE_ROOT) $(p).pc ] ;\n", "\n", "NoCare $(pcfile) ;\n", "include $(pcfile) ;\n", "\n", "if ! $(pkg-$(p)-ok)\n", "{\n", "$(2) += $(p) ;\n", "}\n", "else if $(pkg-$(p)-uses)\n", "{\n", "_PkgUses $(pkg-$(p)-uses) ;\n", "}\n", "_PKG_ALL_USES += $(p) ;\n", "}\n", "}\n", "}\n", "\n", "\n", "rule PkgUses\n", "{\n", "local pkg-missing = ;\n", "\n", "_PkgUses $(1) : pkg-missing ;\n", "\n", "if $(pkg-missing)\n", "{\n", "Exit \"Please install the following required packages:\" $(pkg-missing) ;\n", "}\n", "\n", "_PkgPrepend _PKG_USES : $(1) ;\n", "\n", "_PkgUpdate ;\n", "}\n", "\n", "\n", "rule _PkgMakeLocate\n", "{\n", "local top = $(3:E=$(DOT)) ;\n", "local dir file ss ;\n", "local dirs ;\n", "\n", "for ss in $(2)\n", "{\n", "file = [ FDirName $(top) $(ss:G=\"\") ] ;\n", "dir = $(1) ;\n", "\n", "if $(ss:D)\n", "{\n", "dir = [ FDirName $(dir) $(ss:D) ] ;\n", "}\n", "\n", "LOCATE on $(ss) = $(1) ;\n", "Depends $(ss) : $(dir) ;\n", "\n", "if ! $(dir) in $(dirs)\n", "{\n", "dirs += $(dir) ;\n", "}\n", "}\n", "\n", "MkDir $(dirs) ;\n", "}\n", "\n", "rule _PkgInstallInto\n", "{\n", "local sources = $(2) ;\n", "local targets = $(sources:G=$(INSTALLGRIST)) ;\n", "\n", "\n", "Depends install : $(targets) ;\n", "Clean uninstall : $(targets) ;\n", "\n", "_PkgMakeLocate $(1) : $(targets) : $(3) ;\n", "\n", "\n", "for s in $(sources)\n", "{\n", "local t = $(s:G=$(INSTALLGRIST)) ;\n", "\n", "Depends $(t) : $(s) ;\n", "\n", "SEARCH on $(s) = $(3) ;\n", "\n", "Install $(t) : $(s) ;\n", "Chmod $(t) ;\n", "\n", "if $(OWNER) && $(CHOWN)\n", "{\n", "Chown $(t) ;\n", "OWNER on $(t) = $(OWNER) ;\n", "}\n", "\n", "if $(GROUP) && $(CHGRP)\n", "{\n", "Chgrp $(t) ;\n", "GROUP on $(t) = $(GROUP) ;\n", "}\n", "}\n", "}\n", "\n", "rule _PkgInstallBin\n", "{\n", "local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;\n", "\n", "_PkgInstallInto $(<) : $(_t) : $(3) ;\n", "MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;\n", "}\n", "\n", "\n", "rule _PkgInstallShell\n", "{\n", "_PkgInstallInto $(1) : $(2) : $(3) ;\n", "MODE on $(2:G=$(INSTALLGRIST)) = $(SHELLMODE) ;\n", "}\n", "\n", "\n", "rule _PkgInstallFile\n", "{\n", "_PkgInstallInto $(1) : $(2) : $(3) ;\n", "MODE on $(2:G=$(INSTALLGRIST)) = $(FILEMODE) ;\n", "}\n", "\n", "rule PkgIncludes\n", "{\n", "_PKG_INCLUDES += $(1) ;\n", "_PkgUpdate ;\n", "}\n", "\n", "rule PkgDefines\n", "{\n", "_PKG_DEFINES += $(1) ;\n", "_PkgUpdate ;\n", "}\n", "\n", "rule PkgInstallHeader\n", "{\n", "local dir = [ FDirName $(_PKG_TOP) include ] ;\n", "\n", "_PKG_DO_INSTALL = 1 ;\n", "\n", "_PkgInstallFile [ FDirName $(dir) $(3) ] : $(1) : $(2) ;\n", "_PkgAppend _PKG_INCLUDES : $(dir) ;\n", "_PkgUpdate ;\n", "}\n", "\n", "rule PkgInstallLib\n", "{\n", "local lib = $(1:S=$(SUFLIB)) ;\n", "local dir = [ FDirName $(_PKG_TOP) lib ] ;\n", "\n", "_PKG_DO_INSTALL = 1 ;\n", "\n", "_PkgInstallFile $(dir) : $(lib) : $(DOT) ;\n", "_PkgPrepend _PKG_LIBS : [ FDirName $(dir) $(lib) ] ;\n", "_PkgUpdate ;\n", "}\n", "\n", "\n", "rule PkgNeedLib\n", "{\n", "_PkgAppend _PKG_LIBS : $(1) ;\n", "_PkgUpdate ;\n", "}\n", "\n", "\n", "rule PkgMain\n", "{\n", "MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", "Objects $(>) ;\n", "LINKLIBS on $(<:S=$(SUFEXE)) += $(LINKLIBS) ;\n", "Depends $(<:S=$(SUFEXE)) : $(_PKG_USE_LIBS) ;\n", "}\n", "\n", "\n", "rule PkgGlob\n", "{\n", "local files dir ;\n", "files = [ GLOB [ FDirName $(2) $(1) ] : $(3) ] ;\n", "dir = [ FDirName $(1) ] ;\n", "\n", "return $(files:D=$(dir)) ;\n", "}\n", "\n", "\n", "include $(JAMFILE) ;\n", 0 }; ftjam-2.5.2/lists.h0000744000424500003730000000444410441006345013726 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * lists.h - the LIST structure and routines to manipulate them * * The whole of jam relies on lists of strings as a datatype. This * module, in conjunction with newstr.c, handles these relatively * efficiently. * * Structures defined: * * LIST - list of strings * LOL - list of LISTs * * External routines: * * list_append() - append a list onto another one, returning total * list_new() - tack a string onto the end of a list of strings * list_copy() - copy a whole list of strings * list_sublist() - copy a subset of a list of strings * list_free() - free a list of strings * list_print() - print a list of strings to stdout * list_printq() - print a list of safely quoted strings to a file * list_length() - return the number of items in the list * * lol_init() - initialize a LOL (list of lists) * lol_add() - append a LIST onto an LOL * lol_free() - free the LOL and its LISTs * lol_get() - return one of the LISTs in the LOL * lol_print() - debug print LISTS separated by ":" * * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 08/23/94 (seiwald) - new list_append() * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 11/04/02 (seiwald) - const-ing for string literals * 12/09/02 (seiwald) - new list_printq() for writing lists to Jambase */ /* * LIST - list of strings */ typedef struct _list LIST; struct _list { LIST *next; LIST *tail; /* only valid in head node */ const char *string; /* private copy */ } ; /* * LOL - list of LISTs */ typedef struct _lol LOL; # define LOL_MAX 9 struct _lol { int count; LIST *list[ LOL_MAX ]; } ; LIST * list_append( LIST *l, LIST *nl ); LIST * list_copy( LIST *l, LIST *nl ); void list_free( LIST *head ); LIST * list_new( LIST *head, const char *string, int copy ); void list_print( LIST *l ); int list_length( LIST *l ); LIST * list_sublist( LIST *l, int start, int count ); # define list_next( l ) ((l)->next) # define L0 ((LIST *)0) void lol_add( LOL *lol, LIST *l ); void lol_init( LOL *lol ); void lol_free( LOL *lol ); LIST * lol_get( LOL *lol, int i ); void lol_print( LOL *lol ); ftjam-2.5.2/jamgram.y0000744000424500003730000002353210441006345014226 0ustar dturnermhpsys%token _LANGLE_t %token _LANGLE_EQUALS_t %token _EQUALS_t %token _RANGLE_t %token _RANGLE_EQUALS_t %token _BAR_t %token _BARBAR_t %token _SEMIC_t %token _COLON_t %token _BANG_t %token _BANG_EQUALS_t %token _QUESTION_EQUALS_t %token _LPAREN_t %token _RPAREN_t %token _LBRACKET_t %token _RBRACKET_t %token _LBRACE_t %token _RBRACE_t %token _AMPER_t %token _AMPERAMPER_t %token _PLUS_EQUALS_t %token ACTIONS_t %token BIND_t %token BREAK_t %token CASE_t %token CONTINUE_t %token DEFAULT_t %token ELSE_t %token EXISTING_t %token FOR_t %token IF_t %token IGNORE_t %token IN_t %token INCLUDE_t %token LOCAL_t %token MAXLINE_t %token ON_t %token PIECEMEAL_t %token QUIETLY_t %token RETURN_t %token RULE_t %token SWITCH_t %token TOGETHER_t %token UPDATED_t %token WHILE_t /* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * jamgram.yy - jam grammar * * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 06/01/94 (seiwald) - new 'actions existing' does existing sources * 08/23/94 (seiwald) - Support for '+=' (append to variable) * 08/31/94 (seiwald) - Allow ?= as alias for "default =". * 09/15/94 (seiwald) - if conditionals take only single arguments, so * that 'if foo == bar' gives syntax error (use =). * 02/11/95 (seiwald) - when scanning arguments to rules, only treat * punctuation keywords as keywords. All arg lists * are terminated with punctuation keywords. * 09/11/00 (seiwald) - Support for function calls; rules return LIST *. * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() * 01/24/01 (seiwald) - 'while' statement * 03/23/01 (seiwald) - "[ on target rule ]" support * 02/27/02 (seiwald) - un-break "expr : arg in list" syntax * 03/02/02 (seiwald) - rules can be invoked via variable names * 03/12/02 (seiwald) - set YYMAXDEPTH for big, right-recursive rules * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx * 06/21/02 (seiwald) - support for named parameters * 10/22/02 (seiwald) - working return/break/continue statements */ %token ARG STRING %left _BARBAR_t _BAR_t %left _AMPERAMPER_t _AMPER_t %left _EQUALS_t _BANG_EQUALS_t IN_t %left _LANGLE_t _LANGLE_EQUALS_t _RANGLE_t _RANGLE_EQUALS_t %left _BANG_t %{ #include "jam.h" #include "lists.h" #include "variable.h" #include "parse.h" #include "scan.h" #include "compile.h" #include "newstr.h" #include "rules.h" # define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ # define F0 (LIST *(*)(PARSE *, LOL *, int *))0 # define P0 (PARSE *)0 # define S0 (char *)0 # define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) # define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) # define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) # define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) # define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) # define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) # define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) # define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) # define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) # define pon( l,r ) parse_make( compile_on,l,r,P0,S0,S0,0 ) # define prule( a,p ) parse_make( compile_rule,a,p,P0,S0,S0,0 ) # define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) # define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) # define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) # define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) # define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) %} %% run : /* empty */ /* do nothing */ | rules { parse_save( $1.parse ); } ; /* * block - zero or more rules * rules - one or more rules * rule - any one of jam's rules * right-recursive so rules execute in order. */ block : /* empty */ { $$.parse = pnull(); } | rules { $$.parse = $1.parse; } ; rules : rule { $$.parse = $1.parse; } | rule rules { $$.parse = prules( $1.parse, $2.parse ); } | LOCAL_t list _SEMIC_t block { $$.parse = plocal( $2.parse, pnull(), $4.parse ); } | LOCAL_t list _EQUALS_t list _SEMIC_t block { $$.parse = plocal( $2.parse, $4.parse, $6.parse ); } ; rule : _LBRACE_t block _RBRACE_t { $$.parse = $2.parse; } | INCLUDE_t list _SEMIC_t { $$.parse = pincl( $2.parse ); } | arg lol _SEMIC_t { $$.parse = prule( $1.parse, $2.parse ); } | arg assign list _SEMIC_t { $$.parse = pset( $1.parse, $3.parse, $2.number ); } | arg ON_t list assign list _SEMIC_t { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } | BREAK_t list _SEMIC_t { $$.parse = pbreak( $2.parse, JMP_BREAK ); } | CONTINUE_t list _SEMIC_t { $$.parse = pbreak( $2.parse, JMP_CONTINUE ); } | RETURN_t list _SEMIC_t { $$.parse = pbreak( $2.parse, JMP_RETURN ); } | FOR_t ARG IN_t list _LBRACE_t block _RBRACE_t { $$.parse = pfor( $2.string, $4.parse, $6.parse ); } | SWITCH_t list _LBRACE_t cases _RBRACE_t { $$.parse = pswitch( $2.parse, $4.parse ); } | IF_t expr _LBRACE_t block _RBRACE_t { $$.parse = pif( $2.parse, $4.parse, pnull() ); } | IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } | WHILE_t expr _LBRACE_t block _RBRACE_t { $$.parse = pwhile( $2.parse, $4.parse ); } | RULE_t ARG params _LBRACE_t block _RBRACE_t { $$.parse = psetc( $2.string, $3.parse, $5.parse ); } | ON_t arg rule { $$.parse = pon( $2.parse, $3.parse ); } | ACTIONS_t eflags ARG bindlist _LBRACE_t { yymode( SCAN_STRING ); } STRING { yymode( SCAN_NORMAL ); } _RBRACE_t { $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); } ; /* * assign - = or += */ assign : _EQUALS_t { $$.number = VAR_SET; } | _PLUS_EQUALS_t { $$.number = VAR_APPEND; } | _QUESTION_EQUALS_t { $$.number = VAR_DEFAULT; } | DEFAULT_t _EQUALS_t { $$.number = VAR_DEFAULT; } ; /* * expr - an expression for if */ expr : arg { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); } | expr _EQUALS_t expr { $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); } | expr _BANG_EQUALS_t expr { $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); } | expr _LANGLE_t expr { $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); } | expr _LANGLE_EQUALS_t expr { $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); } | expr _RANGLE_t expr { $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); } | expr _RANGLE_EQUALS_t expr { $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); } | expr _AMPER_t expr { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } | expr _AMPERAMPER_t expr { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } | expr _BAR_t expr { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } | expr _BARBAR_t expr { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } | arg IN_t list { $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); } | _BANG_t expr { $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); } | _LPAREN_t expr _RPAREN_t { $$.parse = $2.parse; } ; /* * cases - action elements inside a 'switch' * case - a single action element inside a 'switch' * right-recursive rule so cases can be examined in order. */ cases : /* empty */ { $$.parse = P0; } | case cases { $$.parse = pnode( $1.parse, $2.parse ); } ; case : CASE_t ARG _COLON_t block { $$.parse = psnode( $2.string, $4.parse ); } ; /* * params - optional parameter names to rule definition * right-recursive rule so that params can be added in order. */ params : /* empty */ { $$.parse = P0; } | ARG _COLON_t params { $$.parse = psnode( $1.string, $3.parse ); } | ARG { $$.parse = psnode( $1.string, P0 ); } ; /* * lol - list of lists * right-recursive rule so that lists can be added in order. */ lol : list { $$.parse = pnode( P0, $1.parse ); } | list _COLON_t lol { $$.parse = pnode( $3.parse, $1.parse ); } ; /* * list - zero or more args in a LIST * listp - list (in puncutation only mode) * arg - one ARG or function call */ list : listp { $$.parse = $1.parse; yymode( SCAN_NORMAL ); } ; listp : /* empty */ { $$.parse = pnull(); yymode( SCAN_PUNCT ); } | listp arg { $$.parse = pappend( $1.parse, $2.parse ); } ; arg : ARG { $$.parse = plist( $1.string ); } | _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t { $$.parse = $3.parse; } ; /* * func - a function call (inside []) * This needs to be split cleanly out of 'rule' */ func : arg lol { $$.parse = prule( $1.parse, $2.parse ); } | ON_t arg arg lol { $$.parse = pon( $2.parse, prule( $3.parse, $4.parse ) ); } | ON_t arg RETURN_t list { $$.parse = pon( $2.parse, $4.parse ); } ; /* * eflags - zero or more modifiers to 'executes' * eflag - a single modifier to 'executes' */ eflags : /* empty */ { $$.number = 0; } | eflags eflag { $$.number = $1.number | $2.number; } ; eflag : UPDATED_t { $$.number = RULE_UPDATED; } | TOGETHER_t { $$.number = RULE_TOGETHER; } | IGNORE_t { $$.number = RULE_IGNORE; } | QUIETLY_t { $$.number = RULE_QUIETLY; } | PIECEMEAL_t { $$.number = RULE_PIECEMEAL; } | EXISTING_t { $$.number = RULE_EXISTING; } | MAXLINE_t ARG { $$.number = atoi( $2.string ) * RULE_MAXLINE; } ; /* * bindlist - list of variable to bind for an action */ bindlist : /* empty */ { $$.parse = pnull(); } | BIND_t list { $$.parse = $2.parse; } ; ftjam-2.5.2/execmac.c0000744000424500003730000000304510441006345014164 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * execunix.c - execute a shell script on UNIX * * If $(JAMSHELL) is defined, uses that to formulate execvp(). * The default is: * * /bin/sh -c % * * Each word must be an individual element in a jam variable value. * * In $(JAMSHELL), % expands to the command string and ! expands to * the slot number (starting at 1) for multiprocess (-j) invocations. * If $(JAMSHELL) doesn't include a %, it is tacked on as the last * argument. * * Don't just set JAMSHELL to /bin/sh - it won't work! * * External routines: * execcmd() - launch an async command execution * execwait() - wait and drive at most one execution completion * * Internal routines: * onintr() - bump intr to note command interruption * * 04/08/94 (seiwald) - Coherent/386 support added. * 05/04/94 (seiwald) - async multiprocess interface * 01/22/95 (seiwald) - $(JAMSHELL) support * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C */ # include "jam.h" # include "lists.h" # include "execcmd.h" # include # ifdef OS_MAC /* * execcmd() - launch an async command execution */ void execcmd( char *string, void (*func)( void *closure, int status ), void *closure, LIST *shell ) { printf( "%s", string ); (*func)( closure, EXEC_CMD_OK ); } /* * execwait() - wait and drive at most one execution completion */ int execwait() { return 0; } # endif /* OS_MAC */ ftjam-2.5.2/search.c0000744000424500003730000000323410441006346014025 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * search.c - find a target along $(SEARCH) or $(LOCATE) * * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "lists.h" # include "search.h" # include "timestamp.h" # include "pathsys.h" # include "variable.h" # include "newstr.h" const char * search( const char *target, time_t *time ) { PATHNAME f[1]; LIST *varlist; char buf[ MAXJPATH ]; /* Parse the filename */ path_parse( target, f ); f->f_grist.ptr = 0; f->f_grist.len = 0; if( varlist = var_get( "LOCATE" ) ) { f->f_root.ptr = varlist->string; f->f_root.len = strlen( varlist->string ); path_build( f, buf, 1 ); if( DEBUG_SEARCH ) printf( "locate %s: %s\n", target, buf ); timestamp( buf, time ); return newstr( buf ); } else if( varlist = var_get( "SEARCH" ) ) { while( varlist ) { f->f_root.ptr = varlist->string; f->f_root.len = strlen( varlist->string ); path_build( f, buf, 1 ); if( DEBUG_SEARCH ) printf( "search %s: %s\n", target, buf ); timestamp( buf, time ); if( *time ) return newstr( buf ); varlist = list_next( varlist ); } } /* Look for the obvious */ /* This is a questionable move. Should we look in the */ /* obvious place if SEARCH is set? */ f->f_root.ptr = 0; f->f_root.len = 0; path_build( f, buf, 1 ); if( DEBUG_SEARCH ) printf( "search %s: %s\n", target, buf ); timestamp( buf, time ); return newstr( buf ); } ftjam-2.5.2/filevms.c0000744000424500003730000001704710441006346014234 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * filevms.c - scan directories and libaries on VMS * * External routines: * * file_dirscan() - scan a directory for files * file_time() - get timestamp of file, if not done by file_dirscan() * file_archscan() - scan an archive for files * * File_dirscan() and file_archscan() call back a caller provided function * for each file found. A flag to this callback function lets file_dirscan() * and file_archscan() indicate that a timestamp is being provided with the * file. If file_dirscan() or file_archscan() do not provide the file's * timestamp, interested parties may later call file_time(). * * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length! * 05/03/96 (seiwald) - split into pathvms.c * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan * 03/23/01 (seiwald) - VMS C++ changes. * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "filesys.h" # include "pathsys.h" # ifdef OS_VMS # include # include # include # include # include # include # include #include #include #include #include #include #include /* Supply missing prototypes for lbr$-routines*/ extern "C" { int lbr$set_module( void **, unsigned long *, struct dsc$descriptor_s *, unsigned short *, void * ); int lbr$open( void **, struct dsc$descriptor_s *, void *, void *, void *, void *, void * ); int lbr$ini_control( void **, unsigned long *, unsigned long *, void * ); int lbr$get_index( void **, unsigned long *, int (*func)( struct dsc$descriptor_s *, unsigned long *), void * ); int lbr$close( void ** ); } static void file_cvttime( unsigned int *curtime, time_t *unixtime ) { static const size_t divisor = 10000000; static unsigned int bastim[2] = { 0x4BEB4000, 0x007C9567 }; /* 1/1/1970 */ int delta[2], remainder; lib$subx( curtime, bastim, delta ); lib$ediv( &divisor, delta, unixtime, &remainder ); } # define DEFAULT_FILE_SPECIFICATION "[]*.*;0" # define min( a,b ) ((a)<(b)?(a):(b)) void file_dirscan( const char *dir, scanback func, void *closure ) { struct FAB xfab; struct NAM xnam; struct XABDAT xab; char esa[256]; char filename[256]; char filename2[256]; char dirname[256]; register int status; PATHNAME f; memset( (char *)&f, '\0', sizeof( f ) ); f.f_root.ptr = dir; f.f_root.len = strlen( dir ); /* get the input file specification */ xnam = cc$rms_nam; xnam.nam$l_esa = esa; xnam.nam$b_ess = sizeof( esa ) - 1; xnam.nam$l_rsa = filename; xnam.nam$b_rss = min( sizeof( filename ) - 1, NAM$C_MAXRSS ); xab = cc$rms_xabdat; /* initialize extended attributes */ xab.xab$b_cod = XAB$C_DAT; /* ask for date */ xab.xab$l_nxt = NULL; /* terminate XAB chain */ xfab = cc$rms_fab; xfab.fab$l_dna = DEFAULT_FILE_SPECIFICATION; xfab.fab$b_dns = sizeof( DEFAULT_FILE_SPECIFICATION ) - 1; xfab.fab$l_fop = FAB$M_NAM; xfab.fab$l_fna = (char *)dir; /* address of file name */ xfab.fab$b_fns = strlen( dir ); /* length of file name */ xfab.fab$l_nam = &xnam; /* address of NAB block */ xfab.fab$l_xab = (char *)&xab; /* address of XAB block */ status = sys$parse( &xfab ); if( DEBUG_BINDSCAN ) printf( "scan directory %s\n", dir ); if ( !( status & 1 ) ) return; /* Add bogus directory for [000000] */ if( !strcmp( dir, "[000000]" ) ) { (*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ ); } /* Add bogus directory for [] */ if( !strcmp( dir, "[]" ) ) { (*func)( closure, "[]", 1 /* time valid */, 1 /* old but true */ ); (*func)( closure, "[-]", 1 /* time valid */, 1 /* old but true */ ); } while ( (status = sys$search( &xfab )) & 1 ) { char *s; time_t time; /* "I think that might work" - eml */ sys$open( &xfab ); sys$close( &xfab ); file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time ); filename[xnam.nam$b_rsl] = '\0'; /* What we do with the name depends on the suffix: */ /* .dir is a directory */ /* .xxx is a file with a suffix */ /* . is no suffix at all */ if( xnam.nam$b_type == 4 && !strncmp( xnam.nam$l_type, ".DIR", 4 ) ) { /* directory */ sprintf( dirname, "[.%.*s]", xnam.nam$b_name, xnam.nam$l_name ); f.f_dir.ptr = dirname; f.f_dir.len = strlen( dirname ); f.f_base.ptr = 0; f.f_base.len = 0; f.f_suffix.ptr = 0; f.f_suffix.len = 0; } else { /* normal file with a suffix */ f.f_dir.ptr = 0; f.f_dir.len = 0; f.f_base.ptr = xnam.nam$l_name; f.f_base.len = xnam.nam$b_name; f.f_suffix.ptr = xnam.nam$l_type; f.f_suffix.len = xnam.nam$b_type; } path_build( &f, filename2, 0 ); /* if( DEBUG_SEARCH ) printf("root '%s' base %.*s suf %.*s = %s\n", dir, xnam.nam$b_name, xnam.nam$l_name, xnam.nam$b_type, xnam.nam$l_type, filename2); */ (*func)( closure, filename2, 1 /* time valid */, time ); } } int file_time( const char *filename, time_t *time ) { /* This should never be called, as all files are */ /* timestampped in file_dirscan() and file_archscan() */ return -1; } static char *VMS_archive = 0; static scanback VMS_func; static void *VMS_closure; static void *context; static int file_archmember( struct dsc$descriptor_s *module, unsigned long *rfa ) { static struct dsc$descriptor_s bufdsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; struct mhddef *mhd; char filename[128]; char buf[ MAXJPATH ]; int status; time_t library_date; register int i; register char *p; bufdsc.dsc$a_pointer = filename; bufdsc.dsc$w_length = sizeof( filename ); status = lbr$set_module( &context, rfa, &bufdsc, &bufdsc.dsc$w_length, NULL ); if ( !(status & 1) ) return ( 1 ); mhd = (struct mhddef *)filename; file_cvttime( &mhd->mhd$l_datim, &library_date ); for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; i++, p++ ) filename[i] = *p; filename[i] = '\0'; sprintf( buf, "%s(%s.obj)", VMS_archive, filename ); (*VMS_func)( VMS_closure, buf, 1 /* time valid */, (time_t)library_date ); return ( 1 ); } void file_archscan( const char *archive, scanback func, void *closure ) { static struct dsc$descriptor_s library = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; unsigned long lfunc = LBR$C_READ; unsigned long typ = LBR$C_TYP_UNK; unsigned long index = 1; register int status; VMS_archive = (char *)archive; VMS_func = func; VMS_closure = closure; status = lbr$ini_control( &context, &lfunc, &typ, NULL ); if ( !( status & 1 ) ) return; library.dsc$a_pointer = (char *)archive; library.dsc$w_length = strlen( archive ); status = lbr$open( &context, &library, NULL, NULL, NULL, NULL, NULL ); if ( !( status & 1 ) ) return; (void) lbr$get_index( &context, &index, file_archmember, NULL ); (void) lbr$close( &context ); } # endif /* VMS */ ftjam-2.5.2/jambase.h0000744000424500003730000000060410441006346014165 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * jambase.h - declaration for the internal jambase * * The file Jambase is turned into a C array of strings in jambase.c * so that it can be built in to the executable. This is the * declaration for that array. */ extern char *jambase[]; ftjam-2.5.2/parse.c0000744000424500003730000000432310441006347013673 0ustar dturnermhpsys/* * Copyright 1993, 2000 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * parse.c - make and destroy parse trees as driven by the parser * * 09/07/00 (seiwald) - ref count on PARSE to avoid freeing when used, * as per Matt Armstrong. * 09/11/00 (seiwald) - structure reworked to reflect that (*func)() * returns a LIST *. * 10/22/02 (seiwald) - working return/break/continue statements * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "lists.h" # include "parse.h" # include "scan.h" # include "newstr.h" static PARSE *yypsave; void parse_file( const char *f ) { /* Suspend scan of current file */ /* and push this new file in the stream */ yyfparse(f); /* Now parse each block of rules and execute it. */ /* Execute it outside of the parser so that recursive */ /* calls to yyrun() work (no recursive yyparse's). */ for(;;) { LOL l; PARSE *p; int jmp = 0; /* JMP_NONE */ /* $(<) and $(>) empty in outer scope. */ lol_init( &l ); /* Filled by yyparse() calling parse_save() */ yypsave = 0; /* If parse error or empty parse, outta here */ if( yyparse() || !( p = yypsave ) ) break; /* Run the parse tree. */ list_free( (*(p->func))( p, &l, &jmp ) ); parse_free( p ); } } void parse_save( PARSE *p ) { yypsave = p; } PARSE * parse_make( LIST *(*func)( PARSE *p, LOL *args, int *jmp ), PARSE *left, PARSE *right, PARSE *third, const char *string, const char *string1, int num ) { PARSE *p = (PARSE *)malloc( sizeof( PARSE ) ); p->func = func; p->left = left; p->right = right; p->third = third; p->string = string; p->string1 = string1; p->num = num; p->refs = 1; return p; } void parse_refer( PARSE *p ) { ++p->refs; } void parse_free( PARSE *p ) { if( --p->refs ) return; if( p->string ) freestr( p->string ); if( p->string1 ) freestr( p->string1 ); if( p->left ) parse_free( p->left ); if( p->right ) parse_free( p->right ); if( p->third ) parse_free( p->third ); free( (char *)p ); } ftjam-2.5.2/search.h0000744000424500003730000000047310441006347014035 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * search.h - find a target along $(SEARCH) or $(LOCATE) * * 11/04/02 (seiwald) - const-ing for string literals */ const char *search( const char *target, time_t *time ); ftjam-2.5.2/README0000744000424500003730000000565010441006347013301 0ustar dturnermhpsys============================================================================= This if "FT-Jam", a simple derivative of the Jam build tool, based and 100% compatible with Jam 2.5. See http://www.freetype.org/jam/ for more details. This is a non-official release of FT-Jam, dubbed 2.5.1 at the moment. Note that you'll find the original Jam README in the file README.ORG Installation on Unix (and Cygwin): ---------------------------------- Unlike Classic Jam, this release can be installed with traditionnal Unix commands, i.e.: ./configure make make install (may need to be root) at the moment, only the 'jam' executable is installed in $prefix/bin. we'll try to install the documentation and convert it to manpages later, if time permits. If the './configure' command doesn't work, do the following, you might have a working source release that wasn't packaged for distribution. You can get it to install normally doing the following: chmod +x configure chmod +x yyacc cd builds/unix autoconf cd ../.. then ./configure make make install Installation on Win32: ---------------------- We provide a few build scripts for various compilers on Win32. In all cases, this will generate an executable named 'jam.exe' within the bin.ntx86 directory: Visual C++: set JAM_TOOLSET=VISUALC nmake -f builds\win32-visualc.mk Borland C++: set JAM_TOOLSET=BORLANDC make -fbuilds\win32-borlandc.mk Mingw: set JAM_TOOLSET=MINGW make -f builds/win32-gcc.mk Digital Mars: set JAM_TOOLSET=DIGITALMARS make -f builds\win32-dmars.mk Cygwin: make -f builds/win32-cygwin.mk Copy the executable to your path. ============================================================================== IMPORTANT FOR CYGWIN AND MINGW USERS: Note that the Mingw and Cygwin builds produce different executables !! the first one will only work correctly on the Windows command line, while the second one will only work on a Unix shell (e.g. Bash). =============================================================================== Installation with Jam or FT-Jam: -------------------------------- If you already have a previous version of Jam or FT-Jam in your path, simply invoke it from the root directory. This will generate the 'jam' or 'jam.exe' executable in a directory named 'bin.', where '' depends on your platform, e.g. bin.linuxx86, bin.ntx86, etc... Differences with Classic Jam: ----------------------------- Sorry, there is no official documentation at the moment. You can however parse the 'Jambase' file, since documentation comments have been added to all important rules. Troubleshooting: ---------------- Please report problems to the Jam mailing list (jamming@perforce.com). We'll try to create a FT-Jam specific list in the future. ftjam-2.5.2/make.c0000744000424500003730000003443710441006350013501 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * make.c - bring a target up to date, once rules are in place * * This modules controls the execution of rules to bring a target and * its dependencies up to date. It is invoked after the targets, rules, * et. al. described in rules.h are created by the interpreting of the * jam files. * * This file contains the main make() entry point and the first pass * make0(). The second pass, make1(), which actually does the command * execution, is in make1.c. * * External routines: * make() - make a target, given its name * * Internal routines: * make0() - bind and scan everything to make a TARGET * make0sort() - reorder TARGETS chain by their time (newest to oldest) * * 12/26/93 (seiwald) - allow NOTIME targets to be expanded via $(<), $(>) * 01/04/94 (seiwald) - print all targets, bounded, when tracing commands * 04/08/94 (seiwald) - progress report now reflects only targets with actions * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET. * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. * 12/20/94 (seiwald) - make0() headers after determining fate of target, so * that headers aren't seen as dependents on themselves. * 01/19/95 (seiwald) - distinguish between CANTFIND/CANTMAKE targets. * 02/02/95 (seiwald) - propagate leaf source time for new LEAVES rule. * 02/14/95 (seiwald) - NOUPDATE rule means don't update existing target. * 08/22/95 (seiwald) - NOUPDATE targets immune to anyhow (-a) flag. * 09/06/00 (seiwald) - NOCARE affects targets with sources/actions. * 03/02/01 (seiwald) - reverse NOCARE change. * 03/14/02 (seiwald) - TEMPORARY targets no longer take on parents age * 03/16/02 (seiwald) - support for -g (reorder builds by source time) * 07/17/02 (seiwald) - TEMPORARY sources for headers now get built * 09/19/02 (seiwald) - new -d displays * 09/23/02 (seiwald) - suppress "...using temp..." in default output * 09/28/02 (seiwald) - make0() takes parent pointer; new -dc display * 11/04/02 (seiwald) - const-ing for string literals * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars * 01/03/03 (seiwald) - T_FATE_NEWER once again gets set with missing parent * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET * 04/04/03 (seiwald) - fix INTERNAL node binding to avoid T_BIND_PARENTS * 04/14/06 (kaib) - fix targets to show in 'updated' when their includes * are newer */ # include "jam.h" # include "lists.h" # include "parse.h" # include "variable.h" # include "rules.h" # include "search.h" # include "newstr.h" # include "make.h" # include "headers.h" # include "command.h" # ifndef max # define max( a,b ) ((a)>(b)?(a):(b)) # endif typedef struct { int temp; int updating; int cantfind; int cantmake; int targets; int made; } COUNTS ; static void make0( TARGET *t, TARGET *p, int depth, COUNTS *counts, int anyhow ); static TARGETS *make0sort( TARGETS *c ); static const char *target_fate[] = { "init", /* T_FATE_INIT */ "making", /* T_FATE_MAKING */ "stable", /* T_FATE_STABLE */ "newer", /* T_FATE_NEWER */ "temp", /* T_FATE_ISTMP */ "touched", /* T_FATE_TOUCHED */ "missing", /* T_FATE_MISSING */ "needtmp", /* T_FATE_NEEDTMP */ "old", /* T_FATE_OUTDATED */ "update", /* T_FATE_UPDATE */ "nofind", /* T_FATE_CANTFIND */ "nomake" /* T_FATE_CANTMAKE */ } ; static const char *target_bind[] = { "unbound", "missing", "parents", "exists", } ; # define spaces(x) ( " " + 16 - ( x > 16 ? 16 : x ) ) /* * make() - make a target, given its name */ int make( int n_targets, const char **targets, int anyhow ) { int i; COUNTS counts[1]; int status = 0; /* 1 if anything fails */ memset( (char *)counts, 0, sizeof( *counts ) ); for( i = 0; i < n_targets; i++ ) { TARGET *t = bindtarget( targets[i] ); make0( t, 0, 0, counts, anyhow ); } if( DEBUG_MAKE ) { if( counts->targets ) printf( "...found %d target(s)...\n", counts->targets ); if( counts->temp ) printf( "...using %d temp target(s)...\n", counts->temp ); if( counts->updating ) printf( "...updating %d target(s)...\n", counts->updating ); if( counts->cantfind ) printf( "...can't find %d target(s)...\n", counts->cantfind ); if( counts->cantmake ) printf( "...can't make %d target(s)...\n", counts->cantmake ); } status = counts->cantfind || counts->cantmake; for( i = 0; i < n_targets; i++ ) status |= make1( bindtarget( targets[i] ) ); return status; } /* * make0() - bind and scan everything to make a TARGET * * Make0() recursively binds a target, searches for #included headers, * calls itself on those headers, and calls itself on any dependents. */ static void make0( TARGET *t, TARGET *p, /* parent */ int depth, /* for display purposes */ COUNTS *counts, /* for reporting */ int anyhow ) /* forcibly touch all (real) targets */ { TARGETS *c, *d, *incs; TARGET *ptime = t; time_t last, leaf, hlast; int fate; const char *flag = ""; SETTINGS *s; /* * Step 1: initialize */ if( DEBUG_MAKEPROG ) printf( "make\t--\t%s%s\n", spaces( depth ), t->name ); t->fate = T_FATE_MAKING; /* * Step 2: under the influence of "on target" variables, * bind the target and search for headers. */ /* Step 2a: set "on target" variables. */ s = copysettings( t->settings ); pushsettings( s ); /* Step 2b: find and timestamp the target file (if it's a file). */ if( t->binding == T_BIND_UNBOUND && !( t->flags & T_FLAG_NOTFILE ) ) { t->boundname = search( t->name, &t->time ); t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING; } /* INTERNAL, NOTFILE header nodes have the time of their parents */ if( p && t->flags & T_FLAG_INTERNAL ) ptime = p; /* If temp file doesn't exist but parent does, use parent */ if( p && t->flags & T_FLAG_TEMP && t->binding == T_BIND_MISSING && p->binding != T_BIND_MISSING ) { t->binding = T_BIND_PARENTS; ptime = p; } /* Step 2c: If its a file, search for headers. */ if( t->binding == T_BIND_EXISTS ) headers( t ); /* Step 2d: reset "on target" variables */ popsettings( s ); freesettings( s ); /* * Pause for a little progress reporting */ if( DEBUG_MAKEPROG ) { if( strcmp( t->name, t->boundname ) ) { printf( "bind\t--\t%s%s: %s\n", spaces( depth ), t->name, t->boundname ); } switch( t->binding ) { case T_BIND_UNBOUND: case T_BIND_MISSING: case T_BIND_PARENTS: printf( "time\t--\t%s%s: %s\n", spaces( depth ), t->name, target_bind[ t->binding ] ); break; case T_BIND_EXISTS: printf( "time\t--\t%s%s: %s", spaces( depth ), t->name, ctime( &t->time ) ); break; } } /* * Step 3: recursively make0() dependents & headers */ /* Step 3a: recursively make0() dependents */ for( c = t->depends; c; c = c->next ) { int internal = t->flags & T_FLAG_INTERNAL; if( DEBUG_DEPENDS ) printf( "%s \"%s\" : \"%s\" ;\n", internal ? "Includes" : "Depends", t->name, c->target->name ); /* Warn about circular deps, except for includes, */ /* which include each other alot. */ if( c->target->fate == T_FATE_INIT ) make0( c->target, ptime, depth + 1, counts, anyhow ); else if( c->target->fate == T_FATE_MAKING && !internal ) printf( "warning: %s depends on itself\n", c->target->name ); } /* Step 3b: recursively make0() internal includes node */ if( t->includes ) make0( t->includes, p, depth + 1, counts, anyhow ); /* Step 3c: add dependents' includes to our direct dependencies */ incs = 0; for( c = t->depends; c; c = c->next ) if( c->target->includes ) { incs = targetentry( incs, c->target->includes ); /* If the includes are newer than we are their original target also needs to be marked newer. This is needed so that 'updated' correctly will include the original target in the $(<) variable. */ if(c->target->includes->time > t->time) c->target->fate = max(T_FATE_NEWER, c->target->fate); } t->depends = targetchain( t->depends, incs ); /* * Step 4: compute time & fate */ /* Step 4a: pick up dependents' time and fate */ last = 0; leaf = 0; fate = T_FATE_STABLE; for( c = t->depends; c; c = c->next ) { /* If LEAVES has been applied, we only heed the timestamps of */ /* the leaf source nodes. */ leaf = max( leaf, c->target->leaf ); if( t->flags & T_FLAG_LEAVES ) { last = leaf; continue; } last = max( last, c->target->time ); fate = max( fate, c->target->fate ); } /* Step 4b: pick up included headers time */ /* * If a header is newer than a temp source that includes it, * the temp source will need building. */ hlast = t->includes ? t->includes->time : 0; /* Step 4c: handle NOUPDATE oddity */ /* * If a NOUPDATE file exists, make dependents eternally old. * Don't inherit our fate from our dependents. Decide fate * based only upon other flags and our binding (done later). */ if( t->flags & T_FLAG_NOUPDATE ) { last = 0; t->time = 0; fate = T_FATE_STABLE; } /* Step 4d: determine fate: rebuild target or what? */ /* In English: If can't find or make child, can't make target. If children changed, make target. If target missing, make it. If children newer, make target. If temp's children newer than parent, make temp. If temp's headers newer than parent, make temp. If deliberately touched, make it. If up-to-date temp file present, use it. If target newer than non-notfile parent, mark target newer. Otherwise, stable! Note this block runs from least to most stable: as we make it further down the list, the target's fate is getting stabler. */ if( fate >= T_FATE_BROKEN ) { fate = T_FATE_CANTMAKE; } else if( fate >= T_FATE_SPOIL ) { fate = T_FATE_UPDATE; } else if( t->binding == T_BIND_MISSING ) { fate = T_FATE_MISSING; } else if( t->binding == T_BIND_EXISTS && last > t->time ) { fate = T_FATE_OUTDATED; } else if( t->binding == T_BIND_PARENTS && last > p->time ) { fate = T_FATE_NEEDTMP; } else if( t->binding == T_BIND_PARENTS && hlast > p->time ) { fate = T_FATE_NEEDTMP; } else if( t->flags & T_FLAG_TOUCHED ) { fate = T_FATE_TOUCHED; } else if( anyhow && !( t->flags & T_FLAG_NOUPDATE ) ) { fate = T_FATE_TOUCHED; } else if( t->binding == T_BIND_EXISTS && t->flags & T_FLAG_TEMP ) { fate = T_FATE_ISTMP; } else if( t->binding == T_BIND_EXISTS && p && p->binding != T_BIND_UNBOUND && t->time > p->time ) { fate = T_FATE_NEWER; } else { fate = T_FATE_STABLE; } /* Step 4e: handle missing files */ /* If it's missing and there are no actions to create it, boom. */ /* If we can't make a target we don't care about, 'sokay */ /* We could insist that there are updating actions for all missing */ /* files, but if they have dependents we just pretend it's NOTFILE. */ if( fate == T_FATE_MISSING && !t->actions && !t->depends ) { if( t->flags & T_FLAG_NOCARE ) { fate = T_FATE_STABLE; } else { printf( "don't know how to make %s\n", t->name ); fate = T_FATE_CANTFIND; } } /* Step 4f: propagate dependents' time & fate. */ /* Set leaf time to be our time only if this is a leaf. */ t->time = max( t->time, last ); t->leaf = leaf ? leaf : t->time ; t->fate = fate; /* * Step 5: sort dependents by their update time. */ if( globs.newestfirst ) t->depends = make0sort( t->depends ); /* * Step 6: a little harmless tabulating for tracing purposes */ /* Don't count or report interal includes nodes. */ if( t->flags & T_FLAG_INTERNAL ) return; if( !( ++counts->targets % 1000 ) && DEBUG_MAKE ) printf( "...patience...\n" ); if( fate == T_FATE_ISTMP ) counts->temp++; else if( fate == T_FATE_CANTFIND ) counts->cantfind++; else if( fate == T_FATE_CANTMAKE && t->actions ) counts->cantmake++; else if( fate >= T_FATE_BUILD && fate < T_FATE_BROKEN && t->actions ) counts->updating++; if( !( t->flags & T_FLAG_NOTFILE ) && fate >= T_FATE_SPOIL ) flag = "+"; else if( t->binding == T_BIND_EXISTS && p && t->time > p->time ) flag = "*"; if( DEBUG_MAKEPROG ) printf( "made%s\t%s\t%s%s\n", flag, target_fate[ t->fate ], spaces( depth ), t->name ); if( DEBUG_CAUSES && t->fate >= T_FATE_NEWER && t->fate <= T_FATE_MISSING ) printf( "%s %s\n", target_fate[ t->fate ], t->name ); } /* * make0sort() - reorder TARGETS chain by their time (newest to oldest) */ static TARGETS * make0sort( TARGETS *chain ) { TARGETS *result = 0; /* We walk chain, taking each item and inserting it on the */ /* sorted result, with newest items at the front. This involves */ /* updating each TARGETS' c->next and c->tail. Note that we */ /* make c->tail a valid prev pointer for every entry. Normally, */ /* it is only valid at the head, where prev == tail. Note also */ /* that while tail is a loop, next ends at the end of the chain. */ /* Walk current target list */ while( chain ) { TARGETS *c = chain; TARGETS *s = result; chain = chain->next; /* Find point s in result for c */ while( s && s->target->time > c->target->time ) s = s->next; /* Insert c in front of s (might be 0). */ /* Don't even think of deciphering this. */ c->next = s; /* good even if s = 0 */ if( result == s ) result = c; /* new head of chain? */ if( !s ) s = result; /* wrap to ensure a next */ if( result != c ) s->tail->next = c; /* not head? be prev's next */ c->tail = s->tail; /* take on next's prev */ s->tail = c; /* make next's prev us */ } return result; } ftjam-2.5.2/common.mk0000744000424500003730000000076510441006350014236 0ustar dturnermhpsys# Common Makefile rules # # the Jam sources needed to build "jam0" # SOURCES = \ builtins.c command.c compile.c execnt.c execunix.c execvms.c expand.c \ filent.c fileos2.c fileunix.c filevms.c glob.c hash.c \ hdrmacro.c headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c \ newstr.c option.c parse.c pathunix.c pathvms.c regexp.c \ rules.c scan.c search.c timestamp.c variable.c # the bootstrap "jam0" build tool # jam0: $(CC) $(TARGET) $(CFLAGS) $(SOURCES) $(LINKLIBS) ftjam-2.5.2/command.c0000744000424500003730000000226210441006350014171 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * command.c - maintain lists of commands * * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C * 09/08/00 (seiwald) - bulletproof PIECEMEAL size computation */ # include "jam.h" # include "lists.h" # include "parse.h" # include "variable.h" # include "rules.h" # include "command.h" /* * cmd_new() - return a new CMD or 0 if too many args */ CMD * cmd_new( RULE *rule, LIST *targets, LIST *sources, LIST *shell, int maxline ) { CMD *cmd = (CMD *)malloc( sizeof( CMD ) ); cmd->rule = rule; cmd->shell = shell; cmd->next = 0; lol_init( &cmd->args ); lol_add( &cmd->args, targets ); lol_add( &cmd->args, sources ); /* Bail if the result won't fit in maxline */ /* We don't free targets/sources/shell if bailing. */ if( var_string( rule->actions, cmd->buf, maxline, &cmd->args ) < 0 ) { cmd_free( cmd ); return 0; } return cmd; } /* * cmd_free() - free a CMD */ void cmd_free( CMD *cmd ) { lol_free( &cmd->args ); list_free( cmd->shell ); free( (char *)cmd ); } ftjam-2.5.2/parse.h0000744000424500003730000000160210441006351013670 0ustar dturnermhpsys/* * Copyright 1993, 2000 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * parse.h - make and destroy parse trees as driven by the parser * * 10/22/02 (seiwald) - working return/break/continue statements * 11/04/02 (seiwald) - const-ing for string literals */ /* * parse tree node */ typedef struct _PARSE PARSE; struct _PARSE { LIST *(*func)( PARSE *p, LOL *args, int *jmp ); PARSE *left; PARSE *right; PARSE *third; const char *string; const char *string1; int num; int refs; } ; void parse_file( const char *f ); void parse_save( PARSE *p ); PARSE * parse_make( LIST *(*func)( PARSE *p, LOL *args, int *jmp ), PARSE *left, PARSE *right, PARSE *third, const char *string, const char *string1, int num ); void parse_refer( PARSE *p ); void parse_free( PARSE *p ); ftjam-2.5.2/make.h0000744000424500003730000000053610441006351013500 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * make.h - bring a target up to date, once rules are in place * * 11/04/02 (seiwald) - const-ing for string literals */ int make( int n_targets, const char **targets, int anyhow ); int make1( TARGET *t ); ftjam-2.5.2/expand.c0000744000424500003730000003310010441006351014026 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * expand.c - expand a buffer, given variable values * * External routines: * * var_expand() - variable-expand input string into list of strings * * Internal routines: * * var_edit_parse() - parse : modifiers into PATHNAME structure * var_edit_file() - copy input target name to output, modifying filename * var_edit_shift() - do upshift/downshift mods * * 01/25/94 (seiwald) - $(X)$(UNDEF) was expanding like plain $(X) * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C * 01/11/01 (seiwald) - added support for :E=emptyvalue, :J=joinval * 01/13/01 (seiwald) - :UDJE work on non-filename strings * 02/19/01 (seiwald) - make $($(var):J=x) join multiple values of var * 01/25/02 (seiwald) - fixed broken $(v[1-]), by ian godin * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 11/04/02 (seiwald) - const-ing for string literals * 12/30/02 (armstrong) - fix out-of-bounds access in var_expand() */ # include "jam.h" # include "lists.h" # include "variable.h" # include "expand.h" # include "pathsys.h" # include "newstr.h" typedef struct { PATHNAME f; /* :GDBSMR -- pieces */ char parent; /* :P -- go to parent directory */ char filemods; /* one of the above applied */ char downshift; /* :L -- downshift result */ char upshift; /* :U -- upshift result */ char quote; /* :Q -- quote */ PATHPART empty; /* :E -- default for empties */ PATHPART join; /* :J -- join list with char */ } VAR_EDITS ; static void var_edit_parse( const char *mods, VAR_EDITS *edits ); static void var_edit_file( const char *in, char *out, VAR_EDITS *edits ); static void var_edit_shift( char *out, VAR_EDITS *edits ); static void var_edit_quote( char* out ); # define MAGIC_COLON '\001' # define MAGIC_LEFT '\002' # define MAGIC_RIGHT '\003' /* * var_expand() - variable-expand input string into list of strings * * Would just copy input to output, performing variable expansion, * except that since variables can contain multiple values the result * of variable expansion may contain multiple values (a list). Properly * performs "product" operations that occur in "$(var1)xxx$(var2)" or * even "$($(var2))". * * Returns a newly created list. */ LIST * var_expand( LIST *l, const char *in, const char *end, LOL *lol, int cancopyin ) { char out_buf[ MAXSYM ]; char *out = out_buf; const char *inp = in; char *ov; /* for temp copy of variable in outbuf */ int depth; if( DEBUG_VAREXP ) printf( "expand '%.*s'\n", end - in, in ); /* This gets alot of cases: $(<) and $(>) */ if( end - in == 4 && in[0] == '$' && in[1] == '(' && in[3] == ')' ) { switch( in[2] ) { case '1': case '<': return list_copy( l, lol_get( lol, 0 ) ); case '2': case '>': return list_copy( l, lol_get( lol, 1 ) ); } } /* Just try simple copy of in to out. */ while( in < end ) if( ( *out++ = *in++ ) == '$' && *in == '(' ) goto expand; /* No variables expanded - just add copy of input string to list. */ /* Cancopyin is an optimization: if the input was already a list */ /* item, we can use the copystr() to put it on the new list. */ /* Otherwise, we use the slower newstr(). */ *out = '\0'; if( cancopyin ) return list_new( l, inp, 1 ); else return list_new( l, out_buf, 0 ); expand: /* * Input so far (ignore blanks): * * stuff-in-outbuf $(variable) remainder * ^ ^ * in end * Output so far: * * stuff-in-outbuf $ * ^ ^ * out_buf out * * * We just copied the $ of $(...), so back up one on the output. * We now find the matching close paren, copying the variable and * modifiers between the $( and ) temporarily into out_buf, so that * we can replace :'s with MAGIC_COLON. This is necessary to avoid * being confused by modifier values that are variables containing * :'s. Ugly. */ depth = 1; out--, in++; ov = out; while( in < end && depth ) { switch( *ov++ = *in++ ) { case '(': depth++; break; case ')': depth--; break; case ':': ov[-1] = MAGIC_COLON; break; case '[': ov[-1] = MAGIC_LEFT; break; case ']': ov[-1] = MAGIC_RIGHT; break; } } /* Copied ) - back up. */ ov--; /* * Input so far (ignore blanks): * * stuff-in-outbuf $(variable) remainder * ^ ^ * in end * Output so far: * * stuff-in-outbuf variable * ^ ^ ^ * out_buf out ov * * Later we will overwrite 'variable' in out_buf, but we'll be * done with it by then. 'variable' may be a multi-element list, * so may each value for '$(variable element)', and so may 'remainder'. * Thus we produce a product of three lists. */ { LIST *variables = 0; LIST *remainder = 0; LIST *vars; /* Recursively expand variable name & rest of input */ if( out < ov ) variables = var_expand( L0, out, ov, lol, 0 ); if( in < end ) remainder = var_expand( L0, in, end, lol, 0 ); /* Now produce the result chain */ /* For each variable name */ for( vars = variables; vars; vars = list_next( vars ) ) { LIST *value, *evalue = 0; char *colon; char *bracket; char varname[ MAXSYM ]; int sub1 = 0, sub2 = -1; VAR_EDITS edits; /* Look for a : modifier in the variable name */ /* Must copy into varname so we can modify it */ strcpy( varname, vars->string ); if( colon = strchr( varname, MAGIC_COLON ) ) { *colon = '\0'; var_edit_parse( colon + 1, &edits ); } /* Look for [x-y] subscripting */ /* sub1 is x (0 default) */ /* sub2 is length (-1 means forever) */ if( bracket = strchr( varname, MAGIC_LEFT ) ) { char *dash; if( dash = strchr( bracket + 1, '-' ) ) *dash = '\0'; sub1 = atoi( bracket + 1 ) - 1; if( !dash ) sub2 = 1; else if( !dash[1] || dash[1] == MAGIC_RIGHT ) sub2 = -1; else sub2 = atoi( dash + 1 ) - sub1; *bracket = '\0'; } /* Get variable value, specially handling $(<), $(>), $(n) */ if( varname[0] == '<' && !varname[1] ) value = lol_get( lol, 0 ); else if( varname[0] == '>' && !varname[1] ) value = lol_get( lol, 1 ); else if( varname[0] >= '1' && varname[0] <= '9' && !varname[1] ) value = lol_get( lol, varname[0] - '1' ); else value = var_get( varname ); /* The fast path: $(x) - just copy the variable value. */ /* This is only an optimization */ if( out == out_buf && !bracket && !colon && in == end ) { l = list_copy( l, value ); continue; } /* Handle start subscript */ while( sub1 > 0 && value ) --sub1, value = list_next( value ); /* Empty w/ :E=default? */ if( !value && colon && edits.empty.ptr ) evalue = value = list_new( L0, edits.empty.ptr, 0 ); /* For each variable value */ for( ; value; value = list_next( value ) ) { LIST *rem; char *out1; /* Handle end subscript (length actually) */ if( sub2 >= 0 && --sub2 < 0 ) break; /* Apply : mods, if present */ if( colon && edits.filemods ) var_edit_file( value->string, out, &edits ); else strcpy( out, value->string ); if( colon && ( edits.upshift || edits.downshift ) ) var_edit_shift( out, &edits ); if ( colon && edits.quote ) var_edit_quote( out ); /* Handle :J=joinval */ /* If we have more values for this var, just */ /* keep appending them (with the join value) */ /* rather than creating separate LIST elements. */ if( colon && edits.join.ptr && ( list_next( value ) || list_next( vars ) ) ) { out += strlen( out ); strcpy( out, edits.join.ptr ); out += strlen( out ); continue; } /* If no remainder, append result to output chain. */ if( in == end ) { l = list_new( l, out_buf, 0 ); continue; } /* For each remainder, append the complete string */ /* to the output chain. */ /* Remember the end of the variable expansion so */ /* we can just tack on each instance of 'remainder' */ out1 = out + strlen( out ); for( rem = remainder; rem; rem = list_next( rem ) ) { strcpy( out1, rem->string ); l = list_new( l, out_buf, 0 ); } } /* Toss used empty */ if( evalue ) list_free( evalue ); } /* variables & remainder were gifts from var_expand */ /* and must be freed */ if( variables ) list_free( variables ); if( remainder) list_free( remainder ); if( DEBUG_VAREXP ) { printf( "expanded to " ); list_print( l ); printf( "\n" ); } return l; } } /* * var_edit_parse() - parse : modifiers into PATHNAME structure * * The : modifiers in a $(varname:modifier) currently support replacing * or omitting elements of a filename, and so they are parsed into a * PATHNAME structure (which contains pointers into the original string). * * Modifiers of the form "X=value" replace the component X with * the given value. Modifiers without the "=value" cause everything * but the component X to be omitted. X is one of: * * G * D directory name * B base name * S .suffix * M (member) * R root directory - prepended to whole path * * This routine sets: * * f->f_xxx.ptr = 0 * f->f_xxx.len = 0 * -> leave the original component xxx * * f->f_xxx.ptr = string * f->f_xxx.len = strlen( string ) * -> replace component xxx with string * * f->f_xxx.ptr = "" * f->f_xxx.len = 0 * -> omit component xxx * * var_edit_file() below and path_build() obligingly follow this convention. */ static void var_edit_parse( const char *mods, VAR_EDITS *edits ) { int havezeroed = 0; memset( (char *)edits, 0, sizeof( *edits ) ); while( *mods ) { char *p; PATHPART *fp; switch( *mods++ ) { case 'L': edits->downshift = 1; continue; case 'U': edits->upshift = 1; continue; case 'Q': edits->quote = 1; continue; case 'P': edits->parent = edits->filemods = 1; continue; case 'E': fp = &edits->empty; goto strval; case 'J': fp = &edits->join; goto strval; case 'G': fp = &edits->f.f_grist; goto fileval; case 'R': fp = &edits->f.f_root; goto fileval; case 'D': fp = &edits->f.f_dir; goto fileval; case 'B': fp = &edits->f.f_base; goto fileval; case 'S': fp = &edits->f.f_suffix; goto fileval; case 'M': fp = &edits->f.f_member; goto fileval; default: return; /* should complain, but so what... */ } fileval: /* Handle :CHARS, where each char (without a following =) */ /* selects a particular file path element. On the first such */ /* char, we deselect all others (by setting ptr = "", len = 0) */ /* and for each char we select that element (by setting ptr = 0) */ edits->filemods = 1; if( *mods != '=' ) { int i; if( !havezeroed++ ) for( i = 0; i < 6; i++ ) { edits->f.part[ i ].len = 0; edits->f.part[ i ].ptr = ""; } fp->ptr = 0; continue; } strval: /* Handle :X=value, or :X */ if( *mods != '=' ) { fp->ptr = ""; fp->len = 0; } else if( p = strchr( mods, MAGIC_COLON ) ) { *p = 0; fp->ptr = ++mods; fp->len = p - mods; mods = p + 1; } else { fp->ptr = ++mods; fp->len = strlen( mods ); mods += fp->len; } } } /* * var_edit_file() - copy input target name to output, modifying filename */ static void var_edit_file( const char *in, char *out, VAR_EDITS *edits ) { PATHNAME pathname; /* Parse apart original filename, putting parts into "pathname" */ path_parse( in, &pathname ); /* Replace any pathname with edits->f */ if( edits->f.f_grist.ptr ) pathname.f_grist = edits->f.f_grist; if( edits->f.f_root.ptr ) pathname.f_root = edits->f.f_root; if( edits->f.f_dir.ptr ) pathname.f_dir = edits->f.f_dir; if( edits->f.f_base.ptr ) pathname.f_base = edits->f.f_base; if( edits->f.f_suffix.ptr ) pathname.f_suffix = edits->f.f_suffix; if( edits->f.f_member.ptr ) pathname.f_member = edits->f.f_member; /* If requested, modify pathname to point to parent */ if( edits->parent ) path_parent( &pathname ); /* Put filename back together */ path_build( &pathname, out, 0 ); } /* * var_edit_shift() - do upshift/downshift mods */ static void var_edit_shift( char *out, VAR_EDITS *edits ) { /* Handle upshifting, downshifting now */ if( edits->upshift ) { for( ; *out; ++out ) *out = toupper( *out ); } else if( edits->downshift ) { for( ; *out; ++out ) *out = tolower( *out ); } } static void var_edit_quote( char *out ) { /* Handle quoting now */ int count, len; char* p = out; char* q; count = 0; for ( p = out; *p; ++p ) if ( *p == '\\' ) count++; q = p + count; for ( ; p >= out; ) { if ( *p == '\\' ) { *q-- = *p--; *q-- = '\\'; } else *q-- = *p--; } } ftjam-2.5.2/command.h0000744000424500003730000000326510441006352014204 0ustar dturnermhpsys/* * Copyright 1994 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * command.h - the CMD structure and routines to manipulate them * * Both ACTION and CMD contain a rule, targets, and sources. An * ACTION describes a rule to be applied to the given targets and * sources; a CMD is what actually gets executed by the shell. The * differences are due to: * * ACTIONS must be combined if 'actions together' is given. * ACTIONS must be split if 'actions piecemeal' is given. * ACTIONS must have current sources omitted for 'actions updated'. * * The CMD datatype holds a single command that is to be executed * against a target, and they can chain together to represent the * full collection of commands used to update a target. * * Structures: * * CMD - an action, ready to be formatted into a buffer and executed * * External routines: * * cmd_new() - return a new CMD or 0 if too many args * cmd_free() - delete CMD and its parts * cmd_next() - walk the CMD chain */ /* * CMD - an action, ready to be formatted into a buffer and executed */ typedef struct _cmd CMD; struct _cmd { CMD *next; CMD *tail; /* valid on in head */ RULE *rule; /* rule->actions contains shell script */ LIST *shell; /* $(SHELL) value */ LOL args; /* LISTs for $(<), $(>) */ char buf[ MAXLINE ]; /* actual commands */ } ; CMD *cmd_new( RULE *rule, /* rule (referenced) */ LIST *targets, /* $(<) (freed) */ LIST *sources, /* $(>) (freed) */ LIST *shell, /* $(SHELL) (freed) */ int maxline ); /* max line length */ void cmd_free( CMD *cmd ); # define cmd_next( c ) ((c)->next) ftjam-2.5.2/filesys.h0000744000424500003730000000104510441006352014236 0ustar dturnermhpsys/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * filesys.h - OS specific file routines * * 11/04/02 (seiwald) - const-ing for string literals */ typedef void (*scanback)( void *closure, const char *file, int found, time_t t ); void file_dirscan( const char *dir, scanback func, void *closure ); void file_archscan( const char *arch, scanback func, void *closure ); int file_time( const char *filename, time_t *time ); ftjam-2.5.2/glob.c0000744000424500003730000000525510441006352013505 0ustar dturnermhpsys/* * Copyright 1994 Christopher Seiwald. All rights reserved. * * This file is part of Jam - see jam.c for Copyright information. */ /* * glob.c - match a string against a simple pattern * * Understands the following patterns: * * * any number of characters * ? any single character * [a-z] any single character in the range a-z * [^a-z] any single character not in the range a-z * \x match x * * External functions: * * glob() - match a string against a simple pattern * * Internal functions: * * globchars() - build a bitlist to check for character group match * * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # define CHECK_BIT( tab, bit ) ( tab[ (bit)/8 ] & (1<<( (bit)%8 )) ) # define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */ static void globchars( const char *s, const char *e, char *b ); /* * glob() - match a string against a simple pattern */ int glob( const char *c, const char *s ) { char bitlist[ BITLISTSIZE ]; const char *here; for( ;; ) switch( *c++ ) { case '\0': return *s ? -1 : 0; case '?': if( !*s++ ) return 1; break; case '[': /* scan for matching ] */ here = c; do if( !*c++ ) return 1; while( here == c || *c != ']' ); c++; /* build character class bitlist */ globchars( here, c, bitlist ); if( !CHECK_BIT( bitlist, *(unsigned char *)s ) ) return 1; s++; break; case '*': here = s; while( *s ) s++; /* Try to match the rest of the pattern in a recursive */ /* call. If the match fails we'll back up chars, retrying. */ while( s != here ) { int r; /* A fast path for the last token in a pattern */ r = *c ? glob( c, s ) : *s ? -1 : 0; if( !r ) return 0; else if( r < 0 ) return 1; --s; } break; case '\\': /* Force literal match of next char. */ if( !*c || *s++ != *c++ ) return 1; break; default: if( *s++ != c[-1] ) return 1; break; } } /* * globchars() - build a bitlist to check for character group match */ static void globchars( const char *s, const char *e, char *b ) { int neg = 0; memset( b, '\0', BITLISTSIZE ); if( *s == '^') neg++, s++; while( s < e ) { int c; if( s+2 < e && s[1] == '-' ) { for( c = s[0]; c <= s[2]; c++ ) b[ c/8 ] |= (1<<(c%8)); s += 3; } else { c = *s++; b[ c/8 ] |= (1<<(c%8)); } } if( neg ) { int i; for( i = 0; i < BITLISTSIZE; i++ ) b[ i ] ^= 0377; } /* Don't include \0 in either $[chars] or $[^chars] */ b[0] &= 0376; } ftjam-2.5.2/expand.h0000744000424500003730000000054510441006353014044 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * expand.h - expand a buffer, given variable values * * 11/04/02 (seiwald) - const-ing for string literals */ LIST *var_expand( LIST *l, const char *in, const char *end, LOL *lol, int cancopyin ); ftjam-2.5.2/execunix.c0000744000424500003730000002023710441006353014410 0ustar dturnermhpsys/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * execunix.c - execute a shell script on UNIX/WinNT/OS2/AmigaOS * * If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp(). * The default is: * * /bin/sh -c % [ on UNIX/AmigaOS ] * cmd.exe /c % [ on OS2/WinNT ] * * Each word must be an individual element in a jam variable value. * * In $(JAMSHELL), % expands to the command string and ! expands to * the slot number (starting at 1) for multiprocess (-j) invocations. * If $(JAMSHELL) doesn't include a %, it is tacked on as the last * argument. * * Don't just set JAMSHELL to /bin/sh or cmd.exe - it won't work! * * External routines: * execcmd() - launch an async command execution * execwait() - wait and drive at most one execution completion * * Internal routines: * onintr() - bump intr to note command interruption * * 04/08/94 (seiwald) - Coherent/386 support added. * 05/04/94 (seiwald) - async multiprocess interface * 01/22/95 (seiwald) - $(JAMSHELL) support * 06/02/97 (gsar) - full async multiprocess support for Win32 * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C * 11/04/02 (seiwald) - const-ing for string literals * 12/27/02 (seiwald) - grist .bat file with pid for system uniqueness */ # include "jam.h" # include "lists.h" # include "execcmd.h" # include # ifdef USE_EXECUNIX # ifdef OS_OS2 # define USE_EXECNT # include # endif # ifdef OS_NT # define USE_EXECNT # include # define WIN32_LEAN_AND_MEAN # include /* do the ugly deed */ # define USE_MYWAIT # if !defined( __BORLANDC__ ) # define wait my_wait static int my_wait( int *status ); # endif # endif static int intr = 0; static int cmdsrunning = 0; static void (*istat)( int ); static struct { int pid; /* on win32, a real process handle */ void (*func)( void *closure, int status ); void *closure; # ifdef USE_EXECNT char *tempfile; # endif } cmdtab[ MAXJOBS ] = {{0}}; /* * onintr() - bump intr to note command interruption */ void onintr( int disp ) { intr++; printf( "...interrupted\n" ); } /* * execcmd() - launch an async command execution */ void execcmd( char *string, void (*func)( void *closure, int status ), void *closure, LIST *shell ) { int pid; int slot; const char *argv[ MAXARGC + 1 ]; /* +1 for NULL */ # ifdef USE_EXECNT char *p; # endif /* Find a slot in the running commands table for this one. */ for( slot = 0; slot < MAXJOBS; slot++ ) if( !cmdtab[ slot ].pid ) break; if( slot == MAXJOBS ) { printf( "no slots for child!\n" ); exit( EXITBAD ); } # ifdef USE_EXECNT if( !cmdtab[ slot ].tempfile ) { char *tempdir; if( !( tempdir = getenv( "TEMP" ) ) && !( tempdir = getenv( "TMP" ) ) ) tempdir = "\\temp"; /* +32 is room for \jamXXXXXtSS.bat (at least) */ cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 32 ); sprintf( cmdtab[ slot ].tempfile, "%s\\jam%dt%d.bat", tempdir, GetCurrentProcessId(), slot ); } /* Trim leading, ending white space */ while( isspace( *string ) ) ++string; p = strchr( string, '\n' ); while( p && isspace( *p ) ) ++p; /* If multi line, or too long, or JAMSHELL is set, write to bat file. */ /* Otherwise, exec directly. */ /* Frankly, if it is a single long line I don't think the */ /* command interpreter will do any better -- it will fail. */ if( p && *p || strlen( string ) > MAXLINE || shell ) { FILE *f; /* Write command to bat file. */ f = fopen( cmdtab[ slot ].tempfile, "w" ); fputs( string, f ); fclose( f ); string = cmdtab[ slot ].tempfile; } # endif /* Forumulate argv */ /* If shell was defined, be prepared for % and ! subs. */ /* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */ if( shell ) { int i; char jobno[4]; int gotpercent = 0; sprintf( jobno, "%d", slot + 1 ); for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) ) { switch( shell->string[0] ) { case '%': argv[i] = string; gotpercent++; break; case '!': argv[i] = jobno; break; default: argv[i] = shell->string; } if( DEBUG_EXECCMD ) printf( "argv[%d] = '%s'\n", i, argv[i] ); } if( !gotpercent ) argv[i++] = string; argv[i] = 0; } else { # ifdef USE_EXECNT argv[0] = "cmd.exe"; argv[1] = "/Q/C"; /* anything more is non-portable */ # else argv[0] = "/bin/sh"; argv[1] = "-c"; # endif argv[2] = string; argv[3] = 0; } /* Catch interrupts whenever commands are running. */ if( !cmdsrunning++ ) istat = signal( SIGINT, onintr ); /* Start the command */ # ifdef USE_EXECNT if( ( pid = spawnvp( P_NOWAIT, argv[0], argv ) ) == -1 ) { perror( "spawn" ); exit( EXITBAD ); } # else # ifdef NO_VFORK if ((pid = fork()) == 0) { execvp( argv[0], argv ); _exit(127); } # else if ((pid = vfork()) == 0) { execvp( argv[0], argv ); _exit(127); } # endif if( pid == -1 ) { perror( "vfork" ); exit( EXITBAD ); } # endif /* Save the operation for execwait() to find. */ cmdtab[ slot ].pid = pid; cmdtab[ slot ].func = func; cmdtab[ slot ].closure = closure; /* Wait until we're under the limit of concurrent commands. */ /* Don't trust globs.jobs alone. */ while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs ) if( !execwait() ) break; } /* * execwait() - wait and drive at most one execution completion */ int execwait() { int i; int status, w; int rstat; /* Handle naive make1() which doesn't know if cmds are running. */ if( !cmdsrunning ) return 0; /* Pick up process pid and status */ while( ( w = wait( &status ) ) == -1 && errno == EINTR ) ; if( w == -1 ) { printf( "child process(es) lost!\n" ); perror("wait"); exit( EXITBAD ); } /* Find the process in the cmdtab. */ for( i = 0; i < MAXJOBS; i++ ) if( w == cmdtab[ i ].pid ) break; if( i == MAXJOBS ) { printf( "waif child found!\n" ); exit( EXITBAD ); } # ifdef USE_EXECNT /* Clear the temp file */ unlink( cmdtab[ i ].tempfile ); # endif /* Drive the completion */ if( !--cmdsrunning ) signal( SIGINT, istat ); if( intr ) rstat = EXEC_CMD_INTR; else if( w == -1 || status != 0 ) rstat = EXEC_CMD_FAIL; else rstat = EXEC_CMD_OK; cmdtab[ i ].pid = 0; (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat ); return 1; } # ifdef USE_MYWAIT static int my_wait( int *status ) { int i, num_active = 0; DWORD exitcode, waitcode; static HANDLE *active_handles = 0; if (!active_handles) active_handles = (HANDLE *)malloc(globs.jobs * sizeof(HANDLE) ); /* first see if any non-waited-for processes are dead, * and return if so. */ for ( i = 0; i < globs.jobs; i++ ) { if ( cmdtab[i].pid ) { if ( GetExitCodeProcess((HANDLE)cmdtab[i].pid, &exitcode) ) { if ( exitcode == STILL_ACTIVE ) active_handles[num_active++] = (HANDLE)cmdtab[i].pid; else { CloseHandle((HANDLE)cmdtab[i].pid); *status = (int)((exitcode & 0xff) << 8); return cmdtab[i].pid; } } else goto FAILED; } } /* if a child exists, wait for it to die */ if ( !num_active ) { errno = ECHILD; return -1; } waitcode = WaitForMultipleObjects( num_active, active_handles, FALSE, INFINITE ); if ( waitcode != WAIT_FAILED ) { if ( waitcode >= WAIT_ABANDONED_0 && waitcode < WAIT_ABANDONED_0 + num_active ) i = waitcode - WAIT_ABANDONED_0; else i = waitcode - WAIT_OBJECT_0; if ( GetExitCodeProcess(active_handles[i], &exitcode) ) { CloseHandle(active_handles[i]); *status = (int)((exitcode & 0xff) << 8); return (int)active_handles[i]; } } FAILED: errno = GetLastError(); return -1; } # endif /* USE_MYWAIT */ # endif /* USE_EXECUNIX */