diff options
author | Kenneth Heafield <github@kheafield.com> | 2012-10-22 12:07:20 +0100 |
---|---|---|
committer | Kenneth Heafield <github@kheafield.com> | 2012-10-22 12:07:20 +0100 |
commit | ac586bc9b156b4ae687cd5961ba1fe7b20ec57d6 (patch) | |
tree | 052473b46d7fa18d51f897cdb9e7c93a7186dafd /jam-files/engine | |
parent | 97b85c082b3e55c28a8b0c0eb762483ac84a1577 (diff) | |
parent | ad6d4a1b2519896f2b16a282699ce4e64041fab8 (diff) |
Merge remote branch 'upstream/master'
Conflicts:
Jamroot
bjam
decoder/Jamfile
decoder/cdec.cc
dpmert/Jamfile
jam-files/sanity.jam
klm/lm/Jamfile
klm/util/Jamfile
mira/Jamfile
Diffstat (limited to 'jam-files/engine')
110 files changed, 0 insertions, 31951 deletions
diff --git a/jam-files/engine/Jambase b/jam-files/engine/Jambase deleted file mode 100644 index 94f8fbde..00000000 --- a/jam-files/engine/Jambase +++ /dev/null @@ -1,2473 +0,0 @@ -# -# /+\ -# +\ Copyright 1993, 2000 Christopher Seiwald. -# \+/ -# -# This file is part of Jam - see jam.c for Copyright information. -# - -# This file is ALSO: -# Copyright 2001-2004 David Abrahams. -# Copyright 2002-2004 Rene Rivera. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - -if $(NT) -{ - SLASH ?= \\ ; -} -SLASH ?= / ; - - -# Glob for patterns in the directories starting from the given start directory, -# up to and including the root of the file-system. We stop globbing as soon as -# we find at least one match. -# -rule find-to-root ( dir : patterns + ) -{ - local globs = [ GLOB $(dir) : $(patterns) ] ; - while ! $(globs) && $(dir:P) != $(dir) - { - dir = $(dir:P) ; - globs = [ GLOB $(dir) : $(patterns) ] ; - } - return $(globs) ; -} - - -# This global will hold the location of the user's boost-build.jam file. -.boost-build-file = ; - -# This global will hold the location of the build system bootstrap file. -.bootstrap-file = ; - -# Remember the value of $(BOOST_BUILD_PATH) supplied to us by the user. -BOOST_BUILD_PATH.user-value = $(BOOST_BUILD_PATH) ; - -# On Unix only, when BOOST_BUILD_PATH is not supplied by the user, set it to a -# sensible default value. This allows Boost.Build to work without any -# environment variables, which is good in itself and also required by the Debian -# Policy. -if ! $(BOOST_BUILD_PATH) && $(UNIX) -{ - BOOST_BUILD_PATH = /usr/share/boost-build ; -} - - -rule _poke ( module-name ? : variables + : value * ) -{ - module $(<) - { - $(>) = $(3) ; - } -} - - -# This rule can be invoked from an optional user's boost-build.jam file to both -# indicate where to find the build system files, and to load them. The path -# indicated is relative to the location of the boost-build.jam file. -# -rule boost-build ( dir ? ) -{ - if $(.bootstrap-file) - { - ECHO "Error: Illegal attempt to re-bootstrap the build system by invoking" ; - ECHO ; - ECHO " 'boost-build" $(dir) ";'" ; - ECHO ; - EXIT "Please consult the documentation at 'http://www.boost.org'." ; - } - - # Add the given directory to the path so we can find the build system. If - # dir is empty, has no effect. - BOOST_BUILD_PATH = $(dir:R=$(.boost-build-file:D)) $(BOOST_BUILD_PATH) ; - - # We might have just modified the *global* value of BOOST_BUILD_PATH. The - # code that loads the rest of Boost.Build, in particular the site-config.jam - # and user-config.jam configuration files uses os.environ, so we need to - # update the value there. - _poke .ENVIRON : BOOST_BUILD_PATH : $(BOOST_BUILD_PATH) ; - - # Try to find the build system bootstrap file 'bootstrap.jam'. - local bootstrap-file = [ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ; - .bootstrap-file = $(bootstrap-file[1]) ; - - # There is no bootstrap.jam we can find, exit with an error. - if ! $(.bootstrap-file) - { - ECHO "Unable to load Boost.Build: could not find build system." ; - ECHO --------------------------------------------------------- ; - ECHO "$(.boost-build-file) attempted to load the build system by invoking" ; - ECHO ; - ECHO " 'boost-build" $(dir) ";'" ; - ECHO ; - ECHO "but we were unable to find \"bootstrap.jam\" in the specified directory" ; - ECHO "or in BOOST_BUILD_PATH (searching "$(BOOST_BUILD_PATH:J=", ")")." ; - ECHO ; - EXIT "Please consult the documentation at 'http://www.boost.org'." ; - } - - if [ MATCH .*(--debug-configuration).* : $(ARGV) ] - { - ECHO "notice: loading Boost.Build from" - [ NORMALIZE_PATH $(.bootstrap-file:D) ] ; - } - - # Load the build system, now that we know where to start from. - include $(.bootstrap-file) ; -} - - -if [ MATCH .*(b2).* : $(ARGV[1]:BL) ] - || [ MATCH .*(bjam).* : $(ARGV[1]:BL) ] - || $(BOOST_ROOT) # A temporary measure so Jam works with Boost.Build v1. -{ - # We attempt to load "boost-build.jam" by searching from the current - # invocation directory up to the root of the file-system. - # - # boost-build.jam is expected to invoke the "boost-build" rule to load the - # Boost.Build files. - - local search-path = $(BOOST_BUILD_PATH) $(BOOST_ROOT) ; - local self = [ SELF_PATH ] ; - local boost-build-relative = ../../share/boost-build ; - local self-based-path = [ NORMALIZE_PATH $(boost-build-relative:R=$(self)) ] ; - - local boost-build-files = - [ find-to-root [ PWD ] : boost-build.jam ] - [ GLOB $(self-based-path) : boost-build.jam ] - # Another temporary measure so Jam works with Boost.Build v1. - [ GLOB $(search-path) : boost-build.jam ] ; - - .boost-build-file = $(boost-build-files[1]) ; - - # There is no boost-build.jam we can find, exit with an error, and - # information. - if ! $(.boost-build-file) - { - ECHO "Unable to load Boost.Build: could not find \"boost-build.jam\"" ; - ECHO --------------------------------------------------------------- ; - - if ! [ MATCH .*(bjam).* : $(ARGV[1]:BL) ] - { - ECHO "BOOST_ROOT must be set, either in the environment, or " ; - ECHO "on the command-line with -sBOOST_ROOT=..., to the root" ; - ECHO "of the boost installation." ; - ECHO ; - } - - ECHO "Attempted search from" [ PWD ] "up to the root" ; - ECHO "at" $(self-based-path) ; - ECHO "and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: "$(search-path:J=", ")"." ; - EXIT "Please consult the documentation at 'http://www.boost.org'." ; - } - - if [ MATCH .*(--debug-configuration).* : $(ARGV) ] - { - ECHO "notice: found boost-build.jam at" - [ NORMALIZE_PATH $(.boost-build-file) ] ; - } - - # Now load the boost-build.jam to get the build system loaded. This - # incidentaly loads the users jamfile and attempts to build targets. - # - # We also set it up so we can tell whether we are loading the new V2 system - # or the the old V1 system. - include $(.boost-build-file) ; - - # Check that, at minimum, the bootstrap file was found. - if ! $(.bootstrap-file) - { - ECHO "Unable to load Boost.Build" ; - ECHO -------------------------- ; - ECHO "\"$(.boost-build-file)\" was found by searching from" [ PWD ] "up to the root" ; - ECHO "and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: "$(search-path:J=", ")"." ; - ECHO ; - ECHO "However, it failed to call the \"boost-build\" rule to indicate" ; - ECHO "the location of the build system." ; - ECHO ; - EXIT "Please consult the documentation at 'http://www.boost.org'." ; - } -} -else -{ - -# -# JAMBASE - jam 2.3 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 dependency 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 -# 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 dirs ; add include dirs 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 -# FConcat value ... ; return contatenated values -# 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)) -# 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.3) -# -# 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 -# - -# Initialize variables -# - -# -# OS specific variable settings -# -if $(NT) -{ - # the list of supported toolsets on Windows NT and Windows 95/98 - # - local SUPPORTED_TOOLSETS = "BORLANDC" "VC7" "VISUALC" "VISUALC16" "INTELC" "WATCOM" - "MINGW" "LCC" ; - - # 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) - { - local t ; - - for t in $(SUPPORTED_TOOLSETS) - { - $(t) = $($(t):J=" ") ; # reconstitute paths with spaces in them - if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; } - } - - if ! $(TOOLSET) - { - 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 ! $(TOOLSET) - { - if $(BCCROOT) - { - TOOLSET = BORLANDC ; - BORLANDC = $(BCCROOT:J=" ") ; - } - else if $(MSVC) - { - TOOLSET = VISUALC16 ; - VISUALC16 = $(MSVC:J=" ") ; - } - else if $(MSVCNT) - { - TOOLSET = VISUALC ; - VISUALC = $(MSVCNT:J=" ") ; - } - else if $(MSVCDir) - { - TOOLSET = VISUALC ; - VISUALC = $(MSVCDir:J=" ") ; - } - else if $(MINGW) - { - TOOLSET = MINGW ; - } - else - { - ECHO "Jam cannot be run because, either:" ; - ECHO " a. You didn't set BOOST_ROOT to indicate the root of your" ; - ECHO " Boost installation." ; - ECHO " b. You are trying to use stock Jam but didn't indicate which" ; - ECHO " compilation toolset to use. To do so, follow these simple" ; - ECHO " 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 " BORLANDC Borland C++ BC++ install path" ; - ECHO " VISUALC Microsoft Visual C++ VC++ install path" ; - ECHO " VISUALC16 Microsoft Visual C++ 16 bit VC++ 16 bit install" ; - ECHO " INTELC Intel C/C++ IC++ install path" ; - ECHO " WATCOM Watcom C/C++ Watcom install path" ; - ECHO " MINGW MinGW (gcc) MinGW install path" ; - ECHO " LCC Win32-LCC LCC-Win32 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 VISUALC=C:\\Visual6" ; - ECHO " set JAM_TOOLSET=VISUALC" ; - EXIT ; - } - } - - CP ?= copy ; - RM ?= del /f/q ; - SLASH ?= \\ ; - SUFLIB ?= .lib ; - SUFOBJ ?= .obj ; - SUFEXE ?= .exe ; - - if $(TOOLSET) = BORLANDC - { - ECHO "Compiler is Borland C++" ; - - AR ?= tlib /C /P64 ; - CC ?= bcc32 ; - CCFLAGS ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus ; - C++ ?= bcc32 ; - C++FLAGS ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus -P ; - LINK ?= $(CC) ; - LINKFLAGS ?= $(CCFLAGS) ; - STDLIBPATH ?= $(BORLANDC)\\lib ; - STDHDRS ?= $(BORLANDC)\\include ; - NOARSCAN ?= true ; - } - else if $(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 ?= - \"$(VISUALC16)\\lib\\mlibce.lib\" - \"$(VISUALC16)\\lib\\oldnames.lib\" - ; - LINKLIBS ?= ; - NOARSCAN ?= true ; - OPTIM ?= "" ; - STDHDRS ?= $(VISUALC16)\\include ; - UNDEFFLAG ?= "/u _" ; - } - else if $(TOOLSET) = VISUALC - { - ECHO "Compiler is Microsoft Visual C++" ; - - AR ?= lib ; - AS ?= masm386 ; - CC ?= cl /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\\gdi32.lib\" - \"$(VISUALC)\\lib\\user32.lib\" - \"$(VISUALC)\\lib\\kernel32.lib\" ; - OPTIM ?= "" ; - STDHDRS ?= $(VISUALC)\\include ; - UNDEFFLAG ?= "/u _" ; - } - else if $(TOOLSET) = VC7 - { - ECHO "Compiler is Microsoft Visual C++ .NET" ; - - AR ?= lib ; - AS ?= masm386 ; - CC ?= cl /nologo ; - CCFLAGS ?= "" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= link /nologo ; - LINKFLAGS ?= "" ; - LINKLIBS ?= \"$(VISUALC)\\PlatformSDK\\lib\\advapi32.lib\" - # $(VISUALC)\\lib\\libc.lib - # $(VISUALC)\\lib\\oldnames.lib - \"$(VISUALC)\\PlatformSDK\\lib\\gdi32.lib\" - \"$(VISUALC)\\PlatformSDK\\lib\\user32.lib\" - \"$(VISUALC)\\PlatformSDK\\lib\\kernel32.lib\" ; - OPTIM ?= "" ; - STDHDRS ?= \"$(VISUALC)\\include\" - \"$(VISUALC)\\PlatformSDK\\include\" ; - UNDEFFLAG ?= "/u _" ; - } - else if $(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 $(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 _" ; - } - else if $(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 $(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 - { -# -# XXX: We need better comments here !! -# - EXIT On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the - Borland or Microsoft directories. ; - } - -} -else if $(OS2) -{ - # the list of supported toolsets on Windows NT and Windows 95/98 - # - 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) - { - local t ; - - for t in $(SUPPORTED_TOOLSETS) - { - $(t) = $($(t):J=" ") ; # reconstitute paths with spaces in them - if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; } - } - - if ! $(TOOLSET) - { - 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 ! $(TOOLSET) - { - if $(watcom) - { - WATCOM = $(watcom:J=" ") ; - 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 ; - - if $(TOOLSET) = WATCOM - { - AR ?= wlib ; - BINDIR ?= \\os2\\apps ; - CC ?= wcc386 ; - CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet - C++ ?= wpp386 ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= wcl386 ; - LINKFLAGS ?= /zq ; # zq=quiet - LINKLIBS ?= ; - NOARSCAN ?= true ; - OPTIM ?= ; - SLASH ?= \\ ; - STDHDRS ?= $(WATCOM)\\h ; - UNDEFFLAG ?= "/u _" ; - } - else if $(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 = / ; -# NOARSCAN ?= true ; - } - 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:Runtime PPC:MSL MPWCRuntime.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib" ; - - MPWNLLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW(NL).Lib" ; - - SIOUXHDRS ?= ; - - SIOUXLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.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 -nomapcr ; - CC ?= mwcppc ; - CCFLAGS ?= -w off -nomapcr ; - 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 && $(METROWERKS) -{ - AR ?= mwld -xml -o ; - BINDIR ?= /boot/apps ; - CC ?= mwcc ; - CCFLAGS ?= -nosyspath ; - C++ ?= $(CC) ; - C++FLAGS ?= -nosyspath ; - FORTRAN ?= "" ; - LIBDIR ?= /boot/develop/libraries ; - LINK ?= mwld ; - LINKFLAGS ?= "" ; - MANDIR ?= /boot/documentation/"Shell Tools"/HTML ; - NOARSCAN ?= true ; - STDHDRS ?= /boot/develop/headers/posix ; -} -else if $(OS) = BEOS -{ - BINDIR ?= /boot/apps ; - CC ?= gcc ; - C++ ?= $(CC) ; - FORTRAN ?= "" ; - LIBDIR ?= /boot/develop/libraries ; - LINK ?= gcc ; - LINKLIBS ?= -lnet ; - NOARSCAN ?= true ; - STDHDRS ?= /boot/develop/headers/posix ; -} -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 ; - RANLIB ?= "" ; - SUFEXE ?= .exe ; - YACC ?= "bison -y" ; - - case DGUX : - RANLIB ?= "" ; - RELOCATE ?= true ; - - case HPUX : - YACC = ; - CFLAGS += -Ae ; - CCFLAGS += -Ae ; - RANLIB ?= "" ; - - case INTERIX : - CC ?= gcc ; - 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 : - AR ?= libtool -o ; - C++ ?= c++ ; - MANDIR ?= /usr/local/share/man ; - RANLIB ?= "" ; - - 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 ; - YACCFILES ?= y.tab ; - YACCFLAGS ?= -d ; -} - -# -# 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 ; - RSH ?= rsh ; - SED ?= sed ; - SHELLHEADER ?= "#!/bin/sh" ; - SHELLMODE ?= 755 ; - SLASH ?= / ; - STDHDRS ?= /usr/include ; - SUFEXE ?= "" ; - SUFLIB ?= .a ; - SUFOBJ ?= .o ; - UNDEFFLAG ?= "-u _" ; - YACC ?= ; - 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 -# - -rule As -{ - DEPENDS $(<) : $(>) ; - ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ; -} - -rule Bulk -{ - local i ; - - for i in $(>) - { - File $(i:D=$(<)) : $(i) ; - } -} - -rule Cc -{ - local _h ; - - DEPENDS $(<) : $(>) ; - - # Just to clarify here: this sets the per-target CCFLAGS to - # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS. - - CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ; - - # If the compiler's -o flag doesn't work, relocate the .o - - if $(RELOCATE) - { - CcMv $(<) : $(>) ; - } - - _h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ; - - if $(VMS) && $(_h) - { - SLASHINC on $(<) = "/inc=(" $(_h[1]) ,$(_h[2-]) ")" ; - } - else if $(MAC) && $(_h) - { - local _i _j ; - _j = $(_h[1]) ; - for _i in $(_h[2-]) - { - _j = $(_j),$(_i) ; - } - MACINC on $(<) = \"$(_j)\" ; - } -} - -rule C++ -{ - local _h ; - - DEPENDS $(<) : $(>) ; - C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ; - - if $(RELOCATE) - { - CcMv $(<) : $(>) ; - } - - _h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ; - - if $(VMS) && $(_h) - { - SLASHINC on $(<) = "/inc=(" $(_h[1]) ,$(_h[2-]) ")" ; - } - else if $(MAC) && $(_h) - { - local _i _j ; - _j = $(_h[1]) ; - for _i in $(_h[2-]) - { - _j = $(_j),$(_i) ; - } - MACINC on $(<) = \"$(_j)\" ; - } -} - -rule Chmod -{ - if $(CHMOD) { Chmod1 $(<) ; } -} - -rule File -{ - DEPENDS files : $(<) ; - DEPENDS $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - MODE on $(<) = $(FILEMODE) ; - Chmod $(<) ; -} - -rule Fortran -{ - DEPENDS $(<) : $(>) ; -} - -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) ; -} - -rule HardLink -{ - DEPENDS files : $(<) ; - DEPENDS $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; -} - -rule HdrMacroFile -{ - # HdrMacroFile file ; - # - # this rule is used to indicate that a given file contains definitions - # for filename macros (e.g. "#define MYFILE_H <myfile.h>") that can - # later be used in #include statements in the rest of the source - # - # theses files must be parsed before any make is tried.. - # - HDRMACRO $(<) ; -} - -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 ; - - if $(HDRGRIST) - { - s = $(>:G=$(HDRGRIST)) ; - } else { - s = $(>) ; - } - - 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) ; - } - } -} - -rule InstallBin -{ - local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ; - - InstallInto $(<) : $(_t) ; - MODE on $(_t:G=installed) = $(EXEMODE) ; -} - -rule InstallFile -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=installed) = $(FILEMODE) ; -} - -rule InstallLib -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=installed) = $(FILEMODE) ; -} - -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=installed) = $(FILEMODE) ; -} - -rule InstallShell -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=installed) = $(SHELLMODE) ; -} - -rule Lex -{ - LexMv $(<) : $(>) ; - DEPENDS $(<) : $(>) ; - MakeLocate $(<) : $(LOCATE_SOURCE) ; - Clean clean : $(<) ; -} - -rule Library -{ - LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ; - Objects $(>) ; -} - -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) || $(KEEPOBJS) ) { RmTemps $(_l) : $(_s) ; } -} - -rule Link -{ - MODE on $(<) = $(EXEMODE) ; - Chmod $(<) ; -} - -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)) ; -} - -rule Main -{ - MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ; - Objects $(>) ; -} - -rule MainFromObjects -{ - local _s _t ; - - # Add grist to file names - # Add suffix to exe - - _s = [ FGristFiles $(>) ] ; - _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; - - 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) ; - - Link $(_t) : $(_s) ; -} - -rule MakeLocate -{ - if $(>) - { - LOCATE on $(<) = $(>) ; - Depends $(<) : $(>[1]) ; - MkDir $(>[1]) ; - } -} - -rule MkDir -{ - # If dir exists, don't update it - # Do this even for $(DOT). - - NOUPDATE $(<) ; - - if $(<) != $(DOT) && ! $($(<)-mkdir) - { - local s ; - - # Cheesy gate to prevent multiple invocations on same dir - # MkDir1 has the actions - # Arrange for jam dirs - - $(<)-mkdir = true ; - MkDir1 $(<) ; - Depends dirs : $(<) ; - - # Recursively make parent directories. - # $(<:P) = $(<)'s parent, & we recurse until root - - s = $(<:P) ; - - if $(NT) - { - switch $(s) - { - case *: : s = ; - case *:\\ : s = ; - } - } - - if $(s) && $(s) != $(<) - { - Depends $(<) : $(s) ; - MkDir $(s) ; - } - else if $(s) - { - NOTFILE $(s) ; - } - - } -} - -rule Object -{ - local h ; - - # 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) $(HDRS) $(SUBDIRHDRS) ; - - # 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. - - # $(h) 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). - - if $(SEARCH_SOURCE) - { - h = $(SEARCH_SOURCE) ; - } - else - { - h = "" ; - } - - HDRRULE on $(>) = HdrRule ; - HDRSCAN on $(>) = $(HDRPATTERN) ; - HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ; - HDRGRIST on $(>) = $(HDRGRIST) ; - - # 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 .f : Fortran $(<) : $(>) ; - case .l : Cc $(<) : $(<:S=.c) ; - Lex $(<:S=.c) : $(>) ; - case .s : As $(<) : $(>) ; - case .y : Cc $(<) : $(<:S=.c) ; - Yacc $(<:S=.c) : $(>) ; - case * : UserObject $(<) : $(>) ; - } -} - - -rule ObjectCcFlags -{ - CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; -} - -rule ObjectC++Flags -{ - C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; -} - -rule ObjectHdrs -{ - HDRS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; -} - -rule Objects -{ - local _i ; - - for _i in [ FGristFiles $(<) ] - { - Object $(_i:S=$(SUFOBJ)) : $(_i) ; - DEPENDS obj : $(_i:S=$(SUFOBJ)) ; - } -} - -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 SubDir -{ - local _r _s ; - - # - # SubDir TOP d1 [ ... ] - # - # This introduces a Jamfile that is part of a project tree - # rooted at $(TOP). It (only once) includes the project-specific - # rules file $(TOP)/Jamrules and then sets search & locate stuff. - # - # If the variable $(TOPRULES) is set (where TOP is the first arg - # to SubDir), that file is included instead of $(TOP)/Jamrules. - # - # d1 ... are the directory elements that lead to this directory - # from $(TOP). We construct the system dependent path from these - # directory elements in order to set search & locate stuff. - # - - if ! $($(<[1])) - { - if ! $(<[1]) - { - EXIT SubDir syntax error ; - } - - $(<[1]) = [ FSubDir $(<[2-]) ] ; - } - - # - # If $(TOP)/Jamrules hasn't been included, do so. - # - - if ! $($(<[1])-included) - { - # Gated entry. - - $(<[1])-included = TRUE ; - - # File is $(TOPRULES) or $(TOP)/Jamrules. - - _r = $($(<[1])RULES) ; - - if ! $(_r) - { - _r = $(JAMRULES:R=$($(<[1]))) ; - } - - # Include it. - - include $(_r) ; - } - - # Get path to current directory from root using SubDir. - # Save dir tokens for other potential uses. - - _s = [ FDirName $(<[2-]) ] ; - SUBDIR = $(_s:R=$($(<[1]))) ; - SUBDIR_TOKENS = $(<[2-]) ; - - # 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 $(<[2-]) ] ; - - # Reset per-directory ccflags, hdrs - - SUBDIRCCFLAGS = ; - SUBDIRC++FLAGS = ; - SUBDIRHDRS = ; -} - -rule SubDirCcFlags -{ - SUBDIRCCFLAGS += $(<) ; -} - -rule SubDirC++Flags -{ - SUBDIRC++FLAGS += $(<) ; -} - -rule SubDirHdrs -{ - SUBDIRHDRS += $(<) ; -} - -rule SubInclude -{ - local _s ; - - # That's - # SubInclude TOP d1 [ d2 [ d3 [ d4 ] ] ] - # - # to include a subdirectory's Jamfile. - - if ! $($(<[1])) - { - EXIT Top level of source tree has not been set with $(<[1]) ; - } - - _s = [ FDirName $(<[2-]) ] ; - - include $(JAMFILE:D=$(_s):R=$($(<[1]))) ; -} - -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. -# - -rule FGrist -{ - # Turn individual elements in $(<) into grist. - - local _g _i ; - - _g = $(<[1]) ; - - for _i in $(<[2-]) - { - _g = $(_g)!$(_i) ; - } - - return $(_g) ; -} - -rule FGristFiles -{ - if ! $(SOURCE_GRIST) - { - return $(<) ; - } - else - { - return $(<:G=$(SOURCE_GRIST)) ; - } -} - -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 FConcat -{ - # Puts the variables together, removing spaces. - - local _t _r ; - - $(_r) = $(<[1]) ; - - for _t in $(<[2-]) - { - $(_r) = $(_r)$(_t) ; - } - - return $(_r) ; -} - -rule FSubDir -{ - local _i _d ; - - # If $(>) is the path to the current directory, compute the - # path (using ../../ etc) back to that root directory. - # Sets result in $(<) - - if ! $(<[1]) - { - _d = $(DOT) ; - } - else - { - _d = $(DOTDOT) ; - - for _i in $(<[2-]) - { - _d = $(_d:R=$(DOTDOT)) ; - } - } - - return $(_d) ; -} - -rule FDirName -{ - local _s _i ; - - # Turn individual elements in $(<) into a usable path. - - if ! $(<) - { - _s = $(DOT) ; - } - else if $(VMS) - { - # 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)) ; - } - } - else if $(MAC) - { - _s = $(DOT) ; - - for _i in $(<) - { - _s = $(_i:R=$(_s)) ; - } - } - else - { - _s = $(<[1]) ; - - for _i in $(<[2-]) - { - _s = $(_i:R=$(_s)) ; - } - } - - return $(_s) ; -} - - -rule _makeCommon -{ - # strip common initial elements - - if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) - { - $(<) = $($(<)[2-]) ; - $(>) = $($(>)[2-]) ; - _makeCommon $(<) : $(>) ; - } -} - - -rule FRelPath -{ - local _l _r ; - - # first strip off common parts - - _l = $(<) ; - _r = $(>) ; - - _makeCommon _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 $(<) ; - } -} - -rule unmakeDir -{ - if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\ - { - unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ; - } - else - { - $(<) = $(>) ; - } -} - - -rule FConvertToSlashes -{ - local _d, _s, _i ; - - unmakeDir _d : $(<) ; - - _s = $(_d[1]) ; - for _i in $(_d[2-]) - { - _s = $(_s)/$(_i) ; - } - return $(_s) ; -} - - -# -# Actions -# - -# -# First the defaults -# - -actions updated together piecemeal Archive -{ - $(AR) $(<) $(>) -} - -actions As -{ - $(AS) $(ASFLAGS) -I$(HDRS) -o $(<) $(>) -} - -actions C++ -{ - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>) -} - -actions Cc -{ - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>) -} - -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 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) -I$(HDRS) $(>) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) $(>) - } - - actions ignore CcMv - { - [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<) - } -} - -# -# NOARUPDATE - can't update an archive -# - -if $(NOARUPDATE) -{ - actions Archive - { - $(AR) $(<) $(>) - } -} - -# -# NT specific actions -# - -if $(NT) -{ - if $(TOOLSET) = VISUALC || $(TOOLSET) = VC7 || $(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 $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) $(>) - } - - actions C++ - { - $(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) /Tp$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - } - else if $(TOOLSET) = VISUALC16 - { - actions updated together piecemeal Archive - { - $(AR) $(<) -+$(>) - } - - actions Cc - { - $(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) $(>) - } - - actions C++ - { - $(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /Tp$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - } - else if $(TOOLSET) = BORLANDC - { - actions updated together piecemeal Archive - { - $(AR) $(<) -+$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>) - } - - actions C++ - { - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - - } - else if $(TOOLSET) = MINGW - { - actions together piecemeal Archive - { - $(AR) $(<) $(>:T) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - - actions C++ - { - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - } - else if $(TOOLSET) = WATCOM - { - actions together piecemeal Archive - { - $(AR) $(<) +-$(>) - } - - actions Cc - { - $(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) - } - - actions C++ - { - $(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - - actions Shell - { - $(CP) $(>) $(<) - } - } - else if $(TOOLSET) = LCC - { - actions together piecemeal Archive - { - $(AR) /out:$(<) $(>) - } - - actions Cc - { - $(CC) $(CCFLAGS) $(OPTIM) -Fo$(<) -I$(HDRS) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - - actions Shell - { - $(CP) $(>) $(<) - } - } -} - -# -# OS2 specific actions -# - -else if $(OS2) -{ - if $(TOOLSET) = WATCOM - { - actions together piecemeal Archive - { - $(AR) $(<) +-$(>) - } - - actions Cc - { - $(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) - } - - actions C++ - { - $(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - - actions Shell - { - $(CP) $(>) $(<) - } - } - else if $(TOOLSET) = EMX - { - actions together piecemeal Archive - { - $(AR) $(<) $(>:T) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - - actions C++ - { - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - } -} - -# -# VMS specific actions -# - -else if $(VMS) -{ - actions updated together piecemeal Archive - { - lib/replace $(<) $(>[1]) ,$(>[2-]) - } - - actions Cc - { - $(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>) - } - - actions C++ - { - $(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>) - } - - 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) $(>[1]) ,$(>[2-]) ,$(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 $(MACINC) - $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>) - } - - actions C++ - { - set -e MWCincludes $(MACINC) - $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)" - } -} - -# -# 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 makeDirName { $(<) = [ FDirName $(>) ] ; } -rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; } -rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; } -rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; } - -# -# Now include the user's Jamfile. -# - -{ - if $(JAMFILE) { include $(JAMFILE) ; } -} - -} diff --git a/jam-files/engine/boost-jam.spec b/jam-files/engine/boost-jam.spec deleted file mode 100644 index bc572fc9..00000000 --- a/jam-files/engine/boost-jam.spec +++ /dev/null @@ -1,64 +0,0 @@ -Name: boost-jam -Version: 3.1.19 -Summary: Build tool -Release: 1 -Source: %{name}-%{version}.tgz - -License: Boost Software License, Version 1.0 -Group: Development/Tools -URL: http://www.boost.org -Packager: Rene Rivera <grafik@redshift-software.com> -BuildRoot: /var/tmp/%{name}-%{version}.root - -%description -Boost Jam is a build tool based on FTJam, which in turn is based on -Perforce Jam. It contains significant improvements made to facilitate -its use in the Boost Build System, but should be backward compatible -with Perforce Jam. - -Authors: - Perforce Jam : Cristopher Seiwald - FT Jam : David Turner - Boost Jam : David Abrahams - -Copyright: - /+\ - +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - \+/ - 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. - -Also: - Copyright 2001-2006 David Abrahams. - Copyright 2002-2006 Rene Rivera. - Copyright 2003-2006 Vladimir Prus. - - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - -%prep -%setup -n %{name}-%{version} - -%build -LOCATE_TARGET=bin ./build.sh $BOOST_JAM_TOOLSET - -%install -rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT%{_bindir} -mkdir -p $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version} -install -m 755 bin/bjam $RPM_BUILD_ROOT%{_bindir}/bjam-%{version} -ln -sf bjam-%{version} $RPM_BUILD_ROOT%{_bindir}/bjam -cp -R *.html *.png *.css LICENSE*.txt images jam $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version} - -find $RPM_BUILD_ROOT -name CVS -type d -exec rm -r {} \; - -%files -%defattr(-,root,root) -%attr(755,root,root) /usr/bin/* -%doc %{_docdir}/%{name}-%{version} - - -%clean -rm -rf $RPM_BUILD_ROOT diff --git a/jam-files/engine/boost-no-inspect b/jam-files/engine/boost-no-inspect deleted file mode 100644 index 8a06f3a7..00000000 --- a/jam-files/engine/boost-no-inspect +++ /dev/null @@ -1 +0,0 @@ -this really out of our hands, so tell inspect to ignore directory
\ No newline at end of file diff --git a/jam-files/engine/build.bat b/jam-files/engine/build.bat deleted file mode 100644 index f927b769..00000000 --- a/jam-files/engine/build.bat +++ /dev/null @@ -1,532 +0,0 @@ -@ECHO OFF - -REM ~ Copyright 2002-2007 Rene Rivera. -REM ~ Distributed under the Boost Software License, Version 1.0. -REM ~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - -setlocal -goto Start - - -:Set_Error -color 00 -goto :eof - - -:Clear_Error -ver >nul -goto :eof - - -:Error_Print -REM Output an error message and set the errorlevel to indicate failure. -setlocal -ECHO ### -ECHO ### %1 -ECHO ### -ECHO ### You can specify the toolset as the argument, i.e.: -ECHO ### .\build.bat msvc -ECHO ### -ECHO ### Toolsets supported by this script are: borland, como, gcc, gcc-nocygwin, -ECHO ### intel-win32, metrowerks, mingw, msvc, vc7, vc8, vc9, vc10 -ECHO ### -call :Set_Error -endlocal -goto :eof - - -:Test_Path -REM Tests for the given file(executable) presence in the directories in the PATH -REM environment variable. Additionaly sets FOUND_PATH to the path of the -REM found file. -call :Clear_Error -setlocal -set test=%~$PATH:1 -endlocal -if not errorlevel 1 set FOUND_PATH=%~dp$PATH:1 -goto :eof - - -:Test_Option -REM Tests whether the given string is in the form of an option: "--*" -call :Clear_Error -setlocal -set test=%1 -if not defined test ( - call :Set_Error - goto Test_Option_End -) -set test=###%test%### -set test=%test:"###=% -set test=%test:###"=% -set test=%test:###=% -if not "-" == "%test:~1,1%" call :Set_Error -:Test_Option_End -endlocal -goto :eof - - -:Test_Empty -REM Tests whether the given string is not empty -call :Clear_Error -setlocal -set test=%1 -if not defined test ( - call :Clear_Error - goto Test_Empty_End -) -set test=###%test%### -set test=%test:"###=% -set test=%test:###"=% -set test=%test:###=% -if not "" == "%test%" call :Set_Error -:Test_Empty_End -endlocal -goto :eof - - -:Call_If_Exists -if EXIST %1 call %* -goto :eof - - -:Guess_Toolset -REM Try and guess the toolset to bootstrap the build with... -REM Sets BOOST_JAM_TOOLSET to the first found toolset. -REM May also set BOOST_JAM_TOOLSET_ROOT to the -REM location of the found toolset. - -call :Clear_Error -call :Test_Empty %ProgramFiles% -if not errorlevel 1 set ProgramFiles=C:\Program Files - -call :Clear_Error -if NOT "_%VS100COMNTOOLS%_" == "__" ( - set "BOOST_JAM_TOOLSET=vc10" - set "BOOST_JAM_TOOLSET_ROOT=%VS100COMNTOOLS%..\..\VC\" - goto :eof) -call :Clear_Error -if EXIST "%ProgramFiles%\Microsoft Visual Studio 10.0\VC\VCVARSALL.BAT" ( - set "BOOST_JAM_TOOLSET=vc10" - set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio 10.0\VC\" - goto :eof) -call :Clear_Error -if NOT "_%VS90COMNTOOLS%_" == "__" ( - set "BOOST_JAM_TOOLSET=vc9" - set "BOOST_JAM_TOOLSET_ROOT=%VS90COMNTOOLS%..\..\VC\" - goto :eof) -call :Clear_Error -if EXIST "%ProgramFiles%\Microsoft Visual Studio 9.0\VC\VCVARSALL.BAT" ( - set "BOOST_JAM_TOOLSET=vc9" - set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio 9.0\VC\" - goto :eof) -call :Clear_Error -if NOT "_%VS80COMNTOOLS%_" == "__" ( - set "BOOST_JAM_TOOLSET=vc8" - set "BOOST_JAM_TOOLSET_ROOT=%VS80COMNTOOLS%..\..\VC\" - goto :eof) -call :Clear_Error -if EXIST "%ProgramFiles%\Microsoft Visual Studio 8\VC\VCVARSALL.BAT" ( - set "BOOST_JAM_TOOLSET=vc8" - set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio 8\VC\" - goto :eof) -call :Clear_Error -if NOT "_%VS71COMNTOOLS%_" == "__" ( - set "BOOST_JAM_TOOLSET=vc7" - set "BOOST_JAM_TOOLSET_ROOT=%VS71COMNTOOLS%\..\..\VC7\" - goto :eof) -call :Clear_Error -if NOT "_%VCINSTALLDIR%_" == "__" ( - REM %VCINSTALLDIR% is also set for VC9 (and probably VC8) - set "BOOST_JAM_TOOLSET=vc7" - set "BOOST_JAM_TOOLSET_ROOT=%VCINSTALLDIR%\VC7\" - goto :eof) -call :Clear_Error -if EXIST "%ProgramFiles%\Microsoft Visual Studio .NET 2003\VC7\bin\VCVARS32.BAT" ( - set "BOOST_JAM_TOOLSET=vc7" - set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio .NET 2003\VC7\" - goto :eof) -call :Clear_Error -if EXIST "%ProgramFiles%\Microsoft Visual Studio .NET\VC7\bin\VCVARS32.BAT" ( - set "BOOST_JAM_TOOLSET=vc7" - set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio .NET\VC7\" - goto :eof) -call :Clear_Error -if NOT "_%MSVCDir%_" == "__" ( - set "BOOST_JAM_TOOLSET=msvc" - set "BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\" - goto :eof) -call :Clear_Error -if EXIST "%ProgramFiles%\Microsoft Visual Studio\VC98\bin\VCVARS32.BAT" ( - set "BOOST_JAM_TOOLSET=msvc" - set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio\VC98\" - goto :eof) -call :Clear_Error -if EXIST "%ProgramFiles%\Microsoft Visual C++\VC98\bin\VCVARS32.BAT" ( - set "BOOST_JAM_TOOLSET=msvc" - set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual C++\VC98\" - goto :eof) -call :Clear_Error -call :Test_Path cl.exe -if not errorlevel 1 ( - set "BOOST_JAM_TOOLSET=msvc" - set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\" - goto :eof) -call :Clear_Error -call :Test_Path vcvars32.bat -if not errorlevel 1 ( - set "BOOST_JAM_TOOLSET=msvc" - call "%FOUND_PATH%VCVARS32.BAT" - set "BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\" - goto :eof) -call :Clear_Error -if EXIST "C:\Borland\BCC55\Bin\bcc32.exe" ( - set "BOOST_JAM_TOOLSET=borland" - set "BOOST_JAM_TOOLSET_ROOT=C:\Borland\BCC55\" - goto :eof) -call :Clear_Error -call :Test_Path bcc32.exe -if not errorlevel 1 ( - set "BOOST_JAM_TOOLSET=borland" - set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\" - goto :eof) -call :Clear_Error -call :Test_Path icl.exe -if not errorlevel 1 ( - set "BOOST_JAM_TOOLSET=intel-win32" - set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\" - goto :eof) -call :Clear_Error -if EXIST "C:\MinGW\bin\gcc.exe" ( - set "BOOST_JAM_TOOLSET=mingw" - set "BOOST_JAM_TOOLSET_ROOT=C:\MinGW\" - goto :eof) -call :Clear_Error -if NOT "_%CWFolder%_" == "__" ( - set "BOOST_JAM_TOOLSET=metrowerks" - set "BOOST_JAM_TOOLSET_ROOT=%CWFolder%\" - goto :eof ) -call :Clear_Error -call :Test_Path mwcc.exe -if not errorlevel 1 ( - set "BOOST_JAM_TOOLSET=metrowerks" - set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\..\" - goto :eof) -call :Clear_Error -call :Error_Print "Could not find a suitable toolset." -goto :eof - - -:Guess_Yacc -REM Tries to find bison or yacc in common places so we can build the grammar. -call :Clear_Error -call :Test_Path yacc.exe -if not errorlevel 1 ( - set "YACC=yacc -d" - goto :eof) -call :Clear_Error -call :Test_Path bison.exe -if not errorlevel 1 ( - set "YACC=bison -d --yacc" - goto :eof) -call :Clear_Error -if EXIST "C:\Program Files\GnuWin32\bin\bison.exe" ( - set "YACC=C:\Program Files\GnuWin32\bin\bison.exe" -d --yacc - goto :eof) -call :Clear_Error -call :Error_Print "Could not find Yacc to build the Jam grammar." -goto :eof - - -:Start -set BOOST_JAM_TOOLSET= -set BOOST_JAM_ARGS= - -REM If no arguments guess the toolset; -REM or if first argument is an option guess the toolset; -REM otherwise the argument is the toolset to use. -call :Clear_Error -call :Test_Empty %1 -if not errorlevel 1 ( - call :Guess_Toolset - if not errorlevel 1 ( goto Setup_Toolset ) else ( goto Finish ) -) - -call :Clear_Error -call :Test_Option %1 -if not errorlevel 1 ( - call :Guess_Toolset - if not errorlevel 1 ( goto Setup_Toolset ) else ( goto Finish ) -) - -call :Clear_Error -set BOOST_JAM_TOOLSET=%1 -shift -goto Setup_Toolset - - -:Setup_Toolset -REM Setup the toolset command and options. This bit of code -REM needs to be flexible enough to handle both when -REM the toolset was guessed at and found, or when the toolset -REM was indicated in the command arguments. -REM NOTE: The strange multiple "if ?? == _toolset_" tests are that way -REM because in BAT variables are subsituted only once during a single -REM command. A complete "if ... ( commands ) else ( commands )" -REM is a single command, even though it's in multiple lines here. -:Setup_Args -call :Clear_Error -call :Test_Empty %1 -if not errorlevel 1 goto Config_Toolset -call :Clear_Error -call :Test_Option %1 -if errorlevel 1 ( - set BOOST_JAM_ARGS=%BOOST_JAM_ARGS% %1 - shift - goto Setup_Args -) -:Config_Toolset -if NOT "_%BOOST_JAM_TOOLSET%_" == "_metrowerks_" goto Skip_METROWERKS -if NOT "_%CWFolder%_" == "__" ( - set "BOOST_JAM_TOOLSET_ROOT=%CWFolder%\" - ) -set "PATH=%BOOST_JAM_TOOLSET_ROOT%Other Metrowerks Tools\Command Line Tools;%PATH%" -set "BOOST_JAM_CC=mwcc -runtime ss -cwd include -DNT -lkernel32.lib -ladvapi32.lib -luser32.lib" -set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe" -set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe" -set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe" -set "_known_=1" -:Skip_METROWERKS -if NOT "_%BOOST_JAM_TOOLSET%_" == "_msvc_" goto Skip_MSVC -if NOT "_%MSVCDir%_" == "__" ( - set "BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\" - ) -call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%bin\VCVARS32.BAT" -if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%" - ) -set "BOOST_JAM_CC=cl /nologo /GZ /Zi /MLd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG kernel32.lib advapi32.lib user32.lib" -set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0" -set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0" -set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0" -set "_known_=1" -:Skip_MSVC -if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc7_" goto Skip_VC7 -if NOT "_%VS71COMNTOOLS%_" == "__" ( - set "BOOST_JAM_TOOLSET_ROOT=%VS71COMNTOOLS%..\..\VC7\" - ) -if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%bin\VCVARS32.BAT" -if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - if "_%VCINSTALLDIR%_" == "__" ( - set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%" - ) ) -set "BOOST_JAM_CC=cl /nologo /GZ /Zi /MLd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG kernel32.lib advapi32.lib user32.lib" -set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0" -set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0" -set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0" -set "_known_=1" -:Skip_VC7 -if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc8_" goto Skip_VC8 -if NOT "_%VS80COMNTOOLS%_" == "__" ( - set "BOOST_JAM_TOOLSET_ROOT=%VS80COMNTOOLS%..\..\VC\" - ) -if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%VCVARSALL.BAT" %BOOST_JAM_ARGS% -if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - if "_%VCINSTALLDIR%_" == "__" ( - set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%" - ) ) -set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib" -set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0" -set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0" -set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0" -set "_known_=1" -:Skip_VC8 -if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc9_" goto Skip_VC9 -if NOT "_%VS90COMNTOOLS%_" == "__" ( - set "BOOST_JAM_TOOLSET_ROOT=%VS90COMNTOOLS%..\..\VC\" - ) -if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%VCVARSALL.BAT" %BOOST_JAM_ARGS% -if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - if "_%VCINSTALLDIR%_" == "__" ( - set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%" - ) ) -set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib" -set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0" -set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0" -set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0" -set "_known_=1" -:Skip_VC9 -if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc10_" goto Skip_VC10 -if NOT "_%VS100COMNTOOLS%_" == "__" ( - set "BOOST_JAM_TOOLSET_ROOT=%VS100COMNTOOLS%..\..\VC\" - ) -if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%VCVARSALL.BAT" %BOOST_JAM_ARGS% -if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - if "_%VCINSTALLDIR%_" == "__" ( - set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%" - ) ) -set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib" -set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0" -set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0" -set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0" -set "_known_=1" -:Skip_VC10 -if NOT "_%BOOST_JAM_TOOLSET%_" == "_borland_" goto Skip_BORLAND -if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - call :Test_Path bcc32.exe ) -if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - if not errorlevel 1 ( - set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\" - ) ) -if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - set "PATH=%BOOST_JAM_TOOLSET_ROOT%Bin;%PATH%" - ) -set "BOOST_JAM_CC=bcc32 -WC -w- -q -I%BOOST_JAM_TOOLSET_ROOT%Include -L%BOOST_JAM_TOOLSET_ROOT%Lib /DNT -nbootstrap" -set "BOOST_JAM_OPT_JAM=-ejam0" -set "BOOST_JAM_OPT_MKJAMBASE=-emkjambasejam0" -set "BOOST_JAM_OPT_YYACC=-eyyacc0" -set "_known_=1" -:Skip_BORLAND -if NOT "_%BOOST_JAM_TOOLSET%_" == "_como_" goto Skip_COMO -set "BOOST_JAM_CC=como -DNT" -set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe" -set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe" -set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe" -set "_known_=1" -:Skip_COMO -if NOT "_%BOOST_JAM_TOOLSET%_" == "_gcc_" goto Skip_GCC -set "BOOST_JAM_CC=gcc -DNT" -set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe" -set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe" -set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe" -set "_known_=1" -:Skip_GCC -if NOT "_%BOOST_JAM_TOOLSET%_" == "_gcc-nocygwin_" goto Skip_GCC_NOCYGWIN -set "BOOST_JAM_CC=gcc -DNT -mno-cygwin" -set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe" -set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe" -set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe" -set "_known_=1" -:Skip_GCC_NOCYGWIN -if NOT "_%BOOST_JAM_TOOLSET%_" == "_intel-win32_" goto Skip_INTEL_WIN32 -set "BOOST_JAM_CC=icl -DNT /nologo kernel32.lib advapi32.lib user32.lib" -set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0" -set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0" -set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0" -set "_known_=1" -:Skip_INTEL_WIN32 -if NOT "_%BOOST_JAM_TOOLSET%_" == "_mingw_" goto Skip_MINGW -if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" ( - set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%" - ) -set "BOOST_JAM_CC=gcc -DNT" -set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe" -set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe" -set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe" -set "_known_=1" -:Skip_MINGW -call :Clear_Error -if "_%_known_%_" == "__" ( - call :Error_Print "Unknown toolset: %BOOST_JAM_TOOLSET%" -) -if errorlevel 1 goto Finish - -echo ### -echo ### Using '%BOOST_JAM_TOOLSET%' toolset. -echo ### - -set YYACC_SOURCES=yyacc.c -set MKJAMBASE_SOURCES=mkjambase.c -set BJAM_SOURCES= -set BJAM_SOURCES=%BJAM_SOURCES% command.c compile.c debug.c execnt.c expand.c filent.c glob.c hash.c -set BJAM_SOURCES=%BJAM_SOURCES% hdrmacro.c headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c -set BJAM_SOURCES=%BJAM_SOURCES% newstr.c option.c output.c parse.c pathunix.c regexp.c -set BJAM_SOURCES=%BJAM_SOURCES% rules.c scan.c search.c subst.c timestamp.c variable.c modules.c -set BJAM_SOURCES=%BJAM_SOURCES% strings.c filesys.c builtins.c md5.c pwd.c class.c w32_getreg.c native.c -set BJAM_SOURCES=%BJAM_SOURCES% modules/set.c modules/path.c modules/regex.c -set BJAM_SOURCES=%BJAM_SOURCES% modules/property-set.c modules/sequence.c modules/order.c - -set BJAM_UPDATE= -:Check_Update -call :Test_Empty %1 -if not errorlevel 1 goto Check_Update_End -call :Clear_Error -setlocal -set test=%1 -set test=###%test%### -set test=%test:"###=% -set test=%test:###"=% -set test=%test:###=% -if "%test%" == "--update" set BJAM_UPDATE=update -endlocal -shift -if not "_%BJAM_UPDATE%_" == "_update_" goto Check_Update -:Check_Update_End -if "_%BJAM_UPDATE%_" == "_update_" ( - if not exist ".\bootstrap\jam0.exe" ( - set BJAM_UPDATE= - ) -) - -@echo ON -@if "_%BJAM_UPDATE%_" == "_update_" goto Skip_Bootstrap -if exist bootstrap rd /S /Q bootstrap -md bootstrap -@if not exist jamgram.y goto Bootstrap_GrammarPrep -@if not exist jamgramtab.h goto Bootstrap_GrammarPrep -@goto Skip_GrammarPrep -:Bootstrap_GrammarPrep -%BOOST_JAM_CC% %BOOST_JAM_OPT_YYACC% %YYACC_SOURCES% -@if not exist ".\bootstrap\yyacc0.exe" goto Skip_GrammarPrep -.\bootstrap\yyacc0 jamgram.y jamgramtab.h jamgram.yy -:Skip_GrammarPrep -@if not exist jamgram.c goto Bootstrap_GrammarBuild -@if not exist jamgram.h goto Bootstrap_GrammarBuild -@goto Skip_GrammarBuild -:Bootstrap_GrammarBuild -@echo OFF -if "_%YACC%_" == "__" ( - call :Guess_Yacc -) -if errorlevel 1 goto Finish -@echo ON -%YACC% jamgram.y -@if errorlevel 1 goto Finish -del /f jamgram.c -rename y.tab.c jamgram.c -del /f jamgram.h -rename y.tab.h jamgram.h -:Skip_GrammarBuild -@echo ON -@if exist jambase.c goto Skip_Jambase -%BOOST_JAM_CC% %BOOST_JAM_OPT_MKJAMBASE% %MKJAMBASE_SOURCES% -@if not exist ".\bootstrap\mkjambase0.exe" goto Skip_Jambase -.\bootstrap\mkjambase0 jambase.c Jambase -:Skip_Jambase -%BOOST_JAM_CC% %BOOST_JAM_OPT_JAM% %BJAM_SOURCES% -:Skip_Bootstrap -@if not exist ".\bootstrap\jam0.exe" goto Skip_Jam -@if "_%BJAM_UPDATE%_" == "_update_" goto Skip_Clean -.\bootstrap\jam0 -f build.jam --toolset=%BOOST_JAM_TOOLSET% "--toolset-root=%BOOST_JAM_TOOLSET_ROOT% " clean -:Skip_Clean -@set args=%* -@echo OFF -:Set_Args -setlocal -call :Test_Empty %args% -if not errorlevel 1 goto Set_Args_End -set test=###%args:~0,2%### -set test=%test:"###=% -set test=%test:###"=% -set test=%test:###=% -set test=%test:~0,1% -if "-" == "%test%" goto Set_Args_End -endlocal -set args=%args:~1% -goto Set_Args -:Set_Args_End -@echo ON -.\bootstrap\jam0 -f build.jam --toolset=%BOOST_JAM_TOOLSET% "--toolset-root=%BOOST_JAM_TOOLSET_ROOT% " %args% -:Skip_Jam - -:Finish diff --git a/jam-files/engine/build.jam b/jam-files/engine/build.jam deleted file mode 100644 index 266b07a1..00000000 --- a/jam-files/engine/build.jam +++ /dev/null @@ -1,1070 +0,0 @@ -#~ Copyright 2002-2007 Rene Rivera. -#~ Distributed under the Boost Software License, Version 1.0. -#~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - -# Clean env vars of any "extra" empty values. -for local v in ARGV CC CFLAGS LIBS -{ - local values ; - for local x in $($(v)) - { - if $(x) != "" - { - values += $(x) ; - } - } - $(v) = $(values) ; -} - -# Platform related specifics. -if $(OS) = NT { rule .path { return "$(<:J=\\)" ; } ./ = "/" ; } -else if $(OS) = OS2 { rule .path { return "$(<:J=\\)" ; } ./ = "/" ; } -else if $(OS) = VMS { rule .path { return "[.$(<:J=/)]" ; } } -else if $(OS) = MAC { rule .path { return ":$(<:J=\:)" ; } } -else { rule .path { return "$(<:J=/)" ; } } -if $(OS) = VMS { . = "_" ; } -else { . = "." ; } -./ ?= "" ; - -# Info about what we are building. -_VERSION_ = 3 1 19 ; -NAME = boost-jam ; -VERSION = $(_VERSION_:J=$(.)) ; -RELEASE = 1 ; -LICENSE = LICENSE_1_0 ; - -# Generate development debug binaries? -if --debug in $(ARGV) -{ - debug = true ; -} - -if --profile in $(ARGV) -{ - profile = true ; -} - -# Attempt to generate and/or build the grammar? -if --grammar in $(ARGV) -{ - grammar = true ; -} - -# Do we need to add a default build type argument? -if ! ( --release in $(ARGV) ) && - ! ( --debug in $(ARGV) ) && - ! ( --profile in $(ARGV) ) -{ - ARGV += --release ; -} - -# Enable, and configure, Python hooks. -with-python = ; -python-location = [ MATCH --with-python=(.*) : $(ARGV) ] ; -if $(python-location) -{ - with-python = true ; -} -if $(with-python) -{ - if $(OS) = NT - { - --python-include = [ .path $(python-location) include ] ; - --python-lib = ; - for local v in 26 25 24 23 22 - { - --python-lib ?= - [ GLOB [ .path $(python-location) libs ] : "python$(v).lib" ] - [ GLOB $(python-location) [ .path $(python-location) libs ] - $(Path) $(PATH) $(path) : "python$(v).dll" ] - ; - if ! $(--python-lib[2]) - { - --python-lib = ; - } - } - --python-lib = $(--python-lib[1]) ; - } - else if $(OS) = MACOSX - { - --python-include = [ .path $(python-location) Headers ] ; - --python-lib = $(python-location) Python ; - } - else - { - --python-include = ; - --python-lib = ; - for local v in 2.6 2.5 2.4 2.3 2.2 - { - local inc = [ GLOB [ .path $(python-location) include ] : python$(v) ] ; - local lib = [ GLOB [ .path $(python-location) lib ] : libpython$(v)* ] ; - if $(inc) && $(lib) - { - --python-include ?= $(inc) ; - --python-lib ?= $(lib[1]:D) python$(v) ; - } - } - } -} - -# Boehm GC? -if --gc in $(ARGV) -{ - --boehm-gc = true ; -} -if $(--boehm-gc) -{ - --extra-include += [ .path [ PWD ] "boehm_gc" "include" ] ; -} - -# Duma? -if --duma in $(ARGV) -{ - --duma = true ; -} -if $(--duma) -{ - --extra-include += [ .path [ PWD ] "duma" ] ; -} - -# An explicit root for the toolset? (trim spaces) -toolset-root = [ MATCH --toolset-root=(.*) : $(ARGV) ] ; -{ - local t = [ MATCH "[ ]*(.*)" : $(toolset-root:J=" ") ] ; - toolset-root = ; - while $(t) - { - t = [ MATCH "([^ ]+)([ ]*)(.*)" : $(t) ] ; - toolset-root += $(t[1]) ; - if $(t[3]) { toolset-root += $(t[2]) ; } - t = $(t[3]) ; - } - toolset-root = $(toolset-root:J="") ; -} - -# Configure the implemented toolsets. These are minimal -# commands and options to compile the full Jam. When -# adding new toolsets make sure to add them to the -# "known" list also. - -rule toolset ( name command .type ? : opt.out + : opt.define * : flags * : linklibs * ) -{ - .type ?= "" ; - tool.$(name)$(.type).cc ?= $(command) ; - tool.$(name)$(.type).opt.out ?= $(opt.out) ; - tool.$(name)$(.type).opt.define ?= $(opt.define) ; - tool.$(name)$(.type).flags ?= $(flags) ; - tool.$(name)$(.type).linklibs ?= $(linklibs) ; - if ! $(name) in $(toolsets) { toolsets += $(name) ; } -} - -rule if-os ( os + : yes-opt * : no-opt * ) - { if $(os) in $(OS) { return $(yes-opt) ; } else { return $(no-opt) ; } } - -rule opt ( type : yes-opt * : no-opt * ) - { if $(type) in $(ARGV) { return $(yes-opt) ; } else { return $(no-opt) ; } } - -## HP-UX aCC compiler -toolset acc cc : "-o " : -D - : -Ae - [ opt --release : -s -O3 ] - [ opt --debug : -g -pg ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Borland C++ 5.5.x -toolset borland bcc32 : -e -n : /D - : -WC -w- -q "-I$(toolset-root)Include" "-L$(toolset-root)Lib" - [ opt --release : -O2 -vi -w-inl ] - [ opt --debug : -v -Od -vi- ] - -I$(--python-include) -I$(--extra-include) - : $(--python-lib[1]) ; -## Generic Unix cc -if ! $(CC) { CC = cc ; } -toolset cc $(CC) : "-o " : -D - : $(CFLAGS) - [ opt --release : -s -O ] - [ opt --debug : -g ] - -I$(--python-include) -I$(--extra-include) - : $(LIBS) -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Comeau C/C++ 4.x -toolset como como : "-o " : -D - : --c - [ opt --release : --inlining ] - [ opt --debug : --no_inlining ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Clang Linux 2.8+ -toolset clang clang : "-o " : -D - : -Wno-unused -Wno-format - [ opt --release : -Os ] - [ opt --debug : -g -O0 -fno-inline ] - [ opt --profile : -finline-functions -g ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## MacOSX Darwin, using GCC 2.9.x, 3.x -toolset darwin cc : "-o " : -D - : - [ opt --release : -Wl,-x -O3 -finline-functions ] - [ opt --debug : -g -O0 -fno-inline -pg ] - [ opt --profile : -Wl,-x -O3 -finline-functions -g -pg ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## GCC 2.x, 3.x, 4.x -toolset gcc gcc : "-o " : -D - : -pedantic -fno-strict-aliasing - [ opt --release : [ opt --symbols : -g : -s ] -O3 ] - [ opt --debug : -g -O0 -fno-inline ] - -I$(--python-include) -I$(--extra-include) -Wno-long-long - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## GCC 2.x, 3.x on CYGWIN but without cygwin1.dll -toolset gcc-nocygwin gcc : "-o " : -D - : -s -O3 -mno-cygwin - [ opt --release : -finline-functions ] - [ opt --debug : -s -O3 -fno-inline -pg ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Intel C/C++ for Darwin -toolset intel-darwin icc : "-o " : -D - : - [ opt --release : -O3 ] - [ opt --debug : -g -O0 -p ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Intel C/C++ for Linux -toolset intel-linux icc : "-o " : -D - : - [ opt --release : -Xlinker -s -O3 ] - [ opt --debug : -g -O0 -p ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Intel C/C++ for Win32 -toolset intel-win32 icl : /Fe : -D - : /nologo - [ opt --release : /MT /O2 /Ob2 /Gy /GF /GA /GB ] - [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 ] - -I$(--python-include) -I$(--extra-include) - : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ; -## KCC ? -toolset kcc KCC : "-o " : -D - : - [ opt --release : -s +K2 ] - [ opt --debug : -g +K0 ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Borland Kylix -toolset kylix bc++ : -o : -D - : -tC -q - [ opt --release : -O2 -vi -w-inl ] - [ opt --debug : -v -Od -vi- ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Metrowerks CodeWarrior 8.x -{ - # Even though CW can compile all files at once, it crashes if it tries in the bjam case. - local mwcc = ; if $(OS) = NT { mwcc = mwcc ; } else { mwcc = mwc$(OSPLAT:L) ; } - mwcc ?= mwcc ; - toolset metrowerks $(mwcc) : "-o " : -D - : -c -lang c -subsystem console -cwd include - [ opt --release : -runtime ss -opt full -inline all ] - [ opt --debug : -runtime ssd -opt none -inline off ] - -I$(--python-include) -I$(--extra-include) ; - toolset metrowerks $(mwcc) .link : "-o " : - : -subsystem console -lkernel32.lib -ladvapi32.lib -luser32.lib - [ opt --release : -runtime ss ] - [ opt --debug : -runtime ssd ] - : $(--python-lib[1]) ; -} -## MINGW GCC -toolset mingw gcc : "-o " : -D - : - [ opt --release : -s -O3 -finline-functions ] - [ opt --debug : -g -O0 -fno-inline -pg ] - -I$(--python-include) -I$(--extra-include) - : $(--python-lib[2]) ; -## MIPS Pro -toolset mipspro cc : "-o " : -D - : - [ opt --release : -s -O3 -g0 -INLINE:none ] - [ opt --debug : -g -O0 -INLINE ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Microsoft Visual Studio C++ 6.x -toolset msvc cl : /Fe /Fe /Fd /Fo : -D - : /nologo - [ opt --release : /ML /O2 /Ob2 /Gy /GF /GA /GB ] - [ opt --debug : /MLd /DEBUG /Z7 /Od /Ob0 ] - -I$(--python-include) -I$(--extra-include) - : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ; -## QNX 6.x GCC 3.x/2.95.3 -toolset qcc qcc : "-o " : -D - : -Wc,-pedantic -Wc,-fno-strict-aliasing - [ opt --release : [ opt --symbols : -g ] -O3 -Wc,-finline-functions ] - [ opt --debug : -g -O0 -Wc,-fno-inline ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Qlogic Pathscale 2.4 -toolset pathscale pathcc : "-o " : -D - : - [ opt --release : -s -Ofast -O3 ] - [ opt --debug : -g ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Portland Group Pgi 6.2 -toolset pgi pgcc : "-o " : -D - : - [ opt --release : -s -O3 ] - [ opt --debug : -g ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Sun Workshop 6 C++ -toolset sun cc : "-o " : -D - : - [ opt --release : -s -fast -xO4 ] - [ opt --debug : -g ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Sun Workshop 6 C++ (old alias) -toolset sunpro cc : "-o " : -D - : - [ opt --release : -s -fast -xO4 ] - [ opt --debug : -g ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## Compaq Alpha CXX -toolset tru64cxx cc : "-o " : -D - : - [ opt --release : -s -O5 -inline speed ] - [ opt --debug : -g -O0 -pg ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; -## IBM VisualAge C++ -toolset vacpp xlc : "-o " : -D - : - [ opt --release : -s -O3 -qstrict -qinline ] - [ opt --debug : -g -qNOOPTimize -qnoinline -pg ] - -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) [ if-os AIX : -bmaxdata:0x40000000 ] ; -## Microsoft Visual C++ .NET 7.x -toolset vc7 cl : /Fe /Fe /Fd /Fo : -D - : /nologo - [ opt --release : /ML /O2 /Ob2 /Gy /GF /GA /GB ] - [ opt --debug : /MLd /DEBUG /Z7 /Od /Ob0 ] - -I$(--python-include) -I$(--extra-include) - : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ; -## Microsoft Visual C++ 2005 -toolset vc8 cl : /Fe /Fe /Fd /Fo : -D - : /nologo - [ opt --release : /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ] - [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ] - -I$(--python-include) -I$(--extra-include) - : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ; -## Microsoft Visual C++ 2008 -toolset vc9 cl : /Fe /Fe /Fd /Fo : -D - : /nologo - [ opt --release : /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ] - [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ] - -I$(--python-include) -I$(--extra-include) - : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ; -## Microsoft Visual C++ 2010 -toolset vc10 cl : /Fe /Fe /Fd /Fo : -D - : /nologo - [ opt --release : /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ] - [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ] - -I$(--python-include) -I$(--extra-include) - : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ; -## VMS/OpenVMS DEC C -toolset vmsdecc cc : /OBJECT= : "/DEFINES=(" "," ")" - : /STANDARD=VAXC /PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES - [ opt --release : /OPTIMIZE /NODEBUG ] - [ opt --debug : /NOOPTIMIZE /DEBUG ] - ; -toolset vmsdecc link .link : /EXECUTABLE= : - : /NOMAP - [ opt --release : /NODEBUG ] - [ opt --debug : /DEBUG ] - ; - -# First set the build commands and options according to the -# preset toolset. -toolset = [ MATCH --toolset=(.*) : $(ARGV) ] ; -if ! $(toolset) -{ - # For some reason, the following test does not catch empty toolset. - ECHO "###" ; - ECHO "###" No toolset specified. Please use --toolset option. ; - ECHO "###" ; - ECHO "###" Known toolsets are: $(toolsets:J=", ") ; - EXIT "###" ; -} -if ! $(toolset) in $(toolsets) -{ - ECHO "###" ; - ECHO "###" Unknown toolset: $(toolset) ; - ECHO "###" ; - ECHO "###" Known toolsets are: $(toolsets:J=", ") ; - EXIT "###" ; -} ---cc = $(tool.$(toolset).cc) ; -if $(tool.$(toolset).opt.out[2]) -{ - if $(tool.$(toolset).opt.out[1]) = $(tool.$(toolset).opt.out[2]) - { - --out = $(tool.$(toolset).opt.out[1]) ; - --dir = $(tool.$(toolset).opt.out[3-]) ; - } - else - { - --bin = $(tool.$(toolset).opt.out[1]) ; - --dir = $(tool.$(toolset).opt.out[2-]) ; - } -} -else -{ - --out = $(tool.$(toolset).opt.out) ; -} ---def = $(tool.$(toolset).opt.define) ; ---flags = $(tool.$(toolset).flags) ; ---defs = $(tool.$(toolset).defines) ; ---libs = $(tool.$(toolset).linklibs) ; -if $(tool.$(toolset).link.cc) -{ - --link = $(tool.$(toolset).link.cc) ; - if $(tool.$(toolset).link.opt.out[2]) - { - if $(tool.$(toolset).link.opt.out[1]) = $(tool.$(toolset).link.opt.out[2]) - { - --link-out = $(tool.$(toolset).link.opt.out[1]) ; - --link-dir = $(tool.$(toolset).link.opt.out[3-]) ; - } - else - { - --link-bin = $(tool.$(toolset).link.opt.out[1]) ; - --link-dir = $(tool.$(toolset).link.opt.out[2-]) ; - } - } - else - { - --link-out = $(tool.$(toolset).link.opt.out) ; - } - --link-def = $(tool.$(toolset).link.opt.define) ; - --link-flags = $(tool.$(toolset).link.flags) ; - --link-defs = $(tool.$(toolset).link.defines) ; - --link-libs = $(tool.$(toolset).link.linklibs) ; -} - -# Put executables in platform-specific subdirectory. -locate-target = $(LOCATE_TARGET) ; -if $(OS) = VMS -{ - locate-target ?= bin$(.)vms ; - platform = vms ; -} -else if $(OS) = MAC -{ - locate-target ?= bin$(.)$(OS:L)$(OSPLAT:L) ; - platform = $(OS:L)$(OSPLAT:L) ; -} -else if $(OSPLAT) -{ - locate-target ?= bin$(.)$(OS:L)$(OSPLAT:L) ; - platform = $(OS:L)$(OSPLAT:L) ; -} -else -{ - locate-target ?= bin$(.)$(OS:L) ; - platform = $(OS:L) ; -} -if $(debug) -{ - locate-target = [ .path $(locate-target)$(.)debug ] ; -} -if $(profile) -{ - locate-target = [ .path $(locate-target)$(.)profile ] ; -} -else -{ - locate-target = [ .path $(locate-target) ] ; -} - -if --show-locate-target in $(ARGV) -{ - ECHO $(locate-target) ; -} - -# We have some different files for UNIX, VMS, and NT. -jam.source = - command.c compile.c debug.c expand.c glob.c - hash.c hcache.c headers.c hdrmacro.c - jam.c jambase.c jamgram.c - lists.c make.c make1.c mem.c newstr.c - option.c output.c parse.c regexp.c rules.c - scan.c search.c subst.c w32_getreg.c - timestamp.c variable.c modules.c strings.c filesys.c - builtins.c pwd.c class.c native.c md5.c modules/set.c - modules/path.c modules/regex.c modules/property-set.c - modules/sequence.c modules/order.c - ; -if $(OS) = NT -{ - jam.source += execnt.c filent.c pathunix.c ; -} -else if $(OS) = OS2 -{ - jam.source += execunix.c fileos2.c pathunix.c ; -} -else if $(OS) = VMS -{ - jam.source += execvms.c filevms.c pathvms.c ; -} -else if $(OS) = MAC -{ - jam.source += execmac.c filemac.c pathmac.c ; -} -else -{ - jam.source += execunix.c fileunix.c pathunix.c ; -} - -# Debug assertions, or not. -if ! $(debug) || --noassert in $(ARGV) -{ - --defs += NDEBUG ; -} - -# Enable some optional features. ---defs += OPT_HEADER_CACHE_EXT ; ---defs += OPT_GRAPH_DEBUG_EXT ; ---defs += OPT_SEMAPHORE ; ---defs += OPT_AT_FILES ; ---defs += OPT_DEBUG_PROFILE ; - -# Bug fixes ---defs += OPT_FIX_TARGET_VARIABLES_EXT ; -#~ --defs += OPT_NO_EXTERNAL_VARIABLE_SPLIT ; - -# Improvements ---defs += OPT_IMPROVED_PATIENCE_EXT ; - -# Use Boehm GC memory allocator? -if $(--boehm-gc) -{ - --defs += OPT_BOEHM_GC ; - if $(debug) - { - --defs += GC_DEBUG ; - } -} - -if $(--duma) -{ - --defs += OPT_DUMA ; -} - -if ( $(OS) = NT ) && ! NT in $(--defs) -{ - --defs += NT ; -} -if $(OS) = VMS -{ - --defs += VMS ; -} ---defs += YYSTACKSIZE=5000 ; - -if $(with-python) -{ - --defs += HAVE_PYTHON ; -} - -if $(debug) -{ - --defs += BJAM_NEWSTR_NO_ALLOCATE ; -} - - -# The basic symbolic targets... -NOTFILE all clean dist ; -ALWAYS clean ; - -# Utility rules and actions... -rule .clean -{ - [DELETE] clean : $(<) ; -} -if $(OS) = NT { actions piecemeal together existing [DELETE] { - del /F /Q "$(>)" -} } -if $(UNIX) = true { actions piecemeal together existing [DELETE] { - rm -f "$(>)" -} } -if $(OS) = VMS { actions piecemeal together existing [DELETE] { - DELETE $(>[--2]:J=";*, ") $(>[-1]);* -} } -if $(OS) = NT { - --chmod+w = "attrib -r " ; -} -if $(UNIX) = true { - --chmod+w = "chmod +w " ; -} -if $(OS) = VMS { - --chmod+w = "SET FILE/PROT=(S:RWED) " ; -} - -rule .mkdir -{ - NOUPDATE $(<) ; - if $(<:P) { DEPENDS $(<) : $(<:P) ; .mkdir $(<:P) ; } - if ! $(md<$(<)>) { [MKDIR] $(<) ; md<$(<)> = - ; } -} -if $(OS) = NT { actions [MKDIR] { - md "$(<)" -} } -if $(UNIX) = true { actions [MKDIR] { - mkdir "$(<)" -} } -if $(OS) = VMS { actions [MKDIR] { - CREATE/DIR $(<J=", ") -} } - -rule .exe -{ - local exe = $(<) ; - if $(OS) = NT || ( $(UNIX) = true && $(OS) = CYGWIN ) || $(OS) = VMS { exe = $(exe:S=.exe) ; } - LOCATE on $(exe) = $(locate-target) ; - DEPENDS all : $(exe) ; - .mkdir $(locate-target) ; - if $(--link) - { - local objs = ; - for local s in $(>) - { - # Translate any subdir elements into a simple file name. - local o = [ MATCH "([^/]+)[/]?(.+)" : $(s) ] ; - o = $(o:J=_) ; - o = $(o:S=.o) ; - objs += $(o) ; - LOCATE on $(o) = $(locate-target) ; - DEPENDS $(exe) : $(o) ; - DEPENDS $(o) : $(s) ; - DEPENDS $(o) : $(locate-target) ; - [COMPILE] $(o) : $(s) ; - .clean $(o) ; - } - DEPENDS $(exe) : $(objs) ; - DEPENDS $(exe) : $(locate-target) ; - [COMPILE.LINK] $(exe) : $(objs) ; - .clean $(exe) ; - } - else - { - DEPENDS $(exe) : $(>) ; - DEPENDS $(exe) : $(locate-target) ; - [COMPILE] $(exe) : $(>) ; - .clean $(exe) ; - } - return $(exe) ; -} -if ! $(--def[2]) { actions [COMPILE] { - "$(--cc)" "$(--bin)$(<:D=)" "$(--dir)$(<:D)$(./)" $(--out)$(<) "$(--def)$(--defs)" "$(--flags)" "$(--libs)" "$(>)" -} } -else { actions [COMPILE] { - "$(--cc)" "$(--bin)$(<:D=)" "$(--dir)$(<:D)$(./)" $(--out)$(<) "$(--def[1])$(--defs:J=$(--def[2]))$(--def[3])" "$(--flags)" "$(--libs)" "$(>)" -} } -if $(OS) = VMS { actions [COMPILE.LINK] { - "$(--link)" $(--link-bin)$(<:D=) $(--link-dir)$(<:D)$(./) $(--link-out)$(<) $(--link-def)$(--link-defs) $(--link-flags) "$(--link-libs)" $(>J=", ") -} } -else { actions [COMPILE.LINK] { - "$(--link)" "$(--link-bin)$(<:D=)" "$(--link-dir)$(<:D)$(./)" "$(--link-out)$(<)" "$(--link-def)$(--link-defs)" "$(--link-flags)" "$(--link-libs)" "$(>)" -} } - -rule .link -{ - DEPENDS all : $(<) ; - DEPENDS $(<) : $(>) ; - [LINK] $(<) : $(>) ; - .clean $(<) ; -} -if $(OS) = NT { actions [LINK] { - copy "$(>)" "$(<)" -} } -if $(UNIX) = true { actions [LINK] { - ln -fs "$(>)" "$(<)" -} } -if $(OS) = VMS { actions [LINK] { - COPY/REPLACE $(>) $(<) -} } - -rule .copy -{ - DEPENDS all : $(<) ; - DEPENDS $(<) : $(>) ; - [COPY] $(<) : $(>) ; - .clean $(<) ; -} - -# Will be redefined later. -actions [COPY] -{ -} - - -rule .move -{ - DEPENDS $(<) : $(>) ; - [MOVE] $(<) : $(>) ; -} -if $(OS) = NT { actions [MOVE] { - del /f "$(<)" - rename "$(>)" "$(<)" -} } -if $(UNIX) = true { actions [MOVE] { - mv -f "$(>)" "$(<)" -} } -if $(OS) = VMS { actions [MOVE] { - RENAME "$(>)" "$(<)" -} } - -# Generate the grammar tokens table, and the real yacc grammar. -rule .yyacc -{ - local exe = [ .exe yyacc : yyacc.c ] ; - NOUPDATE $(exe) ; - DEPENDS $(<) : $(exe) $(>) ; - LEAVES $(<) ; - yyacc.exe on $(<) = $(exe:R=$(locate-target)) ; - [YYACC] $(<) : $(>) ; -} -actions [YYACC] { - $(--chmod+w)$(<[1]) - $(--chmod+w)$(<[2]) - "$(yyacc.exe)" "$(<)" "$(>)" -} -if $(grammar) -{ - .yyacc jamgram.y jamgramtab.h : jamgram.yy ; -} -else if $(debug) -{ - .exe yyacc : yyacc.c ; -} - -# How to build the grammar. -if $(OS) = NT -{ - SUFEXE = .exe ; - # try some other likely spellings... - PATH ?= $(Path) ; - PATH ?= $(path) ; -} -SUFEXE ?= "" ; - -yacc ?= [ GLOB $(PATH) : yacc$(SUFEXE) ] ; -yacc ?= [ GLOB $(PATH) : bison$(SUFEXE) ] ; -yacc ?= [ GLOB "$(ProgramFiles:J= )\\GnuWin32\\bin" "C:\\Program Files\\GnuWin32\\bin" : bison$(SUFEXE) ] ; -yacc = $(yacc[1]) ; -switch $(yacc:D=:S=) -{ - case bison : yacc += -d --yacc ; - case yacc : yacc += -d ; -} -if $(debug) && $(yacc) -{ - yacc += -t -v ; -} -yacc += $(YACCFLAGS) ; - -rule .yacc -{ - DEPENDS $(<) : $(>) ; - LEAVES $(<) ; - [YACC] $(<) : $(>) ; -} -if $(OS) = NT { actions [YACC] { - "$(yacc)" "$(>)" - if not errorlevel 1 ( - del /f "$(<[1])" - rename y.tab$(<[1]:S) "$(<[1])" - del /f $(<[2]) - rename y.tab$(<[2]:S) "$(<[2])" - ) else set _error_ = -} } -if $(UNIX) = true { actions [YACC] { - if ` "$(yacc)" "$(>)" ` ; then - mv -f y.tab$(<[1]:S) "$(<[1])" - mv -f y.tab$(<[2]:S) "$(<[2])" - else - exit 1 - fi -} } -if $(OS) = VMS { actions [YACC] { - IF "$(yacc)" $(>) - THEN - RENAME y_tab$(<[1]:S) $(<[1]) - RENAME y_tab$(<[2]:S) $(<[2]) - ENDIF -} } -if $(grammar) && ! $(yacc) -{ - EXIT "Could not find the 'yacc' tool, and therefore can not build the grammar." ; -} -if $(grammar) && $(yacc) -{ - .yacc jamgram.c jamgram.h : jamgram.y ; -} - -# How to build the compiled in jambase. -rule .mkjambase -{ - local exe = [ .exe mkjambase : mkjambase.c ] ; - DEPENDS $(<) : $(exe) $(>) ; - LEAVES $(<) ; - mkjambase.exe on $(<) = $(exe:R=$(locate-target)) ; - [MKJAMBASE] $(<) : $(>) ; -} -actions [MKJAMBASE] { - $(--chmod+w)$(<) - $(mkjambase.exe) "$(<)" "$(>)" -} -if $(debug) -{ - .mkjambase jambase.c : Jambase ; -} - -# How to build Jam. -rule .jam -{ - $(>).exe = [ .exe $(>) : $(jam.source) ] ; - DEPENDS all : $($(>).exe) ; - - # Make a copy under the old name. - $(<).exe = $(<:S=$($(>).exe:S)) ; - LOCATE on $($(<).exe) = $(locate-target) ; - .copy $($(<).exe) : $($(>).exe) ; - DEPENDS all : $($(<).exe) ; -} -.jam bjam : b2 ; - - -# Scan sources for header dependencies. -# WARNING: Yes those are *REAL TABS* below. DO NOT CHANGE, -# under any circumstances, to spaces!! And the tabs -# indenting this are so that if someone is in the mood to -# replace tabs they hit this comment, and hopefully notice -# their error. -rule .scan -{ - HDRRULE on $(<:D=) = .hdr.scan ; - HDRSCAN on $(<:D=) = "^[ ]*#[ ]*include[ ]*([<\"][^\">]*[\">]).*$" ; -} -rule .hdr.scan -{ - local hdrs = [ GLOB . : $(>:D=) ] ; - INCLUDES $(<:D=) : $(hdrs:D=) ; - HDRRULE on $(>:D=) = .hdr.scan ; - HDRSCAN on $(>:D=) = "^[ ]*#[ ]*include[ ]*([<\"][^\">]*[\">]).*$" ; -} -.scan [ GLOB . : *.c ] ; - -# Distribution making from here on out. Assumes that -# the docs are already built as html at ../doc/html. If -# they aren't, then the docs are not included in the dist -# archive. -dist.license = - [ GLOB . : $(LICENSE).txt ] - ; -dist.license = $(dist.license:D=) - [ GLOB [ .path .. .. .. ] : $(LICENSE).txt ] - [ GLOB [ .path .. boost ] : $(LICENSE).txt ] ; -dist.docs = - [ GLOB . : *.png *.css *.html ] - ; -dist.docs = $(dist.docs:D=) - [ GLOB [ .path images ] : *.png ] - [ GLOB [ .path jam ] : *.html ] - ; -dist.source = - [ GLOB . : *.c *.h ] - ; -dist.source = $(dist.source:D=) - $(dist.license[1]) - $(dist.docs) - build.jam build.bat build.sh build_vms.com - Jambase - jamgram.y jamgram.yy - [ .path modules set.c ] - [ .path modules path.c ] - [ .path modules regex.c ] - [ .path modules property-set.c ] - [ .path modules sequence.c ] - [ .path modules order.c ] - [ GLOB [ .path boehm_gc ] : * ] - [ GLOB [ .path boehm_gc include ] : * ] - [ GLOB [ .path boehm_gc include private ] : * ] - [ GLOB [ .path boehm_gc cord ] : * ] - [ GLOB [ .path boehm_gc Mac_files ] : * ] - [ GLOB [ .path boehm_gc tests ] : * ] - [ GLOB [ .path boehm_gc doc ] : * ] - ; -dist.bin = - bjam - ; -dist.bin = - $(dist.license[1]) - $(dist.bin:S=$(bjam.exe:S)) - ; - -if $(OS) = NT -{ - zip ?= [ GLOB "$(ProgramFiles:J= )\\7-ZIP" "C:\\Program Files\\7-ZIP" : "7z.exe" ] ; - zip ?= [ GLOB "$(ProgramFiles:J= )\\7-ZIP" "C:\\Program Files\\7-ZIP" : "7zn.exe" ] ; - zip ?= [ GLOB $(PATH) : zip.exe ] ; - zip ?= zip ; - zip = $(zip[1]) ; - switch $(zip:D=:S=) - { - case 7z* : zip += a -r -tzip -mx=9 ; - case zip : zip += -9r ; - } - actions piecemeal [PACK] { - "$(zip)" "$(<)" "$(>)" - } - actions piecemeal [ZIP] { - "$(zip)" "$(<)" "$(>)" - } - actions piecemeal [COPY] { - copy /Y "$(>)" "$(<)" >NUL: - } -} -if $(UNIX) = true -{ - tar ?= [ GLOB $(PATH) : star bsdtar tar ] ; - tar = $(tar[1]) ; - switch $(tar:D=:S=) - { - case star : tar += -c artype=pax -D -d -to-stdout ; - case * : tar += -c -f - ; - } - actions [PACK] { - "$(tar)" "$(>)" | gzip -c9 > "$(<)" - } - #~ actions [PACK] { - #~ tar cf "$(<:S=.tar)" "$(>)" - #~ } - actions [ZIP] { - gzip -c9 "$(>)" > "$(<)" - } - actions [COPY] { - cp -Rpf "$(>)" "$(<)" - } -} - -# The single binary, compressed. -rule .binary -{ - local zip = ; - if $(OS) = NT { zip = $($(<).exe:S=.zip) ; } - if $(UNIX) = true { zip = $($(<).exe:S=.tgz) ; } - zip = $(zip:S=)-$(VERSION)-$(RELEASE)-$(platform)$(zip:S) ; - DEPENDS $(zip) : $($(<).exe) ; - DEPENDS dist : $(zip) ; - #~ LOCATE on $(zip) = $(locate-target) ; - if $(OS) = NT { [ZIP] $(zip) : $($(<).exe) ; } - if $(UNIX) = true { [PACK] $(zip) : $($(<).exe) ; } - .clean $(zip) ; -} - -# Package some file. -rule .package ( dst-dir : src-files + ) -{ - local dst-files ; - local src-files-actual ; - for local src-path in $(src-files) - { - if ! [ GLOB $(src-path:P) : $(src-path:B) ] || [ CHECK_IF_FILE $(src-path) ] - { - local src-subdir = $(src-path:D) ; - local src-file = $(src-path) ; - while $(src-subdir:D) { src-subdir = $(src-subdir:D) ; } - if $(src-subdir) = ".." - { - src-file = $(src-file:D=) ; - } - dst-files += $(src-file:R=$(dst-dir)) ; - src-files-actual += $(src-path) ; - } - } - - local pack = ; - if $(OS) = NT { pack = $(dst-dir).zip ; } - if $(UNIX) = true { pack = $(dst-dir).tgz ; } - - DEPENDS dist : $(pack) ; - DEPENDS $(pack) : $(dst-files) ; - - local dst-files-queue = $(dst-files) ; - for local src-path in $(src-files-actual) - { - local dst-file = $(dst-files-queue[1]) ; - dst-files-queue = $(dst-files-queue[2-]) ; - DEPENDS $(dst-file) : $(src-path) $(dst-file:D) ; - .mkdir $(dst-file:D) ; - - [COPY] $(dst-file) : $(src-path) ; - .clean $(dst-file) ; - } - - [PACK] $(pack) : $(dst-files) ; - .clean $(pack) ; -} - -# RPM distro file. -rpm-tool = [ GLOB $(PATH) : "rpmbuild" ] ; -rpm-tool ?= [ GLOB $(PATH) : "rpm" ] ; -rpm-tool = $(rpm-tool[1]) ; -rule .rpm ( name : source ) -{ - local rpm-arch = ; - switch $(OSPLAT) - { - case X86 : rpm-arch ?= i386 ; - case PPC : rpm-arch ?= ppc ; - case AXP : rpm-arch ?= alpha ; - # no guaranty for these: - case IA64 : rpm-arch ?= ia64 ; - case ARM : rpm-arch ?= arm ; - case SPARC : rpm-arch ?= sparc ; - case * : rpm-arch ?= other ; - } - local target = $(name)-rpm ; - NOTFILE $(target) ; - DEPENDS dist : $(target) ; - DEPENDS $(target) : $(name).$(rpm-arch).rpm $(name).src.rpm ; - DEPENDS $(name).$(rpm-arch).rpm : $(source) ; - DEPENDS $(name).src.rpm : $(name).$(rpm-arch).rpm ; - docs on $(target) = $(dist.docs:J=" ") ; - arch on $(target) = $(rpm-arch) ; - if $(rpm-arch) = ppc { target-opt on $(target) = --target= ; } - else { target-opt on $(target) = "--target " ; } - [RPM] $(target) : $(source) ; - .clean $(name).$(rpm-arch).rpm $(name).src.rpm ; -} -actions [RPM] { - set -e - export BOOST_JAM_TOOLSET="$(toolset)" - $(rpm-tool) -ta $(target-opt)$(arch) $(>) | tee rpm.out - cp `grep -e '^Wrote:' rpm.out | sed 's/^Wrote: //'` . - rm -f rpm.out -} - -# The distribution targets. Don't bother with the targets if -# distribution build not requested. -if dist in $(ARGV) -{ - #~ .binary bjam ; - .package $(NAME)-$(VERSION) : $(dist.source) ; - .package $(NAME)-$(VERSION)-$(RELEASE)-$(platform) : $(dist.bin) ; - if $(rpm-tool) - { - #~ .rpm $(NAME)-$(VERSION)-$(RELEASE) : $(NAME)-$(VERSION).tgz ; - } -} diff --git a/jam-files/engine/build.sh b/jam-files/engine/build.sh deleted file mode 100755 index f1fb806d..00000000 --- a/jam-files/engine/build.sh +++ /dev/null @@ -1,303 +0,0 @@ -#!/bin/sh - -#~ Copyright 2002-2005 Rene Rivera. -#~ Distributed under the Boost Software License, Version 1.0. -#~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - -# Reset the toolset. -BOOST_JAM_TOOLSET= - -# Run a command, and echo before doing so. Also checks the exit -# status and quits if there was an error. -echo_run () -{ - echo "$@" - $@ - r=$? - if test $r -ne 0 ; then - exit $r - fi -} - -# Print an error message, and exit with a status of 1. -error_exit () -{ - echo "###" - echo "###" "$@" - echo "###" - echo "### You can specify the toolset as the argument, i.e.:" - echo "### ./build.sh gcc" - echo "###" - echo "### Toolsets supported by this script are:" - echo "### acc, como, darwin, gcc, intel-darwin, intel-linux, kcc, kylix," - echo "### mipspro, mingw(msys), pathscale, pgi, qcc, sun, sunpro, tru64cxx, vacpp" - echo "###" - echo "### A special toolset; cc, is available which is used as a fallback" - echo "### when a more specific toolset is not found and the cc command is" - echo "### detected. The 'cc' toolset will use the CC, CFLAGS, and LIBS" - echo "### envrironment variables, if present." - echo "###" - exit 1 -} - -# Check that a command is in the PATH. -test_path () -{ - if `command -v command 1>/dev/null 2>/dev/null`; then - command -v $1 1>/dev/null 2>/dev/null - else - hash $1 1>/dev/null 2>/dev/null - fi -} - -# Check that the OS name, as returned by "uname", is as given. -test_uname () -{ - if test_path uname; then - test `uname` = $* - fi -} - -# Try and guess the toolset to bootstrap the build with... -Guess_Toolset () -{ - if test -r /mingw/bin/gcc ; then - BOOST_JAM_TOOLSET=mingw - BOOST_JAM_TOOLSET_ROOT=/mingw/ - elif test_uname Darwin ; then BOOST_JAM_TOOLSET=darwin - elif test_uname IRIX ; then BOOST_JAM_TOOLSET=mipspro - elif test_uname IRIX64 ; then BOOST_JAM_TOOLSET=mipspro - elif test_uname OSF1 ; then BOOST_JAM_TOOLSET=tru64cxx - elif test_uname QNX && test_path qcc ; then BOOST_JAM_TOOLSET=qcc - elif test_path gcc ; then BOOST_JAM_TOOLSET=gcc - elif test_path icc ; then BOOST_JAM_TOOLSET=intel-linux - elif test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET=intel-linux - BOOST_JAM_TOOLSET_ROOT=/opt/intel/cc/9.0 - elif test -r /opt/intel_cc_80/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET=intel-linux - BOOST_JAM_TOOLSET_ROOT=/opt/intel_cc_80 - elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET=intel-linux - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler70/ia32/ - elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET=intel-linux - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler60/ia32/ - elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET=intel-linux - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler50/ia32/ - elif test_path pgcc ; then BOOST_JAM_TOOLSET=pgi - elif test_path pathcc ; then BOOST_JAM_TOOLSET=pathscale - elif test_path xlc ; then BOOST_JAM_TOOLSET=vacpp - elif test_path como ; then BOOST_JAM_TOOLSET=como - elif test_path KCC ; then BOOST_JAM_TOOLSET=kcc - elif test_path bc++ ; then BOOST_JAM_TOOLSET=kylix - elif test_path aCC ; then BOOST_JAM_TOOLSET=acc - elif test_uname HP-UX ; then BOOST_JAM_TOOLSET=acc - elif test -r /opt/SUNWspro/bin/cc ; then - BOOST_JAM_TOOLSET=sunpro - BOOST_JAM_TOOLSET_ROOT=/opt/SUNWspro/ - # Test for "cc" as the default fallback. - elif test_path $CC ; then BOOST_JAM_TOOLSET=cc - elif test_path cc ; then - BOOST_JAM_TOOLSET=cc - CC=cc - fi - if test "$BOOST_JAM_TOOLSET" = "" ; then - error_exit "Could not find a suitable toolset." - fi -} - -# The one option we support in the invocation -# is the name of the toolset to force building -# with. -case "$1" in - --guess-toolset) Guess_Toolset ; echo "$BOOST_JAM_TOOLSET" ; exit 1 ;; - -*) Guess_Toolset ;; - ?*) BOOST_JAM_TOOLSET=$1 ; shift ;; - *) Guess_Toolset ;; -esac -BOOST_JAM_OPT_JAM="-o bootstrap/jam0" -BOOST_JAM_OPT_MKJAMBASE="-o bootstrap/mkjambase0" -BOOST_JAM_OPT_YYACC="-o bootstrap/yyacc0" -case $BOOST_JAM_TOOLSET in - mingw) - if test -r ${BOOST_JAM_TOOLSET_ROOT}bin/gcc ; then - export PATH=${BOOST_JAM_TOOLSET_ROOT}bin:$PATH - fi - BOOST_JAM_CC="gcc -DNT" - ;; - - gcc) - BOOST_JAM_CC=gcc - ;; - - darwin) - BOOST_JAM_CC=cc - ;; - - intel-darwin) - BOOST_JAM_CC=icc - ;; - - intel-linux) - if test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel/cc/9.0/ - elif test -r /opt/intel_cc_80/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel_cc_80/ - elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler70/ia32/ - elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler60/ia32/ - elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler50/ia32/ - fi - if test -r ${BOOST_JAM_TOOLSET_ROOT}bin/iccvars.sh ; then - # iccvars doesn't change LD_RUN_PATH. We adjust LD_RUN_PATH - # here in order not to have to rely on ld.so.conf knowing the - # icc library directory. We do this before running iccvars.sh - # in order to allow a user to add modifications to LD_RUN_PATH - # in iccvars.sh. - if test -z "${LD_RUN_PATH}"; then - LD_RUN_PATH="${BOOST_JAM_TOOLSET_ROOT}lib" - else - LD_RUN_PATH="${BOOST_JAM_TOOLSET_ROOT}lib:${LD_RUN_PATH}" - fi - export LD_RUN_PATH - . ${BOOST_JAM_TOOLSET_ROOT}bin/iccvars.sh - fi - BOOST_JAM_CC=icc - ;; - - vacpp) - BOOST_JAM_CC=xlc - ;; - - como) - BOOST_JAM_CC="como --c" - ;; - - kcc) - BOOST_JAM_CC=KCC - ;; - - kylix) - BOOST_JAM_CC=bc++ - ;; - - mipspro) - BOOST_JAM_CC=cc - ;; - - pathscale) - BOOST_JAM_CC=pathcc - ;; - - pgi) - BOOST_JAM_CC=pgcc - ;; - - sun*) - if test -z "${BOOST_JAM_TOOLSET_ROOT}" -a -r /opt/SUNWspro/bin/cc ; then - BOOST_JAM_TOOLSET_ROOT=/opt/SUNWspro/ - fi - if test -r "${BOOST_JAM_TOOLSET_ROOT}bin/cc" ; then - PATH=${BOOST_JAM_TOOLSET_ROOT}bin:${PATH} - export PATH - fi - BOOST_JAM_CC=cc - ;; - - clang*) - BOOST_JAM_CC="clang -Wno-unused -Wno-format" - BOOST_JAM_TOOLSET=clang - ;; - - tru64cxx) - BOOST_JAM_CC=cc - ;; - - acc) - BOOST_JAM_CC="cc -Ae" - ;; - - cc) - if test -z "$CC" ; then CC=cc ; fi - BOOST_JAM_CC=$CC - BOOST_JAM_OPT_JAM="$BOOST_JAM_OPT_JAM $CFLAGS $LIBS" - BOOST_JAM_OPT_MKJAMBASE="$BOOST_JAM_OPT_MKJAMBASE $CFLAGS $LIBS" - BOOST_JAM_OPT_YYACC="$BOOST_JAM_OPT_YYACC $CFLAGS $LIBS" - ;; - - qcc) - BOOST_JAM_CC=qcc - ;; - - *) - error_exit "Unknown toolset: $BOOST_JAM_TOOLSET" - ;; -esac - -echo "###" -echo "### Using '$BOOST_JAM_TOOLSET' toolset." -echo "###" - -YYACC_SOURCES="yyacc.c" -MKJAMBASE_SOURCES="mkjambase.c" -BJAM_SOURCES="\ - command.c compile.c debug.c expand.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 output.c parse.c pathunix.c pathvms.c regexp.c\ - rules.c scan.c search.c subst.c timestamp.c variable.c modules.c\ - strings.c filesys.c builtins.c pwd.c class.c native.c md5.c w32_getreg.c\ - modules/set.c modules/path.c modules/regex.c modules/property-set.c\ - modules/sequence.c modules/order.c" -case $BOOST_JAM_TOOLSET in - mingw) - BJAM_SOURCES="${BJAM_SOURCES} execnt.c filent.c" - ;; - - *) - BJAM_SOURCES="${BJAM_SOURCES} execunix.c fileunix.c" - ;; -esac - -BJAM_UPDATE= -if test "$1" = "--update" -o "$2" = "--update" -o "$3" = "--update" -o "$4" = "--update" ; then - BJAM_UPDATE="update" -fi -if test "${BJAM_UPDATE}" = "update" -a ! -x "./bootstrap/jam0" ; then - BJAM_UPDATE= -fi - -if test "${BJAM_UPDATE}" != "update" ; then - echo_run rm -rf bootstrap - echo_run mkdir bootstrap - if test ! -r jamgram.y -o ! -r jamgramtab.h ; then - echo_run ${BOOST_JAM_CC} ${BOOST_JAM_OPT_YYACC} ${YYACC_SOURCES} - if test -x "./bootstrap/yyacc0" ; then - echo_run ./bootstrap/yyacc0 jamgram.y jamgramtab.h jamgram.yy - fi - fi - if test ! -r jamgram.c -o ! -r jamgram.h ; then - if test_path yacc ; then YACC="yacc -d" - elif test_path bison ; then YACC="bison -y -d --yacc" - fi - echo_run $YACC jamgram.y - mv -f y.tab.c jamgram.c - mv -f y.tab.h jamgram.h - fi - if test ! -r jambase.c ; then - echo_run ${BOOST_JAM_CC} ${BOOST_JAM_OPT_MKJAMBASE} ${MKJAMBASE_SOURCES} - if test -x "./bootstrap/mkjambase0" ; then - echo_run ./bootstrap/mkjambase0 jambase.c Jambase - fi - fi - echo_run ${BOOST_JAM_CC} ${BOOST_JAM_OPT_JAM} ${BJAM_SOURCES} -fi -if test -x "./bootstrap/jam0" ; then - if test "${BJAM_UPDATE}" != "update" ; then - echo_run ./bootstrap/jam0 -f build.jam --toolset=$BOOST_JAM_TOOLSET "--toolset-root=$BOOST_JAM_TOOLSET_ROOT" clean - fi - echo_run ./bootstrap/jam0 -f build.jam --toolset=$BOOST_JAM_TOOLSET "--toolset-root=$BOOST_JAM_TOOLSET_ROOT" "$@" -fi diff --git a/jam-files/engine/build_vms.com b/jam-files/engine/build_vms.com deleted file mode 100644 index 965b6342..00000000 --- a/jam-files/engine/build_vms.com +++ /dev/null @@ -1,105 +0,0 @@ -$ ! Copyright 2002-2003 Rene Rivera, Johan Nilsson. -$ ! Distributed under the Boost Software License, Version 1.0. -$ ! (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -$ ! -$ ! bootstrap build script for Jam -$ ! -$ SAY :== WRITE SYS$OUTPUT -$ ! -$ ON WARNING THEN CONTINUE -$ ! -$ IF "" .NES. F$SEARCH("[.bootstrap_vms]*.*") -$ THEN -$ SAY "Cleaning previous boostrap files..." -$ ! -$ SET FILE/PROTECTION=(S:RWED) [.bootstrap_vms]*.*;* -$ DELETE [.bootstrap_vms]*.*;* -$ ENDIF -$ ! -$ IF "" .NES. F$SEARCH("bootstrap_vms.dir") -$ THEN -$ SAY "Removing previous boostrap directory..." -$ ! -$ SET FILE/PROT=(S:RWED) bootstrap_vms.dir -$ DELETE bootstrap_vms.dir; -$ ENDIF -$ ! -$ SAY "Creating boostrap directory..." -$ ! -$ CREATE/DIR [.bootstrap_vms] -$ ! -$ SAY "Building bootstrap jam..." -$ ! -$ CC_FLAGS = "/DEFINE=VMS /STANDARD=VAXC /PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES " -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]builtins.obj builtins.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]command.obj command.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]compile.obj compile.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]execvms.obj execvms.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]expand.obj expand.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]filesys.obj filesys.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]filevms.obj filevms.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]glob.obj glob.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]hash.obj hash.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]hdrmacro.obj hdrmacro.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]headers.obj headers.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]jam.obj jam.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]jambase.obj jambase.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]jamgram.obj jamgram.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]lists.obj lists.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]make.obj make.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]make1.obj make1.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]modules.obj modules.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]newstr.obj newstr.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]option.obj option.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]parse.obj parse.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]pathvms.obj pathvms.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]pwd.obj pwd.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]regexp.obj regexp.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]rules.obj rules.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]scan.obj scan.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]search.obj search.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]strings.obj strings.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]subst.obj subst.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]timestamp.obj timestamp.c -$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]variable.obj variable.c -$ link - - /EXECUTABLE=[.bootstrap_vms]jam0.exe - - [.bootstrap_vms]builtins.obj, - - [.bootstrap_vms]command.obj, - - [.bootstrap_vms]compile.obj, - - [.bootstrap_vms]execvms.obj, - - [.bootstrap_vms]expand.obj, - - [.bootstrap_vms]filesys.obj, - - [.bootstrap_vms]filevms.obj, - - [.bootstrap_vms]glob.obj, - - [.bootstrap_vms]hash.obj, - - [.bootstrap_vms]hdrmacro.obj, - - [.bootstrap_vms]headers.obj, - - [.bootstrap_vms]jam.obj, - - [.bootstrap_vms]jambase.obj, - - [.bootstrap_vms]jamgram.obj, - - [.bootstrap_vms]lists.obj, - - [.bootstrap_vms]make.obj, - - [.bootstrap_vms]make1.obj, - - [.bootstrap_vms]modules.obj, - - [.bootstrap_vms]newstr.obj, - - [.bootstrap_vms]option.obj, - - [.bootstrap_vms]parse.obj, - - [.bootstrap_vms]pathvms.obj, - - [.bootstrap_vms]pwd.obj, - - [.bootstrap_vms]regexp.obj, - - [.bootstrap_vms]rules.obj, - - [.bootstrap_vms]scan.obj, - - [.bootstrap_vms]search.obj, - - [.bootstrap_vms]strings.obj, - - [.bootstrap_vms]subst.obj, - - [.bootstrap_vms]timestamp.obj, - - [.bootstrap_vms]variable.obj -$ ! -$ SAY "Cleaning any previous build..." -$ ! -$ MCR [.bootstrap_vms]jam0.exe -f build.jam --toolset=vmsdecc clean -$ ! -$ SAY "Building Boost.Jam..." -$ ! -$ MCR [.bootstrap_vms]jam0.exe -f build.jam --toolset=vmsdecc diff --git a/jam-files/engine/builtins.c b/jam-files/engine/builtins.c deleted file mode 100644 index b28a484e..00000000 --- a/jam-files/engine/builtins.c +++ /dev/null @@ -1,2310 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -#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 "frames.h" -#include "hash.h" -#include "strings.h" -#include "pwd.h" -#include "pathsys.h" -#include "make.h" -#include "hdrmacro.h" -#include "compile.h" -#include "native.h" -#include "variable.h" -#include "timestamp.h" -#include "md5.h" -#include <ctype.h> - -#if defined(USE_EXECUNIX) -# include <sys/types.h> -# include <sys/wait.h> -#else -/* - NT does not have wait() and associated macros, it uses the return value - of system() instead. Status code group are documented at - http://msdn.microsoft.com/en-gb/library/ff565436.aspx -*/ -# define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0) -# define WEXITSTATUS(w)(w) -#endif - -/* - * 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. - * - * 01/10/01 (seiwald) - split from compile.c - */ - - -/* - * compile_builtin() - define builtin rules - */ - -#define P0 (PARSE *)0 -#define C0 (char *)0 - -#if defined( OS_NT ) || defined( OS_CYGWIN ) - LIST * builtin_system_registry ( PARSE *, FRAME * ); - LIST * builtin_system_registry_names( PARSE *, FRAME * ); -#endif - -int glob( char * s, char * c ); - -void backtrace ( FRAME * ); -void backtrace_line ( FRAME * ); -void print_source_line( PARSE * ); - - -RULE * bind_builtin( char * name, LIST * (* f)( PARSE *, FRAME * ), int flags, char * * args ) -{ - argument_list* arg_list = 0; - - if ( args ) - { - arg_list = args_new(); - lol_build( arg_list->data, args ); - } - - return new_rule_body( root_module(), name, arg_list, - parse_make( f, P0, P0, P0, C0, C0, flags ), 1 ); -} - - -RULE * duplicate_rule( char * name, RULE * other ) -{ - return import_rule( other, root_module(), name ); -} - - -void load_builtins() -{ - duplicate_rule( "Always", - bind_builtin( "ALWAYS", - builtin_flags, T_FLAG_TOUCHED, 0 ) ); - - duplicate_rule( "Depends", - bind_builtin( "DEPENDS", - builtin_depends, 0, 0 ) ); - - duplicate_rule( "echo", - duplicate_rule( "Echo", - bind_builtin( "ECHO", - builtin_echo, 0, 0 ) ) ); - - { - char * args[] = { "message", "*", ":", "result-value", "?", 0 }; - duplicate_rule( "exit", - duplicate_rule( "Exit", - bind_builtin( "EXIT", - builtin_exit, 0, args ) ) ); - } - - { - char * args[] = { "directories", "*", ":", "patterns", "*", ":", "case-insensitive", "?", 0 }; - duplicate_rule( "Glob", - bind_builtin( "GLOB", builtin_glob, 0, args ) ); - } - - { - char * args[] = { "patterns", "*", 0 }; - bind_builtin( "GLOB-RECURSIVELY", - builtin_glob_recursive, 0, args ); - } - - duplicate_rule( "Includes", - bind_builtin( "INCLUDES", - builtin_depends, 1, 0 ) ); - - { - char * args[] = { "targets", "*", ":", "targets-to-rebuild", "*", 0 }; - bind_builtin( "REBUILDS", - builtin_rebuilds, 0, args ); - } - - duplicate_rule( "Leaves", - bind_builtin( "LEAVES", - builtin_flags, T_FLAG_LEAVES, 0 ) ); - - duplicate_rule( "Match", - bind_builtin( "MATCH", - builtin_match, 0, 0 ) ); - - { - char * args[] = { "string", ":", "delimiters" }; - bind_builtin( "SPLIT_BY_CHARACTERS", - builtin_split_by_characters, 0, 0 ); - } - - duplicate_rule( "NoCare", - bind_builtin( "NOCARE", - builtin_flags, T_FLAG_NOCARE, 0 ) ); - - duplicate_rule( "NOTIME", - duplicate_rule( "NotFile", - bind_builtin( "NOTFILE", - builtin_flags, T_FLAG_NOTFILE, 0 ) ) ); - - duplicate_rule( "NoUpdate", - bind_builtin( "NOUPDATE", - builtin_flags, T_FLAG_NOUPDATE, 0 ) ); - - duplicate_rule( "Temporary", - bind_builtin( "TEMPORARY", - builtin_flags, T_FLAG_TEMP, 0 ) ); - - bind_builtin( "ISFILE", - builtin_flags, T_FLAG_ISFILE, 0 ); - - duplicate_rule( "HdrMacro", - bind_builtin( "HDRMACRO", - builtin_hdrmacro, 0, 0 ) ); - - /* FAIL_EXPECTED is used to indicate that the result of a target build - * action should be inverted (ok <=> fail) this can be useful when - * performing test runs from Jamfiles. - */ - bind_builtin( "FAIL_EXPECTED", - builtin_flags, T_FLAG_FAIL_EXPECTED, 0 ); - - bind_builtin( "RMOLD", - builtin_flags, T_FLAG_RMOLD, 0 ); - - { - char * args[] = { "targets", "*", 0 }; - bind_builtin( "UPDATE", - builtin_update, 0, args ); - } - - { - char * args[] = { "targets", "*", - ":", "log", "?", - ":", "ignore-minus-n", "?", - ":", "ignore-minus-q", "?", 0 }; - bind_builtin( "UPDATE_NOW", - builtin_update_now, 0, args ); - } - - { - char * args[] = { "string", "pattern", "replacements", "+", 0 }; - duplicate_rule( "subst", - bind_builtin( "SUBST", - builtin_subst, 0, args ) ); - } - - { - char * args[] = { "module", "?", 0 }; - bind_builtin( "RULENAMES", - builtin_rulenames, 0, args ); - } - - - { - char * args[] = { "module", "?", 0 }; - bind_builtin( "VARNAMES", - builtin_varnames, 0, args ); - } - - { - char * args[] = { "module", "?", 0 }; - bind_builtin( "DELETE_MODULE", - builtin_delete_module, 0, args ); - } - - { - char * args[] = { "source_module", "?", - ":", "source_rules", "*", - ":", "target_module", "?", - ":", "target_rules", "*", - ":", "localize", "?", 0 }; - bind_builtin( "IMPORT", - builtin_import, 0, args ); - } - - { - char * args[] = { "module", "?", ":", "rules", "*", 0 }; - bind_builtin( "EXPORT", - builtin_export, 0, args ); - } - - { - char * args[] = { "levels", "?", 0 }; - bind_builtin( "CALLER_MODULE", - builtin_caller_module, 0, args ); - } - - { - char * args[] = { "levels", "?", 0 }; - bind_builtin( "BACKTRACE", - builtin_backtrace, 0, args ); - } - - { - char * args[] = { 0 }; - bind_builtin( "PWD", - builtin_pwd, 0, args ); - } - - { - char * args[] = { "target", "*", ":", "path", "*", 0 }; - bind_builtin( "SEARCH_FOR_TARGET", - builtin_search_for_target, 0, args ); - } - - { - char * args[] = { "modules_to_import", "+", ":", "target_module", "?", 0 }; - bind_builtin( "IMPORT_MODULE", - builtin_import_module, 0, args ); - } - - { - char * args[] = { "module", "?", 0 }; - bind_builtin( "IMPORTED_MODULES", - builtin_imported_modules, 0, args ); - } - - { - char * args[] = { "instance_module", ":", "class_module", 0 }; - bind_builtin( "INSTANCE", - builtin_instance, 0, args ); - } - - { - char * args[] = { "sequence", "*", 0 }; - bind_builtin( "SORT", - builtin_sort, 0, args ); - } - - { - char * args[] = { "path_parts", "*", 0 }; - bind_builtin( "NORMALIZE_PATH", - builtin_normalize_path, 0, args ); - } - - { - char * args[] = { "args", "*", 0 }; - bind_builtin( "CALC", - builtin_calc, 0, args ); - } - - { - char * args[] = { "module", ":", "rule", 0 }; - bind_builtin( "NATIVE_RULE", - builtin_native_rule, 0, args ); - } - - { - char * args[] = { "module", ":", "rule", ":", "version", 0 }; - bind_builtin( "HAS_NATIVE_RULE", - builtin_has_native_rule, 0, args ); - } - - { - char * args[] = { "module", "*", 0 }; - bind_builtin( "USER_MODULE", - builtin_user_module, 0, args ); - } - - { - char * args[] = { 0 }; - bind_builtin( "NEAREST_USER_LOCATION", - builtin_nearest_user_location, 0, args ); - } - - { - char * args[] = { "file", 0 }; - bind_builtin( "CHECK_IF_FILE", - builtin_check_if_file, 0, args ); - } - -#ifdef HAVE_PYTHON - { - char * args[] = { "python-module", ":", "function", ":", - "jam-module", ":", "rule-name", 0 }; - bind_builtin( "PYTHON_IMPORT_RULE", - builtin_python_import_rule, 0, args ); - } -#endif - -# if defined( OS_NT ) || defined( OS_CYGWIN ) - { - char * args[] = { "key_path", ":", "data", "?", 0 }; - bind_builtin( "W32_GETREG", - builtin_system_registry, 0, args ); - } - - { - char * args[] = { "key_path", ":", "result-type", 0 }; - bind_builtin( "W32_GETREGNAMES", - builtin_system_registry_names, 0, args ); - } -# endif - - { - char * args[] = { "command", ":", "*", 0 }; - duplicate_rule( "SHELL", - bind_builtin( "COMMAND", - builtin_shell, 0, args ) ); - } - - { - char * args[] = { "string", 0 }; - bind_builtin( "MD5", - builtin_md5, 0, args ) ; - } - - { - char * args[] = { "name", ":", "mode", 0 }; - bind_builtin( "FILE_OPEN", - builtin_file_open, 0, args ); - } - - { - char * args[] = { "string", ":", "width", 0 }; - bind_builtin( "PAD", - builtin_pad, 0, args ); - } - - { - char * args[] = { "targets", "*", 0 }; - bind_builtin( "PRECIOUS", - builtin_precious, 0, args ); - } - - { - char * args [] = { 0 }; - bind_builtin( "SELF_PATH", builtin_self_path, 0, args ); - } - - { - char * args [] = { "path", 0 }; - bind_builtin( "MAKEDIR", builtin_makedir, 0, args ); - } - - /* Initialize builtin modules. */ - init_set(); - init_path(); - init_regex(); - init_property_set(); - init_sequence(); - init_order(); -} - - -/* - * builtin_calc() - CALC rule. - * - * The CALC rule performs simple mathematical operations on two arguments. - */ - -LIST * builtin_calc( PARSE * parse, FRAME * frame ) -{ - LIST * arg = lol_get( frame->args, 0 ); - - LIST * result = 0; - long lhs_value; - long rhs_value; - long result_value; - char buffer [ 16 ]; - char const * lhs; - char const * op; - char const * rhs; - - if ( arg == 0 ) return L0; - lhs = arg->string; - - arg = list_next( arg ); - if ( arg == 0 ) return L0; - op = arg->string; - - arg = list_next( arg ); - if ( arg == 0 ) return L0; - rhs = arg->string; - - lhs_value = atoi( lhs ); - rhs_value = atoi( rhs ); - - if ( strcmp( "+", op ) == 0 ) - { - result_value = lhs_value + rhs_value; - } - else if ( strcmp( "-", op ) == 0 ) - { - result_value = lhs_value - rhs_value; - } - else - { - return L0; - } - - sprintf( buffer, "%ld", result_value ); - result = list_new( result, newstr( buffer ) ); - return result; -} - - -/* - * builtin_depends() - DEPENDS/INCLUDES rule. - * - * The DEPENDS/INCLUDES builtin rule appends each of the listed sources on the - * dependency/includes list of each of the listed targets. It binds both the - * targets and sources as TARGETs. - */ - -LIST * builtin_depends( PARSE * parse, FRAME * frame ) -{ - LIST * targets = lol_get( frame->args, 0 ); - LIST * sources = lol_get( frame->args, 1 ); - 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->includes->original_target = t; - } - t = t->includes; - } - - t->depends = targetlist( t->depends, sources ); - } - - /* Enter reverse links */ - for ( l = sources; l; l = list_next( l ) ) - { - TARGET * s = bindtarget( l->string ); - s->dependants = targetlist( s->dependants, targets ); - } - - return L0; -} - - -/* - * builtin_rebuilds() - REBUILDS rule. - * - * The REBUILDS builtin rule appends each of the listed rebuild-targets in its - * 2nd argument on the rebuilds list of each of the listed targets in its first - * argument. - */ - -LIST * builtin_rebuilds( PARSE * parse, FRAME * frame ) -{ - LIST * targets = lol_get( frame->args, 0 ); - LIST * rebuilds = lol_get( frame->args, 1 ); - LIST * l; - - for ( l = targets; l; l = list_next( l ) ) - { - TARGET * t = bindtarget( l->string ); - t->rebuilds = targetlist( t->rebuilds, rebuilds ); - } - - 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, FRAME * frame ) -{ - list_print( lol_get( frame->args, 0 ) ); - printf( "\n" ); - fflush( stdout ); - 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, FRAME * frame ) -{ - list_print( lol_get( frame->args, 0 ) ); - printf( "\n" ); - if ( lol_get( frame->args, 1 ) ) - { - exit( atoi( lol_get( frame->args, 1 )->string ) ); - } - else - { - 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, FRAME * frame ) -{ - LIST * l = lol_get( frame->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; - LIST * case_insensitive; -}; - - -static void downcase_inplace( char * p ) -{ - for ( ; *p; ++p ) - *p = tolower( *p ); -} - - -static void builtin_glob_back -( - void * closure, - char * file, - int status, - time_t time -) -{ - PROFILE_ENTER( BUILTIN_GLOB_BACK ); - - struct globbing * globbing = (struct globbing *)closure; - LIST * l; - PATHNAME f; - string buf[ 1 ]; - - /* Null out directory for matching. We wish we had file_dirscan() pass up a - * PATHNAME. - */ - path_parse( file, &f ); - f.f_dir.len = 0; - - /* For globbing, we unconditionally ignore current and parent directory - * items. Since they items always exist, there is no reason why caller of - * GLOB would want to see them. We could also change file_dirscan(), but - * then paths with embedded "." and ".." would not work anywhere. - */ - if ( !strcmp( f.f_base.ptr, "." ) || !strcmp( f.f_base.ptr, ".." ) ) - { - PROFILE_EXIT( BUILTIN_GLOB_BACK ); - return; - } - - string_new( buf ); - path_build( &f, buf, 0 ); - - if ( globbing->case_insensitive ) - downcase_inplace( buf->value ); - - for ( l = globbing->patterns; l; l = l->next ) - { - if ( !glob( l->string, buf->value ) ) - { - globbing->results = list_new( globbing->results, newstr( file ) ); - break; - } - } - - string_free( buf ); - - PROFILE_EXIT( BUILTIN_GLOB_BACK ); -} - - -static LIST * downcase_list( LIST * in ) -{ - LIST * result = 0; - - string s[ 1 ]; - string_new( s ); - - while ( in ) - { - string_copy( s, in->string ); - downcase_inplace( s->value ); - result = list_append( result, list_new( 0, newstr( s->value ) ) ); - in = in->next; - } - - string_free( s ); - return result; -} - - -LIST * builtin_glob( PARSE * parse, FRAME * frame ) -{ - LIST * l = lol_get( frame->args, 0 ); - LIST * r = lol_get( frame->args, 1 ); - - struct globbing globbing; - - globbing.results = L0; - globbing.patterns = r; - - globbing.case_insensitive -# if defined( OS_NT ) || defined( OS_CYGWIN ) - = l; /* Always case-insensitive if any files can be found. */ -# else - = lol_get( frame->args, 2 ); -# endif - - if ( globbing.case_insensitive ) - globbing.patterns = downcase_list( r ); - - for ( ; l; l = list_next( l ) ) - file_dirscan( l->string, builtin_glob_back, &globbing ); - - if ( globbing.case_insensitive ) - list_free( globbing.patterns ); - - return globbing.results; -} - - -static int has_wildcards( char const * str ) -{ - size_t const index = strcspn( str, "[]*?" ); - return str[ index ] == '\0' ? 0 : 1; -} - - -/* - * If 'file' exists, append 'file' to 'list'. Returns 'list'. - */ - -static LIST * append_if_exists( LIST * list, char * file ) -{ - time_t time; - timestamp( file, &time ); - return time > 0 - ? list_new( list, newstr( file ) ) - : list; -} - - -LIST * glob1( char * dirname, char * pattern ) -{ - LIST * plist = list_new( L0, pattern ); - struct globbing globbing; - - globbing.results = L0; - globbing.patterns = plist; - - globbing.case_insensitive -# if defined( OS_NT ) || defined( OS_CYGWIN ) - = plist; /* always case-insensitive if any files can be found */ -# else - = L0; -# endif - - if ( globbing.case_insensitive ) - globbing.patterns = downcase_list( plist ); - - file_dirscan( dirname, builtin_glob_back, &globbing ); - - if ( globbing.case_insensitive ) - list_free( globbing.patterns ); - - list_free( plist ); - - return globbing.results; -} - - -LIST * glob_recursive( char * pattern ) -{ - LIST * result = L0; - - /* Check if there's metacharacters in pattern */ - if ( !has_wildcards( pattern ) ) - { - /* No metacharacters. Check if the path exists. */ - result = append_if_exists(result, pattern); - } - else - { - /* Have metacharacters in the pattern. Split into dir/name. */ - PATHNAME path[ 1 ]; - path_parse( pattern, path ); - - if ( path->f_dir.ptr ) - { - LIST * dirs = L0; - string dirname[ 1 ]; - string basename[ 1 ]; - string_new( dirname ); - string_new( basename ); - - string_append_range( dirname, path->f_dir.ptr, - path->f_dir.ptr + path->f_dir.len ); - - path->f_grist.ptr = 0; - path->f_grist.len = 0; - path->f_dir.ptr = 0; - path->f_dir.len = 0; - path_build( path, basename, 0 ); - - dirs = has_wildcards( dirname->value ) - ? glob_recursive( dirname->value ) - : list_new( dirs, dirname->value ); - - if ( has_wildcards( basename->value ) ) - { - for ( ; dirs; dirs = dirs->next ) - result = list_append( result, glob1( dirs->string, - basename->value ) ); - } - else - { - string file_string[ 1 ]; - string_new( file_string ); - - /* No wildcard in basename. */ - for ( ; dirs; dirs = dirs->next ) - { - path->f_dir.ptr = dirs->string; - path->f_dir.len = strlen( dirs->string ); - path_build( path, file_string, 0 ); - - result = append_if_exists( result, file_string->value ); - - string_truncate( file_string, 0 ); - } - - string_free( file_string ); - } - - string_free( dirname ); - string_free( basename ); - } - else - { - /** No directory, just a pattern. */ - result = list_append( result, glob1( ".", pattern ) ); - } - } - - return result; -} - - -LIST * builtin_glob_recursive( PARSE * parse, FRAME * frame ) -{ - LIST * result = L0; - LIST * l = lol_get( frame->args, 0 ); - for ( ; l; l = l->next ) - result = list_append( result, glob_recursive( l->string ) ); - return result; -} - - -/* - * builtin_match() - MATCH rule, regexp matching. - */ - -LIST * builtin_match( PARSE * parse, FRAME * frame ) -{ - LIST * l; - LIST * r; - LIST * result = 0; - - string buf[ 1 ]; - string_new( buf ); - - /* For each pattern */ - - for ( l = lol_get( frame->args, 0 ); l; l = l->next ) - { - /* Result is cached and intentionally never freed. */ - regexp * re = regex_compile( l->string ); - - /* For each string to match against. */ - for ( r = lol_get( frame->args, 1 ); r; r = r->next ) - { - if ( regexec( re, r->string ) ) - { - int i; - int 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 ) - { - string_append_range( buf, re->startp[ i ], re->endp[ i ] ); - result = list_new( result, newstr( buf->value ) ); - string_truncate( buf, 0 ); - } - } - } - } - - string_free( buf ); - return result; -} - -LIST * builtin_split_by_characters( PARSE * parse, FRAME * frame ) -{ - LIST * l1 = lol_get( frame->args, 0 ); - LIST * l2 = lol_get( frame->args, 1 ); - - LIST * result = 0; - - char* s = strdup (l1->string); - char* delimiters = l2->string; - char* t; - - t = strtok (s, delimiters); - while (t) - { - result = list_new(result, newstr(t)); - t = strtok (NULL, delimiters); - } - - free (s); - - return result; -} - -LIST * builtin_hdrmacro( PARSE * parse, FRAME * frame ) -{ - LIST * l = lol_get( frame->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; -} - - -/* - * builtin_rulenames() - RULENAMES ( MODULE ? ). - * - * Returns a list of the non-local rule names in the given MODULE. If MODULE is - * not supplied, returns the list of rule names in the global module. - */ - -static void add_rule_name( void * r_, void * result_ ) -{ - RULE * r = (RULE *)r_; - LIST * * result = (LIST * *)result_; - if ( r->exported ) - *result = list_new( *result, copystr( r->name ) ); -} - - -LIST * builtin_rulenames( PARSE * parse, FRAME * frame ) -{ - LIST * arg0 = lol_get( frame->args, 0 ); - LIST * result = L0; - module_t * source_module = bindmodule( arg0 ? arg0->string : 0 ); - - if ( source_module->rules ) - hashenumerate( source_module->rules, add_rule_name, &result ); - return result; -} - - -/* - * builtin_varnames() - VARNAMES ( MODULE ? ). - * - * Returns a list of the variable names in the given MODULE. If MODULE is not - * supplied, returns the list of variable names in the global module. - */ - -/* helper function for builtin_varnames(), below. Used with hashenumerate, will - * prepend the key of each element to the list - */ -static void add_hash_key( void * np, void * result_ ) -{ - LIST * * result = (LIST * *)result_; - *result = list_new( *result, copystr( *(char * *)np ) ); -} - - -static struct hash * get_running_module_vars() -{ - struct hash * dummy; - struct hash * vars = NULL; - /* Get the global variables pointer (that of the currently running module). - */ - var_hash_swap( &vars ); - dummy = vars; - /* Put the global variables pointer in its right place. */ - var_hash_swap( &dummy ); - return vars; -} - - -LIST * builtin_varnames( PARSE * parse, FRAME * frame ) -{ - LIST * arg0 = lol_get( frame->args, 0 ); - LIST * result = L0; - module_t * source_module = bindmodule( arg0 ? arg0->string : 0 ); - - /* The running module _always_ has its 'variables' member set to NULL due to - * the way enter_module() and var_hash_swap() work. - */ - struct hash * vars = source_module == frame->module - ? get_running_module_vars() - : source_module->variables; - - if ( vars ) - hashenumerate( vars, add_hash_key, &result ); - return result; -} - - -/* - * builtin_delete_module() - MODULE ?. - * - * Clears all rules and variables from the given module. - */ - -LIST * builtin_delete_module( PARSE * parse, FRAME * frame ) -{ - LIST * arg0 = lol_get( frame->args, 0 ); - LIST * result = L0; - module_t * source_module = bindmodule( arg0 ? arg0->string : 0 ); - delete_module( source_module ); - return result; -} - - -static void unknown_rule( FRAME * frame, char * key, char * module_name, char * rule_name ) -{ - backtrace_line( frame->prev ); - printf( "%s error: rule \"%s\" unknown in module \"%s\"\n", key, rule_name, module_name ); - backtrace( frame->prev ); - exit( 1 ); -} - - -/* - * builtin_import() - IMPORT - * ( - * SOURCE_MODULE ? : - * SOURCE_RULES * : - * TARGET_MODULE ? : - * TARGET_RULES * : - * LOCALIZE ? - * ) - * - * The IMPORT rule imports rules from the SOURCE_MODULE into the TARGET_MODULE - * as local rules. If either SOURCE_MODULE or TARGET_MODULE is not supplied, it - * refers to the global module. SOURCE_RULES specifies which rules from the - * SOURCE_MODULE to import; TARGET_RULES specifies the names to give those rules - * in TARGET_MODULE. If SOURCE_RULES contains a name which doesn't correspond to - * a rule in SOURCE_MODULE, or if it contains a different number of items than - * TARGET_RULES, an error is issued. If LOCALIZE is specified, the rules will be - * executed in TARGET_MODULE, with corresponding access to its module local - * variables. - */ - -LIST * builtin_import( PARSE * parse, FRAME * frame ) -{ - LIST * source_module_list = lol_get( frame->args, 0 ); - LIST * source_rules = lol_get( frame->args, 1 ); - LIST * target_module_list = lol_get( frame->args, 2 ); - LIST * target_rules = lol_get( frame->args, 3 ); - LIST * localize = lol_get( frame->args, 4 ); - - module_t * target_module = - bindmodule( target_module_list ? target_module_list->string : 0 ); - module_t * source_module = - bindmodule( source_module_list ? source_module_list->string : 0 ); - - LIST * source_name; - LIST * target_name; - - for ( source_name = source_rules, target_name = target_rules; - source_name && target_name; - source_name = list_next( source_name ), - target_name = list_next( target_name ) ) - { - RULE r_; - RULE * r = &r_; - RULE * imported; - r_.name = source_name->string; - - if ( !source_module->rules || - !hashcheck( source_module->rules, (HASHDATA * *)&r ) ) - unknown_rule( frame, "IMPORT", source_module->name, r_.name ); - - imported = import_rule( r, target_module, target_name->string ); - if ( localize ) - imported->module = target_module; - /* This rule is really part of some other module. Just refer to it here, - * but do not let it out. - */ - imported->exported = 0; - } - - if ( source_name || target_name ) - { - backtrace_line( frame->prev ); - printf( "import error: length of source and target rule name lists don't match!\n" ); - printf( " source: " ); - list_print( source_rules ); - printf( "\n target: " ); - list_print( target_rules ); - printf( "\n" ); - backtrace( frame->prev ); - exit( 1 ); - } - - return L0; -} - - -/* - * builtin_export() - EXPORT ( MODULE ? : RULES * ). - * - * The EXPORT rule marks RULES from the SOURCE_MODULE as non-local (and thus - * exportable). If an element of RULES does not name a rule in MODULE, an error - * is issued. - */ - -LIST * builtin_export( PARSE * parse, FRAME * frame ) -{ - LIST * module_list = lol_get( frame->args, 0 ); - LIST * rules = lol_get( frame->args, 1 ); - module_t * m = bindmodule( module_list ? module_list->string : 0 ); - - for ( ; rules; rules = list_next( rules ) ) - { - RULE r_; - RULE * r = &r_; - r_.name = rules->string; - - if ( !m->rules || !hashcheck( m->rules, (HASHDATA * *)&r ) ) - unknown_rule( frame, "EXPORT", m->name, r_.name ); - - r->exported = 1; - } - return L0; -} - - -/* - * get_source_line() - Retrieve the file and line number that should be - * indicated for a given procedure in debug output or an error backtrace. - */ - -static void get_source_line( PARSE * procedure, char * * file, int * line ) -{ - if ( procedure ) - { - char * f = procedure->file; - int l = procedure->line; - if ( !strcmp( f, "+" ) ) - { - f = "jambase.c"; - l += 3; - } - *file = f; - *line = l; - } - else - { - *file = "(builtin)"; - *line = -1; - } -} - - -void print_source_line( PARSE * p ) -{ - char * file; - int line; - - get_source_line( p, &file, &line ); - if ( line < 0 ) - printf( "(builtin):" ); - else - printf( "%s:%d:", file, line ); -} - - -/* - * backtrace_line() - print a single line of error backtrace for the given - * frame. - */ - -void backtrace_line( FRAME * frame ) -{ - if ( frame == 0 ) - { - printf( "(no frame):" ); - } - else - { - print_source_line( frame->procedure ); - printf( " in %s\n", frame->rulename ); - } -} - - -/* - * backtrace() - Print the entire backtrace from the given frame to the Jambase - * which invoked it. - */ - -void backtrace( FRAME * frame ) -{ - if ( !frame ) return; - while ( ( frame = frame->prev ) ) - backtrace_line( frame ); -} - - -/* - * builtin_backtrace() - A Jam version of the backtrace function, taking no - * arguments and returning a list of quadruples: FILENAME LINE MODULE. RULENAME - * describing each frame. Note that the module-name is always followed by a - * period. - */ - -LIST * builtin_backtrace( PARSE * parse, FRAME * frame ) -{ - LIST * levels_arg = lol_get( frame->args, 0 ); - int levels = levels_arg ? atoi( levels_arg->string ) : ( (unsigned int)(-1) >> 1 ) ; - - LIST * result = L0; - for ( ; ( frame = frame->prev ) && levels ; --levels ) - { - char * file; - int line; - char buf[32]; - get_source_line( frame->procedure, &file, &line ); - sprintf( buf, "%d", line ); - result = list_new( result, newstr( file ) ); - result = list_new( result, newstr( buf ) ); - result = list_new( result, newstr( frame->module->name ) ); - result = list_new( result, newstr( frame->rulename ) ); - } - return result; -} - - -/* - * builtin_caller_module() - CALLER_MODULE ( levels ? ) - * - * If levels is not supplied, returns the name of the module of the rule which - * called the one calling this one. If levels is supplied, it is interpreted as - * an integer specifying a number of additional levels of call stack to traverse - * in order to locate the module in question. If no such module exists, returns - * the empty list. Also returns the empty list when the module in question is - * the global module. This rule is needed for implementing module import - * behavior. - */ - -LIST * builtin_caller_module( PARSE * parse, FRAME * frame ) -{ - LIST * levels_arg = lol_get( frame->args, 0 ); - int levels = levels_arg ? atoi( levels_arg->string ) : 0 ; - - int i; - for ( i = 0; ( i < levels + 2 ) && frame->prev; ++i ) - frame = frame->prev; - - if ( frame->module == root_module() ) - return L0; - - { - LIST * result; - string name; - string_copy( &name, frame->module->name ); - string_pop_back( &name ); - result = list_new( L0, newstr(name.value) ); - string_free( &name ); - return result; - } -} - - -/* - * Return the current working directory. - * - * Usage: pwd = [ PWD ] ; - */ - -LIST * builtin_pwd( PARSE * parse, FRAME * frame ) -{ - return pwd(); -} - - -/* - * Adds targets to the list of target that jam will attempt to update. - */ - -LIST * builtin_update( PARSE * parse, FRAME * frame ) -{ - LIST * result = list_copy( L0, targets_to_update() ); - LIST * arg1 = lol_get( frame->args, 0 ); - clear_targets_to_update(); - for ( ; arg1; arg1 = list_next( arg1 ) ) - mark_target_for_updating( newstr( arg1->string ) ); - return result; -} - -extern int anyhow; -int last_update_now_status; - -/* Takes a list of target names as first argument, and immediately - updates them. - Second parameter, if specified, if the descriptor (converted to a string) - of a log file where all build output is redirected. - Third parameter, if non-empty, specifies that the -n option should have - no effect -- that is, all out-of-date targets should be rebuild. -*/ -LIST * builtin_update_now( PARSE * parse, FRAME * frame ) -{ - LIST * targets = lol_get( frame->args, 0 ); - LIST * log = lol_get( frame->args, 1 ); - LIST * force = lol_get (frame->args, 2); - LIST * continue_ = lol_get(frame->args, 3); - int status = 0; - int original_stdout; - int original_stderr; - int n; - int targets_count; - const char** targets2; - int i; - int original_noexec; - int original_quitquick; - - - if (log) - { - int fd = atoi(log->string); - /* Redirect stdout and stderr, temporary, to the log file. */ - original_stdout = dup (0); - original_stderr = dup (1); - dup2 (fd, 0); - dup2 (fd, 1); - } - - if (force) - { - original_noexec = globs.noexec; - globs.noexec = 0; - original_quitquick = globs.quitquick; - globs.quitquick = 0; - } - - if (continue_) - { - original_quitquick = globs.quitquick; - globs.quitquick = 0; - } - - targets_count = list_length( targets ); - targets2 = (const char * *)BJAM_MALLOC( targets_count * sizeof( char * ) ); - for (i = 0 ; targets; targets = list_next( targets ) ) - targets2[ i++ ] = targets->string; - status |= make( targets_count, targets2, anyhow); - free( targets ); - - if (force) - { - globs.noexec = original_noexec; - globs.quitquick = original_quitquick; - } - - if (continue_) - { - globs.quitquick = original_quitquick; - } - - if (log) - { - /* Flush whatever stdio might have buffered, while descriptions - 0 and 1 still refer to the log file. */ - fflush (stdout); - fflush (stderr); - dup2 (original_stdout, 0); - dup2 (original_stderr, 1); - close (original_stdout); - close (original_stderr); - } - - last_update_now_status = status; - - if (status == 0) - return list_new (L0, newstr ("ok")); - else - return L0; -} - -LIST * builtin_search_for_target( PARSE * parse, FRAME * frame ) -{ - LIST * arg1 = lol_get( frame->args, 0 ); - LIST * arg2 = lol_get( frame->args, 1 ); - TARGET * t = search_for_target( arg1->string, arg2 ); - return list_new( L0, t->name ); -} - - -LIST * builtin_import_module( PARSE * parse, FRAME * frame ) -{ - LIST * arg1 = lol_get( frame->args, 0 ); - LIST * arg2 = lol_get( frame->args, 1 ); - module_t * m = arg2 ? bindmodule( arg2->string ) : root_module(); - import_module( arg1, m ); - return L0; -} - - -LIST * builtin_imported_modules( PARSE * parse, FRAME * frame ) -{ - LIST * arg0 = lol_get( frame->args, 0 ); - return imported_modules( bindmodule( arg0 ? arg0->string : 0 ) ); -} - - -LIST * builtin_instance( PARSE * parse, FRAME * frame ) -{ - LIST * arg1 = lol_get( frame->args, 0 ); - LIST * arg2 = lol_get( frame->args, 1 ); - module_t * const instance = bindmodule( arg1->string ); - module_t * const class_module = bindmodule( arg2->string ); - instance->class_module = class_module; - return L0; -} - - -LIST * builtin_sort( PARSE * parse, FRAME * frame ) -{ - LIST * arg1 = lol_get( frame->args, 0 ); - return list_sort( arg1 ); -} - - -LIST * builtin_normalize_path( PARSE * parse, FRAME * frame ) -{ - LIST * arg = lol_get( frame->args, 0 ); - - /* First, we iterate over all '/'-separated elements, starting from the end - * of string. If we see a '..', we remove a previous path elements. If we - * see '.', we remove it. The removal is done by overwriting data using '\1' - * in the string. After the whole string has been processed, we do a second - * pass, removing all the entered '\1' characters. - */ - - string in[ 1 ]; - string out[ 1 ]; - /* Last character of the part of string still to be processed. */ - char * end; - /* Working pointer. */ - char * current; - /* Number of '..' elements seen and not processed yet. */ - int dotdots = 0; - int rooted = 0; - char * result = 0; - - /* Make a copy of input: we should not change it. Prepend a '/' before it as - * a guard for the algorithm later on and remember whether it was originally - * rooted or not. - */ - string_new( in ); - string_push_back( in, '/' ); - for ( ; arg; arg = list_next( arg ) ) - { - if ( arg->string[ 0 ] != '\0' ) - { - if ( in->size == 1 ) - rooted = ( ( arg->string[ 0 ] == '/' ) || - ( arg->string[ 0 ] == '\\' ) ); - else - string_append( in, "/" ); - string_append( in, arg->string ); - } - } - - /* Convert \ into /. On Windows, paths using / and \ are equivalent, and we - * want this function to obtain a canonic representation. - */ - for ( current = in->value, end = in->value + in->size; - current < end; ++current ) - if ( *current == '\\' ) - *current = '/'; - - /* Now we remove any extra path elements by overwriting them with '\1' - * characters and cound how many more unused '..' path elements there are - * remaining. Note that each remaining path element with always starts with - * a '/' character. - */ - for ( end = in->value + in->size - 1; end >= in->value; ) - { - /* Set 'current' to the next occurence of '/', which always exists. */ - for ( current = end; *current != '/'; --current ); - - if ( current == end ) - { - /* Found a trailing or duplicate '/'. Remove it. */ - *current = '\1'; - } - else if ( ( end - current == 1 ) && ( *(current + 1) == '.' ) ) - { - /* Found '/.'. Remove them all. */ - *current = '\1'; - *(current + 1) = '\1'; - } - else if ( ( end - current == 2 ) && ( *(current + 1) == '.' ) && ( *(current + 2) == '.' ) ) - { - /* Found '/..'. Remove them all. */ - *current = '\1'; - *(current + 1) = '\1'; - *(current + 2) = '\1'; - ++dotdots; - } - else if ( dotdots ) - { - memset( current, '\1', end - current + 1 ); - --dotdots; - } - end = current - 1; - } - - string_new( out ); - - /* Now we know that we need to add exactly dotdots '..' path elements to the - * front and that our string is either empty or has a '/' as its first - * significant character. If we have any dotdots remaining then the passed - * path must not have been rooted or else it is invalid we return an empty - * list. - */ - if ( dotdots ) - { - if ( rooted ) return L0; - do - string_append( out, "/.." ); - while ( --dotdots ); - } - - /* Now we actually remove all the path characters marked for removal. */ - for ( current = in->value; *current; ++current ) - if ( *current != '\1' ) - string_push_back( out, *current ); - - /* Here we know that our string contains no '\1' characters and is either - * empty or has a '/' as its initial character. If the original path was not - * rooted and we have a non-empty path we need to drop the initial '/'. If - * the original path was rooted and we have an empty path we need to add - * back the '/'. - */ - result = newstr( out->size ? out->value + !rooted : ( rooted ? "/" : "." ) ); - - string_free( out ); - string_free( in ); - - return list_new( 0, result ); -} - - -LIST * builtin_native_rule( PARSE * parse, FRAME * frame ) -{ - LIST * module_name = lol_get( frame->args, 0 ); - LIST * rule_name = lol_get( frame->args, 1 ); - - module_t * module = bindmodule( module_name->string ); - - native_rule_t n; - native_rule_t * np = &n; - n.name = rule_name->string; - if ( module->native_rules && hashcheck( module->native_rules, (HASHDATA * *)&np ) ) - { - new_rule_body( module, np->name, np->arguments, np->procedure, 1 ); - } - else - { - backtrace_line( frame->prev ); - printf( "error: no native rule \"%s\" defined in module \"%s\"\n", - n.name, module->name ); - backtrace( frame->prev ); - exit( 1 ); - } - return L0; -} - - -LIST * builtin_has_native_rule( PARSE * parse, FRAME * frame ) -{ - LIST * module_name = lol_get( frame->args, 0 ); - LIST * rule_name = lol_get( frame->args, 1 ); - LIST * version = lol_get( frame->args, 2 ); - - module_t * module = bindmodule( module_name->string ); - - native_rule_t n; - native_rule_t * np = &n; - n.name = rule_name->string; - if ( module->native_rules && hashcheck( module->native_rules, (HASHDATA * *)&np ) ) - { - int expected_version = atoi( version->string ); - if ( np->version == expected_version ) - return list_new( 0, newstr( "true" ) ); - } - return L0; -} - - -LIST * builtin_user_module( PARSE * parse, FRAME * frame ) -{ - LIST * module_name = lol_get( frame->args, 0 ); - for ( ; module_name; module_name = module_name->next ) - { - module_t * m = bindmodule( module_name->string ); - m->user_module = 1; - } - return L0; -} - - -LIST * builtin_nearest_user_location( PARSE * parse, FRAME * frame ) -{ - FRAME * nearest_user_frame = - frame->module->user_module ? frame : frame->prev_user; - if ( !nearest_user_frame ) - return L0; - - { - LIST * result = 0; - char * file; - int line; - char buf[32]; - - get_source_line( nearest_user_frame->procedure, &file, &line ); - sprintf( buf, "%d", line ); - result = list_new( result, newstr( file ) ); - result = list_new( result, newstr( buf ) ); - return result; - } -} - - -LIST * builtin_check_if_file( PARSE * parse, FRAME * frame ) -{ - LIST * name = lol_get( frame->args, 0 ); - return file_is_file( name->string ) == 1 - ? list_new( 0, newstr( "true" ) ) - : L0 ; -} - - -LIST * builtin_md5( PARSE * parse, FRAME * frame ) -{ - LIST * l = lol_get( frame->args, 0 ); - char* s = l->string; - - md5_state_t state; - md5_byte_t digest[16]; - char hex_output[16*2 + 1]; - - int di; - - md5_init(&state); - md5_append(&state, (const md5_byte_t *)s, strlen(s)); - md5_finish(&state, digest); - - for (di = 0; di < 16; ++di) - sprintf(hex_output + di * 2, "%02x", digest[di]); - - return list_new (0, newstr(hex_output)); -} - -LIST *builtin_file_open( PARSE *parse, FRAME *frame ) -{ - char* name = lol_get(frame->args, 0)->string; - char* mode = lol_get(frame->args, 1)->string; - int fd; - char buffer[sizeof("4294967295")]; - - if (strcmp(mode, "w") == 0) - { - fd = open(name, O_WRONLY|O_CREAT|O_TRUNC, 0666); - } - else - { - fd = open(name, O_RDONLY); - } - - if (fd != -1) - { - sprintf(buffer, "%d", fd); - return list_new(L0, newstr(buffer)); - } - else - { - return L0; - } -} - -LIST *builtin_pad( PARSE *parse, FRAME *frame ) -{ - char *string = lol_get(frame->args, 0)->string; - char *width_s = lol_get(frame->args, 1)->string; - - int current = strlen (string); - int desired = atoi(width_s); - if (current >= desired) - return list_new (L0, string); - else - { - char *buffer = malloc (desired + 1); - int i; - LIST *result; - - strcpy (buffer, string); - for (i = current; i < desired; ++i) - buffer[i] = ' '; - buffer[desired] = '\0'; - result = list_new (L0, newstr (buffer)); - free (buffer); - return result; - } -} - -LIST *builtin_precious( PARSE *parse, FRAME *frame ) -{ - LIST* targets = lol_get(frame->args, 0); - - for ( ; targets; targets = list_next( targets ) ) - { - TARGET* t = bindtarget (targets->string); - t->flags |= T_FLAG_PRECIOUS; - } - - return L0; -} - -LIST *builtin_self_path( PARSE *parse, FRAME *frame ) -{ - extern char *saved_argv0; - char *p = executable_path (saved_argv0); - if (p) - { - LIST* result = list_new (0, newstr (p)); - free(p); - return result; - } - else - { - return L0; - } -} - -LIST *builtin_makedir( PARSE *parse, FRAME *frame ) -{ - LIST *path = lol_get(frame->args, 0); - - if (file_mkdir(path->string) == 0) - { - LIST *result = list_new (0, newstr(path->string)); - return result; - } - else - { - return L0; - } -} - -#ifdef HAVE_PYTHON - -LIST * builtin_python_import_rule( PARSE * parse, FRAME * frame ) -{ - static int first_time = 1; - char * python_module = lol_get( frame->args, 0 )->string; - char * python_function = lol_get( frame->args, 1 )->string; - char * jam_module = lol_get( frame->args, 2 )->string; - char * jam_rule = lol_get( frame->args, 3 )->string; - - PyObject * pName; - PyObject * pModule; - PyObject * pDict; - PyObject * pFunc; - - if ( first_time ) - { - /* At the first invocation, we add the value of the global - * EXTRA_PYTHONPATH to the sys.path Python variable. - */ - LIST * extra = 0; - module_t * outer_module = frame->module; - - first_time = 0; - - if ( outer_module != root_module() ) - { - exit_module( outer_module ); - enter_module( root_module() ); - } - - extra = var_get( "EXTRA_PYTHONPATH" ); - - if ( outer_module != root_module() ) - { - exit_module( root_module() ); - enter_module( outer_module ); - } - - for ( ; extra; extra = extra->next ) - { - string buf[ 1 ]; - string_new( buf ); - string_append( buf, "import sys\nsys.path.append(\"" ); - string_append( buf, extra->string ); - string_append( buf, "\")\n" ); - PyRun_SimpleString( buf->value ); - string_free( buf ); - } - } - - pName = PyString_FromString( python_module ); - pModule = PyImport_Import( pName ); - Py_DECREF( pName ); - - if ( pModule != NULL ) - { - pDict = PyModule_GetDict( pModule ); - pFunc = PyDict_GetItemString( pDict, python_function ); - - if ( pFunc && PyCallable_Check( pFunc ) ) - { - module_t * m = bindmodule( jam_module ); - RULE * r = bindrule( jam_rule, m ); - - /* Make pFunc owned. */ - Py_INCREF( pFunc ); - - r->python_function = pFunc; - } - else - { - if ( PyErr_Occurred() ) - PyErr_Print(); - fprintf( stderr, "Cannot find function \"%s\"\n", python_function ); - } - Py_DECREF( pModule ); - } - else - { - PyErr_Print(); - fprintf( stderr, "Failed to load \"%s\"\n", python_module ); - } - return L0; - -} - -#endif - -void lol_build( LOL * lol, char * * elements ) -{ - LIST * l = L0; - lol_init( lol ); - - while ( elements && *elements ) - { - if ( !strcmp( *elements, ":" ) ) - { - lol_add( lol, l ); - l = L0 ; - } - else - { - l = list_new( l, newstr( *elements ) ); - } - ++elements; - } - - if ( l != L0 ) - lol_add( lol, l ); -} - - -#ifdef HAVE_PYTHON - -/* - * Calls the bjam rule specified by name passed in 'args'. The name is looked up - * in the context of bjam's 'python_interface' module. Returns the list of - * string retured by the rule. - */ - -PyObject* bjam_call( PyObject * self, PyObject * args ) -{ - FRAME inner[ 1 ]; - LIST * result; - PARSE * p; - char * rulename; - - /* Build up the list of arg lists. */ - frame_init( inner ); - inner->prev = 0; - inner->prev_user = 0; - inner->module = bindmodule( "python_interface" ); - inner->procedure = 0; - - /* Extract the rule name and arguments from 'args'. */ - - /* PyTuple_GetItem returns borrowed reference. */ - rulename = PyString_AsString( PyTuple_GetItem( args, 0 ) ); - { - int i = 1; - int size = PyTuple_Size( args ); - for ( ; i < size; ++i ) - { - PyObject * a = PyTuple_GetItem( args, i ); - if ( PyString_Check( a ) ) - { - lol_add( inner->args, list_new( 0, newstr( - PyString_AsString( a ) ) ) ); - } - else if ( PySequence_Check( a ) ) - { - LIST * l = 0; - int s = PySequence_Size( a ); - int i = 0; - for ( ; i < s; ++i ) - { - /* PySequence_GetItem returns new reference. */ - PyObject * e = PySequence_GetItem( a, i ); - char * s = PyString_AsString( e ); - if ( !s ) - { - printf( "Invalid parameter type passed from Python\n" ); - exit( 1 ); - } - l = list_new( l, newstr( s ) ); - Py_DECREF( e ); - } - lol_add( inner->args, l ); - } - } - } - - result = evaluate_rule( rulename, inner ); - - frame_free( inner ); - - /* Convert the bjam list into a Python list result. */ - { - PyObject * pyResult = PyList_New( list_length( result ) ); - int i = 0; - while ( result ) - { - PyList_SetItem( pyResult, i, PyString_FromString( result->string ) ); - result = list_next( result ); - i += 1; - } - list_free( result ); - return pyResult; - } -} - - -/* - * Accepts four arguments: - * - module name - * - rule name, - * - Python callable. - * - (optional) bjam language function signature. - * Creates a bjam rule with the specified name in the specified module, which will - * invoke the Python callable. - */ - -PyObject * bjam_import_rule( PyObject * self, PyObject * args ) -{ - char * module; - char * rule; - PyObject * func; - PyObject * bjam_signature = NULL; - module_t * m; - RULE * r; - - if ( !PyArg_ParseTuple( args, "ssO|O:import_rule", - &module, &rule, &func, &bjam_signature ) ) - return NULL; - - if ( !PyCallable_Check( func ) ) - { - PyErr_SetString( PyExc_RuntimeError, - "Non-callable object passed to bjam.import_rule" ); - return NULL; - } - - m = bindmodule( *module ? module : 0 ); - r = bindrule( rule, m ); - - /* Make pFunc owned. */ - Py_INCREF( func ); - - r->python_function = func; - r->arguments = 0; - - if (bjam_signature) - { - argument_list * arg_list = args_new(); - Py_ssize_t i; - - Py_ssize_t s = PySequence_Size (bjam_signature); - for (i = 0; i < s; ++i) - { - PyObject* v = PySequence_GetItem (bjam_signature, i); - lol_add(arg_list->data, list_from_python (v)); - Py_DECREF(v); - } - r->arguments = arg_list; - } - - Py_INCREF( Py_None ); - return Py_None; -} - - -/* - * Accepts four arguments: - * - an action name - * - an action body - * - a list of variable that will be bound inside the action - * - integer flags. - * Defines an action on bjam side. - */ - -PyObject * bjam_define_action( PyObject * self, PyObject * args ) -{ - char * name; - char * body; - module_t * m; - PyObject * bindlist_python; - int flags; - LIST * bindlist = L0; - int n; - int i; - - if ( !PyArg_ParseTuple( args, "ssO!i:define_action", &name, &body, - &PyList_Type, &bindlist_python, &flags ) ) - return NULL; - - n = PyList_Size( bindlist_python ); - for ( i = 0; i < n; ++i ) - { - PyObject * next = PyList_GetItem( bindlist_python, i ); - if ( !PyString_Check( next ) ) - { - PyErr_SetString( PyExc_RuntimeError, - "bind list has non-string type" ); - return NULL; - } - bindlist = list_new( bindlist, PyString_AsString( next ) ); - } - - new_rule_actions( root_module(), name, newstr( body ), bindlist, flags ); - - Py_INCREF( Py_None ); - return Py_None; -} - - -/* - * Returns the value of a variable in root Jam module. - */ - -PyObject * bjam_variable( PyObject * self, PyObject * args ) -{ - char * name; - LIST * value; - PyObject * result; - int i; - - if ( !PyArg_ParseTuple( args, "s", &name ) ) - return NULL; - - enter_module( root_module() ); - value = var_get( name ); - exit_module( root_module() ); - - result = PyList_New( list_length( value ) ); - for ( i = 0; value; value = list_next( value ), ++i ) - PyList_SetItem( result, i, PyString_FromString( value->string ) ); - - return result; -} - - -PyObject * bjam_backtrace( PyObject * self, PyObject * args ) -{ - PyObject * result = PyList_New( 0 ); - struct frame * f = frame_before_python_call; - - for ( ; f = f->prev; ) - { - PyObject * tuple = PyTuple_New( 4 ); - char * file; - int line; - char buf[ 32 ]; - - get_source_line( f->procedure, &file, &line ); - sprintf( buf, "%d", line ); - - /* PyTuple_SetItem steals reference. */ - PyTuple_SetItem( tuple, 0, PyString_FromString( file ) ); - PyTuple_SetItem( tuple, 1, PyString_FromString( buf ) ); - PyTuple_SetItem( tuple, 2, PyString_FromString( f->module->name ) ); - PyTuple_SetItem( tuple, 3, PyString_FromString( f->rulename ) ); - - PyList_Append( result, tuple ); - Py_DECREF( tuple ); - } - return result; -} - -PyObject * bjam_caller( PyObject * self, PyObject * args ) -{ - PyObject *result = PyString_FromString( - frame_before_python_call->prev->module->name); - return result; -} - -#endif /* #ifdef HAVE_PYTHON */ - - -#ifdef HAVE_POPEN - -#if defined(_MSC_VER) || defined(__BORLANDC__) - #define popen windows_popen_wrapper - #define pclose _pclose - - /* - * This wrapper is a workaround for a funny _popen() feature on Windows - * where it eats external quotes in some cases. The bug seems to be related - * to the quote stripping functionality used by the Windows cmd.exe - * interpreter when its /S is not specified. - * - * Cleaned up quote from the cmd.exe help screen as displayed on Windows XP - * SP3: - * - * 1. If all of the following conditions are met, then quote characters on - * the command line are preserved: - * - * - no /S switch - * - exactly two quote characters - * - no special characters between the two quote characters, where - * special is one of: &<>()@^| - * - there are one or more whitespace characters between the two quote - * characters - * - the string between the two quote characters is the name of an - * executable file. - * - * 2. Otherwise, old behavior is to see if the first character is a quote - * character and if so, strip the leading character and remove the last - * quote character on the command line, preserving any text after the - * last quote character. - * - * This causes some commands containing quotes not to be executed correctly. - * For example: - * - * "\Long folder name\aaa.exe" --name="Jurko" --no-surname - * - * would get its outermost quotes stripped and would be executed as: - * - * \Long folder name\aaa.exe" --name="Jurko --no-surname - * - * which would report an error about '\Long' not being a valid command. - * - * cmd.exe help seems to indicate it would be enough to add an extra space - * character in front of the command to avoid this but this does not work, - * most likely due to the shell first stripping all leading whitespace - * characters from the command. - * - * Solution implemented here is to quote the whole command in case it - * contains any quote characters. Note thought this will not work correctly - * should Windows ever 'fix' this feature. - * (03.06.2008.) (Jurko) - */ - static FILE * windows_popen_wrapper( char * command, char * mode ) - { - int extra_command_quotes_needed = ( strchr( command, '"' ) != 0 ); - string quoted_command; - FILE * result; - - if ( extra_command_quotes_needed ) - { - string_new( "ed_command ); - string_append( "ed_command, "\"" ); - string_append( "ed_command, command ); - string_append( "ed_command, "\"" ); - command = quoted_command.value; - } - - result = _popen( command, "r" ); - - if ( extra_command_quotes_needed ) - string_free( "ed_command ); - - return result; - } -#endif - - -static char * rtrim(char *s) -{ - char *p = s; - while(*p) ++p; - for(--p; p >= s && isspace(*p); *p-- = 0); - return s; -} - -LIST * builtin_shell( PARSE * parse, FRAME * frame ) -{ - LIST * command = lol_get( frame->args, 0 ); - LIST * result = 0; - string s; - int ret; - char buffer[ 1024 ]; - FILE * p = NULL; - int exit_status = -1; - int exit_status_opt = 0; - int no_output_opt = 0; - int strip_eol_opt = 0; - - /* Process the variable args options. */ - { - int a = 1; - LIST * arg = lol_get( frame->args, a ); - while ( arg ) - { - if ( strcmp( "exit-status", arg->string ) == 0 ) - { - exit_status_opt = 1; - } - else if ( strcmp( "no-output", arg->string ) == 0 ) - { - no_output_opt = 1; - } - else if ( strcmp("strip-eol", arg->string) == 0 ) - { - strip_eol_opt = 1; - } - arg = lol_get( frame->args, ++a ); - } - } - - /* The following fflush() call seems to be indicated as a workaround for a - * popen() bug on POSIX implementations related to synhronizing input - * stream positions for the called and the calling process. - */ - fflush( NULL ); - - p = popen( command->string, "r" ); - if ( p == NULL ) - return L0; - - string_new( &s ); - - while ( ( ret = fread( buffer, sizeof( char ), sizeof( buffer ) - 1, p ) ) > 0 ) - { - buffer[ret] = 0; - if ( !no_output_opt ) - { - if ( strip_eol_opt ) - rtrim(buffer); - string_append( &s, buffer ); - } - } - - exit_status = pclose( p ); - - /* The command output is returned first. */ - result = list_new( L0, newstr( s.value ) ); - string_free( &s ); - - /* The command exit result next. */ - if ( exit_status_opt ) - { - if ( WIFEXITED(exit_status) ) - exit_status = WEXITSTATUS(exit_status); - else - exit_status = -1; - sprintf( buffer, "%d", exit_status ); - result = list_new( result, newstr( buffer ) ); - } - - return result; -} - -#else /* #ifdef HAVE_POPEN */ - -LIST * builtin_shell( PARSE * parse, FRAME * frame ) -{ - return L0; -} - -#endif /* #ifdef HAVE_POPEN */ diff --git a/jam-files/engine/builtins.h b/jam-files/engine/builtins.h deleted file mode 100644 index 5fed07c9..00000000 --- a/jam-files/engine/builtins.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -#ifndef JAM_BUILTINS_H -# define JAM_BUILTINS_H - -# include "frames.h" - -/* - * builtins.h - compile parsed jam statements - */ - -void load_builtins(); -void init_set(); -void init_path(); -void init_regex(); -void init_property_set(); -void init_sequence(); -void init_order(); - -LIST *builtin_calc( PARSE *parse, FRAME *args ); -LIST *builtin_depends( PARSE *parse, FRAME *args ); -LIST *builtin_rebuilds( PARSE *parse, FRAME *args ); -LIST *builtin_echo( PARSE *parse, FRAME *args ); -LIST *builtin_exit( PARSE *parse, FRAME *args ); -LIST *builtin_flags( PARSE *parse, FRAME *args ); -LIST *builtin_glob( PARSE *parse, FRAME *args ); -LIST *builtin_glob_recursive( PARSE *parse, FRAME *frame ); -LIST *builtin_subst( PARSE *parse, FRAME *args ); -LIST *builtin_match( PARSE *parse, FRAME *args ); -LIST *builtin_split_by_characters( PARSE *parse, FRAME *args ); -LIST *builtin_hdrmacro( PARSE *parse, FRAME *args ); -LIST *builtin_rulenames( PARSE *parse, FRAME *args ); -LIST *builtin_varnames( PARSE *parse, FRAME *args ); -LIST *builtin_delete_module( PARSE *parse, FRAME *args ); -LIST *builtin_import( PARSE *parse, FRAME *args ); -LIST *builtin_export( PARSE *parse, FRAME *args ); -LIST *builtin_caller_module( PARSE *parse, FRAME *args ); -LIST *builtin_backtrace( PARSE *parse, FRAME *args ); -LIST *builtin_pwd( PARSE *parse, FRAME *args ); -LIST *builtin_update( PARSE *parse, FRAME *args ); -LIST *builtin_update_now( PARSE *parse, FRAME *args ); -LIST *builtin_search_for_target( PARSE *parse, FRAME *args ); -LIST *builtin_import_module( PARSE *parse, FRAME *args ); -LIST *builtin_imported_modules( PARSE *parse, FRAME *frame ); -LIST *builtin_instance( PARSE *parse, FRAME *frame ); -LIST *builtin_sort( PARSE *parse, FRAME *frame ); -LIST *builtin_normalize_path( PARSE *parse, FRAME *frame ); -LIST *builtin_native_rule( PARSE *parse, FRAME *frame ); -LIST *builtin_has_native_rule( PARSE *parse, FRAME *frame ); -LIST *builtin_user_module( PARSE *parse, FRAME *frame ); -LIST *builtin_nearest_user_location( PARSE *parse, FRAME *frame ); -LIST *builtin_check_if_file( PARSE *parse, FRAME *frame ); -LIST *builtin_python_import_rule( PARSE *parse, FRAME *frame ); -LIST *builtin_shell( PARSE *parse, FRAME *frame ); -LIST *builtin_md5( PARSE *parse, FRAME *frame ); -LIST *builtin_file_open( PARSE *parse, FRAME *frame ); -LIST *builtin_pad( PARSE *parse, FRAME *frame ); -LIST *builtin_precious( PARSE *parse, FRAME *frame ); -LIST *builtin_self_path( PARSE *parse, FRAME *frame ); -LIST *builtin_makedir( PARSE *parse, FRAME *frame ); - -void backtrace( FRAME *frame ); -extern int last_update_now_status; - -#endif diff --git a/jam-files/engine/bump_version.py b/jam-files/engine/bump_version.py deleted file mode 100644 index 9423c4c7..00000000 --- a/jam-files/engine/bump_version.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/python - -# This script is used to bump version of bjam. It takes a single argument, e.g -# -# ./bump_version.py 3.1.9 -# -# and updates all necessary files. For the time being, it's assumes presense -# of 'perl' executable and Debian-specific 'dch' executable. -# - - -import os -import os.path -import re -import string -import sys - -srcdir = os.path.abspath(os.path.dirname(__file__ )) -docdir = os.path.abspath(os.path.join(srcdir,"..","doc")) - -def edit(file,replacements): - print " '%s'..." %(file) - text = open(file,'r').read() - while len(replacements) > 0: - #~ print " '%s' ==> '%s'" % (replacements[0],replacements[1]) - text = re.compile(replacements[0],re.M).subn(replacements[1],text)[0] - replacements = replacements[2:] - #~ print text - open(file,'w').write(text) - -def make_edits(version): - edit(os.path.join(srcdir,"boost-jam.spec"), [ - '^Version:.*$','Version: %s' % string.join(version, "."), - ]) - - edit(os.path.join(srcdir,"build.jam"), [ - '^_VERSION_ = .* ;$','_VERSION_ = %s %s %s ;' % (version[0], version[1], version[2]), - ]) - - edit(os.path.join(docdir,"bjam.qbk"), [ - '\[version.*\]','[version: %s]' % string.join(version, '.'), - '\[def :version:.*\]','[def :version: %s]' % string.join(version, '.'), - ]) - - edit(os.path.join(srcdir,"patchlevel.h"), [ - '^#define VERSION_MAJOR .*$', - '#define VERSION_MAJOR %s' % (version[0]), - '^#define VERSION_MINOR .*$', - '#define VERSION_MINOR %s' % (version[1]), - '^#define VERSION_PATCH .*$', - '#define VERSION_PATCH %s' % (version[2]), - '^#define VERSION_MAJOR_SYM .*$', - '#define VERSION_MAJOR_SYM "0%s"' % (version[0]), - '^#define VERSION_MINOR_SYM .*$', - '#define VERSION_MINOR_SYM "%s"' % (version[1]), - '^#define VERSION_PATCH_SYM .*$', - '#define VERSION_PATCH_SYM "%s"' % (version[2]), - '^#define VERSION .*$', - '#define VERSION "%s"' % string.join(version, '.'), - '^#define JAMVERSYM .*$', - '#define JAMVERSYM "JAMVERSION=%s.%s"' % (version[0],version[1]), - ]) - -def main(): - - if len(sys.argv) < 2: - print "Expect new version as argument" - sys.exit(1) - - version = string.split(sys.argv[1], ".") - print "Setting version to", version - make_edits(version) - -if __name__ == '__main__': - main() - -#~ Copyright 2006 Rene Rivera. -#~ Copyright 2005-2006 Vladimir Prus. -#~ Distributed under the Boost Software License, Version 1.0. -#~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) diff --git a/jam-files/engine/class.c b/jam-files/engine/class.c deleted file mode 100644 index ff4ec568..00000000 --- a/jam-files/engine/class.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "class.h" -#include "strings.h" -#include "variable.h" -#include "frames.h" -#include "rules.h" -#include "newstr.h" - -#include "hash.h" - - -static struct hash * classes = 0; - - -static void check_defined( LIST * class_names ) -{ - for ( ; class_names; class_names = class_names->next ) - { - char * * p = &class_names->string; - if ( !hashcheck( classes, (HASHDATA * *)&p ) ) - { - printf( "Class %s is not defined\n", class_names->string ); - abort(); - } - } -} - - -static char * class_module_name( char * declared_name ) -{ - string name[ 1 ]; - char * result; - - string_new( name ); - string_append( name, "class@" ); - string_append( name, declared_name ); - - result = newstr( name->value ); - string_free( name ); - - return result; -} - - -struct import_base_data -{ - char * base_name; - module_t * base_module; - module_t * class_module; -}; - - -static void import_base_rule( void * r_, void * d_ ) -{ - RULE * r = (RULE *)r_; - RULE * ir1; - RULE * ir2; - struct import_base_data * d = (struct import_base_data *)d_; - string qualified_name[ 1 ]; - - string_new ( qualified_name ); - string_append ( qualified_name, d->base_name ); - string_push_back( qualified_name, '.' ); - string_append ( qualified_name, r->name ); - - ir1 = import_rule( r, d->class_module, r->name ); - ir2 = import_rule( r, d->class_module, qualified_name->value ); - - /* Copy 'exported' flag. */ - ir1->exported = ir2->exported = r->exported; - - /* If we are importing a class method, localize it. */ - if ( ( r->module == d->base_module ) || ( r->module->class_module && - ( r->module->class_module == d->base_module ) ) ) - ir1->module = ir2->module = d->class_module; - - string_free( qualified_name ); -} - - -/* - * For each exported rule 'n', declared in class module for base, imports that - * rule in 'class' as 'n' and as 'base.n'. Imported rules are localized and - * marked as exported. - */ - -static void import_base_rules( module_t * class, char * base ) -{ - module_t * base_module = bindmodule( class_module_name( base ) ); - struct import_base_data d; - d.base_name = base; - d.base_module = base_module; - d.class_module = class; - - if ( base_module->rules ) - hashenumerate( base_module->rules, import_base_rule, &d ); - - import_module( imported_modules( base_module ), class ); -} - - -char * make_class_module( LIST * xname, LIST * bases, FRAME * frame ) -{ - char * name = class_module_name( xname->string ); - char * * pp = &xname->string; - module_t * class_module = 0; - module_t * outer_module = frame->module; - - if ( !classes ) - classes = hashinit( sizeof( char * ), "classes" ); - - if ( hashcheck( classes, (HASHDATA * *)&pp ) ) - { - printf( "Class %s already defined\n", xname->string ); - abort(); - } - else - { - hashenter( classes, (HASHDATA * *)&pp ); - } - check_defined( bases ); - - class_module = bindmodule( name ); - - exit_module( outer_module ); - enter_module( class_module ); - - var_set( "__name__", xname, VAR_SET ); - var_set( "__bases__", bases, VAR_SET ); - - exit_module( class_module ); - enter_module( outer_module ); - - for ( ; bases; bases = bases->next ) - import_base_rules( class_module, bases->string ); - - return name; -} diff --git a/jam-files/engine/class.h b/jam-files/engine/class.h deleted file mode 100644 index f7faeff6..00000000 --- a/jam-files/engine/class.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#ifndef CLASS_H_VP_2003_08_01 -#define CLASS_H_VP_2003_08_01 - -#include "lists.h" -#include "frames.h" - -char* make_class_module(LIST* xname, LIST* bases, FRAME* frame); - -#endif diff --git a/jam-files/engine/command.c b/jam-files/engine/command.c deleted file mode 100644 index d2ea0681..00000000 --- a/jam-files/engine/command.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * command.c - maintain lists of commands - */ - -#include "jam.h" - -#include "lists.h" -#include "parse.h" -#include "variable.h" -#include "rules.h" - -#include "command.h" -#include <limits.h> -#include <string.h> - - -/* - * cmd_new() - return a new CMD or 0 if too many args - */ - -CMD * cmd_new( RULE * rule, LIST * targets, LIST * sources, LIST * shell ) -{ - CMD * cmd = (CMD *)BJAM_MALLOC( sizeof( CMD ) ); - /* Lift line-length limitation entirely when JAMSHELL is just "%". */ - int no_limit = ( shell && !strcmp(shell->string,"%") && !list_next(shell) ); - int max_line = MAXLINE; - int allocated = -1; - - cmd->rule = rule; - cmd->shell = shell; - cmd->next = 0; - - lol_init( &cmd->args ); - lol_add( &cmd->args, targets ); - lol_add( &cmd->args, sources ); - cmd->buf = 0; - - do - { - BJAM_FREE( cmd->buf ); /* free any buffer from previous iteration */ - - cmd->buf = (char*)BJAM_MALLOC_ATOMIC( max_line + 1 ); - - if ( cmd->buf == 0 ) - break; - - allocated = var_string( rule->actions->command, cmd->buf, max_line, &cmd->args ); - - max_line = max_line * 2; - } - while ( ( allocated < 0 ) && ( max_line < INT_MAX / 2 ) ); - - if ( !no_limit ) - { - /* Bail if the result will not fit in MAXLINE. */ - char * s = cmd->buf; - while ( *s ) - { - size_t l = strcspn( s, "\n" ); - - if ( l > MAXLINE ) - { - /* We do not free targets/sources/shell if bailing. */ - cmd_free( cmd ); - return 0; - } - - s += l; - if ( *s ) - ++s; - } - } - - return cmd; -} - - -/* - * cmd_free() - free a CMD - */ - -void cmd_free( CMD * cmd ) -{ - lol_free( &cmd->args ); - list_free( cmd->shell ); - BJAM_FREE( cmd->buf ); - BJAM_FREE( (char *)cmd ); -} diff --git a/jam-files/engine/command.h b/jam-files/engine/command.h deleted file mode 100644 index ddd38e68..00000000 --- a/jam-files/engine/command.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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; /* actual commands */ -}; - -CMD * cmd_new -( - RULE * rule, /* rule (referenced) */ - LIST * targets, /* $(<) (freed) */ - LIST * sources, /* $(>) (freed) */ - LIST * shell /* $(SHELL) (freed) */ -); - -void cmd_free( CMD * ); - -#define cmd_next( c ) ( ( c )->next ) diff --git a/jam-files/engine/compile.c b/jam-files/engine/compile.c deleted file mode 100644 index 2c049aae..00000000 --- a/jam-files/engine/compile.c +++ /dev/null @@ -1,1424 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# 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 "make.h" -# include "search.h" -# include "hdrmacro.h" -# include "hash.h" -# include "modules.h" -# include "strings.h" -# include "builtins.h" -# include "class.h" - -# include <assert.h> -# include <string.h> -# include <stdarg.h> - -/* - * compile.c - compile parsed jam statements - * - * External routines: - * - * compile_append() - append list results of two statements - * 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_while() - compile 'while' 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 - * - * builtin_depends() - DEPENDS/INCLUDES rule - * builtin_echo() - ECHO rule - * builtin_exit() - EXIT rule - * builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule - * - * 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. - * 09/11/00 (seiwald) - new evaluate_rule() for headers(). - * 09/11/00 (seiwald) - compile_xxx() now return LIST *. - * New compile_append() and compile_list() in - * support of building lists here, rather than - * in jamgram.yy. - * 01/10/00 (seiwald) - built-ins split out to builtin.c. - */ - -static void debug_compile( int which, char *s, FRAME* frame ); -int glob( char *s, char *c ); -/* Internal functions from builtins.c */ -void backtrace( FRAME *frame ); -void backtrace_line( FRAME *frame ); -void print_source_line( PARSE* p ); - -struct frame * frame_before_python_call; - -void frame_init( FRAME* frame ) -{ - frame->prev = 0; - frame->prev_user = 0; - lol_init(frame->args); - frame->module = root_module(); - frame->rulename = "module scope"; - frame->procedure = 0; -} - - -void frame_free( FRAME* frame ) -{ - lol_free( frame->args ); -} - - -/* - * 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, FRAME * frame ) -{ - /* Append right to left. */ - return list_append( - parse_evaluate( parse->left, frame ), - parse_evaluate( parse->right, frame ) ); -} - - -/* - * 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 ) ) - { - char *st = t ? t->string : ""; - 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, FRAME * frame ) -{ - LIST * ll; - LIST * lr; - LIST * s; - LIST * t; - int status = 0; - - /* Short circuit lr eval for &&, ||, and 'in'. */ - - ll = parse_evaluate( parse->left, frame ); - 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_evaluate( parse->right, frame ); - } - - /* 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", frame ); - 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, newstr( "1" ) ); - - 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 * parse, FRAME * frame ) -{ - LIST * nv = parse_evaluate( parse->left, frame ); - LIST * l; - SETTINGS * s = 0; - - if ( parse->num ) - { - s = addsettings( s, VAR_SET, parse->string, L0 ); - pushsettings( s ); - } - - /* Call var_set to reset $(parse->string) for each val. */ - - for ( l = nv; l; l = list_next( l ) ) - { - LIST * val = list_new( L0, copystr( l->string ) ); - var_set( parse->string, val, VAR_SET ); - list_free( parse_evaluate( parse->right, frame ) ); - } - - if ( parse->num ) - { - popsettings( s ); - freesettings( s ); - } - - list_free( nv ); - - return L0; -} - -/* - * compile_if() - compile 'if' rule - * - * parse->left condition tree - * parse->right then tree - * parse->third else tree - */ - -LIST * compile_if( PARSE * p, FRAME * frame ) -{ - LIST * l = parse_evaluate( p->left, frame ); - if ( l ) - { - list_free( l ); - return parse_evaluate( p->right, frame ); - } - return parse_evaluate( p->third, frame ); -} - - -LIST * compile_while( PARSE * p, FRAME * frame ) -{ - LIST * r = 0; - LIST * l; - while ( ( l = parse_evaluate( p->left, frame ) ) ) - { - list_free( l ); - if ( r ) list_free( r ); - r = parse_evaluate( p->right, frame ); - } - return r; -} - - -/* - * 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, FRAME * frame ) -{ - LIST * nt = parse_evaluate( parse->left, frame ); - - if ( DEBUG_COMPILE ) - { - debug_compile( 0, "include", frame); - list_print( nt ); - printf( "\n" ); - } - - if ( nt ) - { - TARGET * t = bindtarget( nt->string ); - - /* DWA 2001/10/22 - Perforce Jam cleared the arguments here, which - * prevents an included file from being treated as part of the body of a - * rule. I did not see any reason to do that, so I lifted the - * restriction. - */ - - /* Bind the include file under the influence of */ - /* "on-target" variables. Though they are targets, */ - /* include files are not built with make(). */ - - pushsettings( t->settings ); - /* We don't expect that file to be included is generated by some - action. Therefore, pass 0 as third argument. - If the name resolves to directory, let it error out. */ - t->boundname = search( t->name, &t->time, 0, 0 ); - popsettings( t->settings ); - - parse_file( t->boundname, frame ); - } - - list_free( nt ); - - return L0; -} - -static LIST* evaluate_in_module ( char* module_name, PARSE * p, FRAME* frame) -{ - LIST* result; - - module_t* outer_module = frame->module; - frame->module = module_name ? bindmodule( module_name ) : root_module(); - - if ( outer_module != frame->module ) - { - exit_module( outer_module ); - enter_module( frame->module ); - } - - result = parse_evaluate( p, frame ); - - if ( outer_module != frame->module ) - { - exit_module( frame->module ); - enter_module( outer_module ); - frame->module = outer_module; - } - - return result; -} - - -LIST * compile_module( PARSE * p, FRAME * frame ) -{ - /* Here we are entering a module declaration block. */ - LIST * module_name = parse_evaluate( p->left, frame ); - LIST * result = evaluate_in_module( module_name ? module_name->string : 0, - p->right, frame ); - list_free( module_name ); - return result; -} - - -LIST * compile_class( PARSE * p, FRAME * frame ) -{ - /** Todo: check for empty class name. - Check for class redeclaration. */ - - char * class_module = 0; - - LIST * name = parse_evaluate( p->left->right, frame ); - LIST * bases = 0; - - if ( p->left->left ) - bases = parse_evaluate( p->left->left->right, frame ); - - class_module = make_class_module( name, bases, frame ); - evaluate_in_module( class_module, p->right, frame ); - - return L0; -} - - -/* - * compile_list() - expand and return a list. - * - * parse->string - character string to expand. - */ - -LIST * compile_list( PARSE * parse, FRAME * frame ) -{ - /* s is a copyable string */ - char * s = parse->string; - return var_expand( L0, s, s + strlen( s ), frame->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, FRAME * frame ) -{ - LIST * l; - SETTINGS * s = 0; - LIST * nt = parse_evaluate( parse->left, frame ); - LIST * ns = parse_evaluate( parse->right, frame ); - LIST * result; - - if ( DEBUG_COMPILE ) - { - debug_compile( 0, "local", frame ); - list_print( nt ); - printf( " = " ); - list_print( ns ); - printf( "\n" ); - } - - /* Initial value is ns. */ - for ( l = nt; l; l = list_next( l ) ) - s = addsettings( s, VAR_SET, 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_evaluate( parse->third, frame ); - popsettings( s ); - - freesettings( s ); - - return result; -} - - -/* - * compile_null() - do nothing -- a stub for parsing. - */ - -LIST * compile_null( PARSE * parse, FRAME * frame ) -{ - return L0; -} - - -/* - * compile_on() - run rule under influence of on-target variables - * - * parse->left list of files to include (can only do 1). - * parse->right rule to run. - * - * EXPERIMENTAL! - */ - -LIST * compile_on( PARSE * parse, FRAME * frame ) -{ - LIST * nt = parse_evaluate( parse->left, frame ); - LIST * result = 0; - - if ( DEBUG_COMPILE ) - { - debug_compile( 0, "on", frame ); - list_print( nt ); - printf( "\n" ); - } - - if ( nt ) - { - TARGET * t = bindtarget( nt->string ); - pushsettings( t->settings ); - result = parse_evaluate( parse->right, frame ); - popsettings( t->settings ); - } - - list_free( nt ); - - return result; -} - - -/* - * compile_rule() - compile a single user defined rule. - * - * parse->string name of user defined rule. - * parse->left parameters (list of lists) to rule, recursing left. - * - * Wrapped around evaluate_rule() so that headers() can share it. - */ - -LIST * compile_rule( PARSE * parse, FRAME * frame ) -{ - FRAME inner[ 1 ]; - LIST * result; - PARSE * p; - - /* Build up the list of arg lists. */ - frame_init( inner ); - inner->prev = frame; - inner->prev_user = frame->module->user_module ? frame : frame->prev_user; - inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below. */ - inner->procedure = parse; - /* Special-case LOL of length 1 where the first list is totally empty. - This is created when calling functions with no parameters, due to - the way jam grammar is written. This is OK when one jam function - calls another, but really not good when Jam function calls Python. */ - if ( parse->left->left == NULL && parse->left->right->func == compile_null) - ; - else - for ( p = parse->left; p; p = p->left ) - lol_add( inner->args, parse_evaluate( p->right, frame ) ); - - /* And invoke the rule. */ - result = evaluate_rule( parse->string, inner ); - frame_free( inner ); - return result; -} - - -static void argument_error( char * message, RULE * rule, FRAME * frame, LIST* arg ) -{ - LOL * actual = frame->args; - assert( frame->procedure != 0 ); - backtrace_line( frame->prev ); - printf( "*** argument error\n* rule %s ( ", frame->rulename ); - lol_print( rule->arguments->data ); - printf( " )\n* called with: ( " ); - lol_print( actual ); - printf( " )\n* %s %s\n", message, arg ? arg->string : "" ); - print_source_line( rule->procedure ); - printf( "see definition of rule '%s' being called\n", rule->name ); - backtrace( frame->prev ); - exit( 1 ); -} - - -/* Define delimiters for type check elements in argument lists (and return type - * specifications, eventually). - */ -# define TYPE_OPEN_DELIM '[' -# define TYPE_CLOSE_DELIM ']' - -/* - * is_type_name() - true iff the given string represents a type check - * specification. - */ - -static int is_type_name( char * s ) -{ - return ( s[ 0 ] == TYPE_OPEN_DELIM ) && - ( s[ strlen( s ) - 1 ] == TYPE_CLOSE_DELIM ); -} - - -/* - * arg_modifier - if the next element of formal is a single character, return - * that; return 0 otherwise. Used to extract "*+?" modifiers * from argument - * lists. - */ - -static char arg_modifier( LIST * formal ) -{ - if ( formal->next ) - { - char * next = formal->next->string; - if ( next && ( next[ 0 ] != 0 ) && ( next[ 1 ] == 0 ) ) - return next[ 0 ]; - } - return 0; -} - - -/* - * type_check() - checks that each element of values satisfies the requirements - * of type_name. - * - * caller - the frame of the rule calling the rule whose arguments are - * being checked - * - * called - the rule being called - * - * arg_name - a list element containing the name of the argument being - * checked - */ - -static void type_check -( - char * type_name, - LIST * values, - FRAME * caller, - RULE * called, - LIST * arg_name -) -{ - static module_t * typecheck = 0; - - /* If nothing to check, bail now. */ - if ( !values || !type_name ) - return; - - if ( !typecheck ) - typecheck = bindmodule( ".typecheck" ); - - /* If the checking rule can not be found, also bail. */ - { - RULE checker_, *checker = &checker_; - - checker->name = type_name; - if ( !typecheck->rules || !hashcheck( typecheck->rules, (HASHDATA * *)&checker ) ) - return; - } - - exit_module( caller->module ); - - while ( values != 0 ) - { - LIST *error; - FRAME frame[1]; - frame_init( frame ); - frame->module = typecheck; - frame->prev = caller; - frame->prev_user = caller->module->user_module ? caller : caller->prev_user; - - enter_module( typecheck ); - /* Prepare the argument list */ - lol_add( frame->args, list_new( L0, values->string ) ); - error = evaluate_rule( type_name, frame ); - - exit_module( typecheck ); - - if ( error ) - argument_error( error->string, called, caller, arg_name ); - - frame_free( frame ); - values = values->next; - } - - enter_module( caller->module ); -} - -/* - * collect_arguments() - local argument checking and collection - */ -static SETTINGS * -collect_arguments( RULE* rule, FRAME* frame ) -{ - SETTINGS *locals = 0; - - LOL * all_actual = frame->args; - LOL * all_formal = rule->arguments ? rule->arguments->data : 0; - if ( all_formal ) /* Nothing to set; nothing to check */ - { - int max = all_formal->count > all_actual->count - ? all_formal->count - : all_actual->count; - - int n; - for ( n = 0; n < max ; ++n ) - { - LIST *actual = lol_get( all_actual, n ); - char *type_name = 0; - - LIST *formal; - for ( formal = lol_get( all_formal, n ); formal; formal = formal->next ) - { - char* name = formal->string; - - if ( is_type_name(name) ) - { - if ( type_name ) - argument_error( "missing argument name before type name:", rule, frame, formal ); - - if ( !formal->next ) - argument_error( "missing argument name after type name:", rule, frame, formal ); - - type_name = formal->string; - } - else - { - LIST* value = 0; - char modifier; - LIST* arg_name = formal; /* hold the argument name for type checking */ - int multiple = 0; - - /* Stop now if a variable number of arguments are specified */ - if ( name[0] == '*' && name[1] == 0 ) - return locals; - - modifier = arg_modifier( formal ); - - if ( !actual && modifier != '?' && modifier != '*' ) - argument_error( "missing argument", rule, frame, formal ); - - switch ( modifier ) - { - case '+': - case '*': - value = list_copy( 0, actual ); - multiple = 1; - actual = 0; - /* skip an extra element for the modifier */ - formal = formal->next; - break; - case '?': - /* skip an extra element for the modifier */ - formal = formal->next; - /* fall through */ - default: - if ( actual ) /* in case actual is missing */ - { - value = list_new( 0, actual->string ); - actual = actual->next; - } - } - - locals = addsettings(locals, VAR_SET, name, value); - locals->multiple = multiple; - type_check( type_name, value, frame, rule, arg_name ); - type_name = 0; - } - } - - if ( actual ) - { - argument_error( "extra argument", rule, frame, actual ); - } - } - } - return locals; -} - -RULE * -enter_rule( char *rulename, module_t *target_module ); - -#ifdef HAVE_PYTHON - -static int python_instance_number = 0; - - -/* Given a Python object, return a string to use in Jam - code instead of said object. - If the object is string, use the string value - If the object implemenets __jam_repr__ method, use that. - Otherwise return 0. - - The result value is newstr-ed. */ -char *python_to_string(PyObject* value) -{ - if (PyString_Check(value)) - { - return newstr(PyString_AsString(value)); - } - else - { - /* See if this is an instance that defines special __jam_repr__ - method. */ - if (PyInstance_Check(value) - && PyObject_HasAttrString(value, "__jam_repr__")) - { - PyObject* repr = PyObject_GetAttrString(value, "__jam_repr__"); - if (repr) - { - PyObject* arguments2 = PyTuple_New(0); - PyObject* value2 = PyObject_Call(repr, arguments2, 0); - Py_DECREF(repr); - Py_DECREF(arguments2); - if (PyString_Check(value2)) - { - return newstr(PyString_AsString(value2)); - } - Py_DECREF(value2); - } - } - return 0; - } -} - -static LIST* -call_python_function(RULE* r, FRAME* frame) -{ - LIST * result = 0; - PyObject * arguments = 0; - PyObject * kw = NULL; - int i ; - PyObject * py_result; - - if (r->arguments) - { - SETTINGS * args; - - arguments = PyTuple_New(0); - kw = PyDict_New(); - - for (args = collect_arguments(r, frame); args; args = args->next) - { - PyObject *key = PyString_FromString(args->symbol); - PyObject *value = 0; - if (args->multiple) - value = list_to_python(args->value); - else { - if (args->value) - value = PyString_FromString(args->value->string); - } - - if (value) - PyDict_SetItem(kw, key, value); - Py_DECREF(key); - Py_XDECREF(value); - } - } - else - { - arguments = PyTuple_New( frame->args->count ); - for ( i = 0; i < frame->args->count; ++i ) - { - PyObject * arg = PyList_New(0); - LIST* l = lol_get( frame->args, i); - - for ( ; l; l = l->next ) - { - PyObject * v = PyString_FromString(l->string); - PyList_Append( arg, v ); - Py_DECREF(v); - } - /* Steals reference to 'arg' */ - PyTuple_SetItem( arguments, i, arg ); - } - } - - frame_before_python_call = frame; - py_result = PyObject_Call( r->python_function, arguments, kw ); - Py_DECREF(arguments); - Py_XDECREF(kw); - if ( py_result != NULL ) - { - if ( PyList_Check( py_result ) ) - { - int size = PyList_Size( py_result ); - int i; - for ( i = 0; i < size; ++i ) - { - PyObject * item = PyList_GetItem( py_result, i ); - char *s = python_to_string (item); - if (!s) { - fprintf( stderr, "Non-string object returned by Python call.\n" ); - } else { - result = list_new (result, s); - } - } - } - else if ( py_result == Py_None ) - { - result = L0; - } - else - { - char *s = python_to_string(py_result); - if (s) - result = list_new(0, s); - else - /* We have tried all we could. Return empty list. There are - cases, e.g. feature.feature function that should return - value for the benefit of Python code and which also can be - called by Jam code, where no sensible value can be - returned. We cannot even emit a warning, since there will - be a pile of them. */ - result = L0; - } - - Py_DECREF( py_result ); - } - else - { - PyErr_Print(); - fprintf(stderr,"Call failed\n"); - } - - return result; -} - - -module_t * python_module() -{ - static module_t * python = 0; - if ( !python ) - python = bindmodule("__python__"); - return python; -} - -#endif - - -/* - * evaluate_rule() - execute a rule invocation. - */ - -LIST * -evaluate_rule( - char * rulename, - FRAME * frame ) -{ - LIST * result = L0; - RULE * rule; - profile_frame prof[1]; - module_t * prev_module = frame->module; - - LIST * l; - { - LOL arg_context_, * arg_context = &arg_context_; - if ( !frame->prev ) - lol_init(arg_context); - else - arg_context = frame->prev->args; - l = var_expand( L0, rulename, rulename+strlen(rulename), arg_context, 0 ); - } - - if ( !l ) - { - backtrace_line( frame->prev ); - printf( "warning: rulename %s expands to empty string\n", rulename ); - backtrace( frame->prev ); - return result; - } - - rulename = l->string; - rule = bindrule( l->string, frame->module ); - -#ifdef HAVE_PYTHON - if ( rule->python_function ) - { - /* The below messing with modules is due to the way modules are - * implemented in Jam. Suppose we are in module M1 now. The global - * variable map actually holds 'M1' variables, and M1->variables hold - * global variables. - * - * If we call Python right away, Python calls back Jam and then Jam - * does 'module M1 { }' then Jam will try to swap the current global - * variables with M1->variables. The result will be that global - * variables map will hold global variables, and any variable settings - * we do will go to the global module, not M1. - * - * By restoring basic state, where the global variable map holds global - * variable, we make sure any future 'module M1' entry will work OK. - */ - - LIST * result; - module_t * m = python_module(); - - frame->module = m; - - exit_module( prev_module ); - enter_module( m ); - - result = call_python_function( rule, frame ); - - exit_module( m ); - enter_module ( prev_module ); - - return result; - } -#endif - - /* Drop the rule name. */ - l = list_pop_front( l ); - - /* Tack the rest of the expansion onto the front of the first argument. */ - frame->args->list[0] = list_append( l, lol_get( frame->args, 0 ) ); - - if ( DEBUG_COMPILE ) - { - /* Try hard to indicate in which module the rule is going to execute. */ - if ( rule->module != frame->module - && rule->procedure != 0 && strcmp( rulename, rule->procedure->rulename ) ) - { - char buf[256] = ""; - strncat( buf, rule->module->name, sizeof( buf ) - 1 ); - strncat( buf, rule->name, sizeof( buf ) - 1 ); - debug_compile( 1, buf, frame ); - } - else - { - debug_compile( 1, rulename, frame ); - } - - lol_print( frame->args ); - printf( "\n" ); - } - - if ( rule->procedure && rule->module != prev_module ) - { - /* Propagate current module to nested rule invocations. */ - frame->module = rule->module; - - /* Swap variables. */ - exit_module( prev_module ); - enter_module( rule->module ); - } - - /* Record current rule name in frame. */ - if ( rule->procedure ) - { - frame->rulename = rulename; - /* And enter record profile info. */ - if ( DEBUG_PROFILE ) - profile_enter( rule->procedure->rulename, prof ); - } - - /* Check traditional targets $(<) and sources $(>). */ - if ( !rule->actions && !rule->procedure ) - { - backtrace_line( frame->prev ); - printf( "rule %s unknown in module %s\n", rule->name, frame->module->name ); - backtrace( frame->prev ); - exit( 1 ); - } - - /* 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 *)BJAM_MALLOC( sizeof( ACTION ) ); - memset( (char *)action, '\0', sizeof( *action ) ); - - action->rule = rule; - action->targets = targetlist( (TARGETS *)0, lol_get( frame->args, 0 ) ); - action->sources = targetlist( (TARGETS *)0, lol_get( frame->args, 1 ) ); - - /* If we have a group of targets all being built using the same action - * then we must not allow any of them to be used as sources unless they - * had all already been built in the first place or their joined action - * has had a chance to finish its work and build all of them anew. - * - * Without this it might be possible, in case of a multi-process build, - * for their action, triggered by buiding one of the targets, to still - * be running when another target in the group reports as done in order - * to avoid triggering the same action again and gets used prematurely. - * - * As a quick-fix to achieve this effect we make all the targets list - * each other as 'included targets'. More precisely, we mark the first - * listed target as including all the other targets in the list and vice - * versa. This makes anyone depending on any of those targets implicitly - * depend on all of them, thus making sure none of those targets can be - * used as sources until all of them have been built. Note that direct - * dependencies could not have been used due to the 'circular - * dependency' issue. - * - * TODO: Although the current implementation solves the problem of one - * of the targets getting used before its action completes its work it - * also forces the action to run whenever any of the targets in the - * group is not up to date even though some of them might not actually - * be used by the targets being built. We should see how we can - * correctly recognize such cases and use that to avoid running the - * action if possible and not rebuild targets not actually depending on - * targets that are not up to date. - * - * TODO: Using the 'include' feature might have side-effects due to - * interaction with the actual 'inclusion scanning' system. This should - * be checked. - */ - if ( action->targets ) - { - TARGET * t0 = action->targets->target; - for ( t = action->targets->next; t; t = t->next ) - { - target_include( t->target, t0 ); - target_include( t0, t->target ); - } - } - - /* 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. - * parse_refer()/parse_free() call pair added to ensure rule not freed - * during use. - */ - if ( rule->procedure ) - { - SETTINGS * local_args = collect_arguments( rule, frame ); - PARSE * parse = rule->procedure; - parse_refer( parse ); - - pushsettings( local_args ); - result = parse_evaluate( parse, frame ); - popsettings( local_args ); - freesettings( local_args ); - - parse_free( parse ); - } - - if ( frame->module != prev_module ) - { - exit_module( frame->module ); - enter_module( prev_module ); - } - - if ( DEBUG_PROFILE && rule->procedure ) - profile_exit( prof ); - - if ( DEBUG_COMPILE ) - debug_compile( -1, 0, frame); - - return result; -} - - -/* - * Call the given rule with the specified parameters. The parameters should be - * of type LIST* and end with a NULL pointer. This differs from 'evaluate_rule' - * in that frame for the called rule is prepared inside 'call_rule'. - * - * This function is useful when a builtin rule (in C) wants to call another rule - * which might be implemented in Jam. - */ - -LIST * call_rule( char * rulename, FRAME * caller_frame, ... ) -{ - va_list va; - LIST * result; - - FRAME inner[1]; - frame_init( inner ); - inner->prev = caller_frame; - inner->prev_user = caller_frame->module->user_module ? - caller_frame : caller_frame->prev_user; - inner->module = caller_frame->module; - inner->procedure = 0; - - va_start( va, caller_frame ); - for ( ; ; ) - { - LIST * l = va_arg( va, LIST* ); - if ( !l ) - break; - lol_add( inner->args, l ); - } - va_end( va ); - - result = evaluate_rule( rulename, inner ); - - frame_free( inner ); - - 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, FRAME * frame ) -{ - /* Ignore result from first statement; return the 2nd. */ - /* Optimize recursion on the right by looping. */ - do list_free( parse_evaluate( parse->left, frame ) ); - while ( ( parse = parse->right )->func == compile_rules ); - return parse_evaluate( parse, frame ); -} - - -/* - * assign_var_mode() - convert ASSIGN_XXX compilation flag into corresponding - * VAR_XXX variable set flag. - */ - -static int assign_var_mode( int parsenum, char const * * tracetext ) -{ - char const * trace; - int setflag; - switch ( parsenum ) - { - case ASSIGN_SET : setflag = VAR_SET ; trace = "=" ; break; - case ASSIGN_APPEND : setflag = VAR_APPEND ; trace = "+="; break; - case ASSIGN_DEFAULT: setflag = VAR_DEFAULT; trace = "?="; break; - default: setflag = VAR_SET ; trace = "" ; break; - } - if ( tracetext ) - *tracetext = trace ; - return setflag; -} - -/* - * compile_set() - compile the "set variable" statement - * - * parse->left variable names - * parse->right variable values - * parse->num ASSIGN_SET/APPEND/DEFAULT - */ - -LIST * compile_set( PARSE * parse, FRAME * frame ) -{ - LIST * nt = parse_evaluate( parse->left, frame ); - LIST * ns = parse_evaluate( parse->right, frame ); - LIST * l; - char const * trace; - int setflag = assign_var_mode( parse->num, &trace ); - - if ( DEBUG_COMPILE ) - { - debug_compile( 0, "set", frame ); - list_print( nt ); - printf( " %s ", trace ); - 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 ), setflag ); - list_free( nt ); - return ns; -} - - -/* - * compile_setcomp() - support for `rule` - save parse tree. - * - * parse->string rule name - * parse->left rules for rule - * parse->right optional list-of-lists describing arguments - */ - -LIST * compile_setcomp( PARSE * parse, FRAME * frame ) -{ - argument_list * arg_list = 0; - - /* Create new LOL describing argument requirements if supplied. */ - if ( parse->right ) - { - PARSE * p; - arg_list = args_new(); - for ( p = parse->right; p; p = p->left ) - lol_add( arg_list->data, parse_evaluate( p->right, frame ) ); - } - - new_rule_body( frame->module, parse->string, arg_list, parse->left, !parse->num ); - 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 transferred directly - * to the rule flags (as defined in rules.h). - */ - -LIST * compile_setexec( PARSE * parse, FRAME * frame ) -{ - LIST * bindlist = parse_evaluate( parse->left, frame ); - new_rule_actions( frame->module, parse->string, parse->string1, bindlist, 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 ASSIGN_SET/APPEND - */ - -LIST * compile_settings( PARSE * parse, FRAME * frame ) -{ - LIST * nt = parse_evaluate( parse->left, frame ); - LIST * ns = parse_evaluate( parse->third, frame ); - LIST * targets = parse_evaluate( parse->right, frame ); - LIST * ts; - char const * trace; - int setflag = assign_var_mode( parse->num, &trace ); - - if ( DEBUG_COMPILE ) - { - debug_compile( 0, "set", frame ); - list_print( nt ); - printf( " on " ); - list_print( targets ); - printf( " %s ", trace ); - 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, setflag, 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, FRAME * frame ) -{ - LIST * nt = parse_evaluate( parse->left, frame ); - LIST * result = 0; - - if ( DEBUG_COMPILE ) - { - debug_compile( 0, "switch", frame ); - 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_evaluate( parse, frame ); - break; - } - } - - list_free( nt ); - return result; -} - - -/* - * debug_compile() - printf with indent to show rule expansion. - */ - -static void debug_compile( int which, char * s, FRAME * frame ) -{ - static int level = 0; - static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|"; - - if ( which >= 0 ) - { - int i; - - print_source_line( frame->procedure ); - - i = ( level + 1 ) * 2; - while ( i > 35 ) - { - fputs( indent, stdout ); - i -= 35; - } - - printf( "%*.*s ", i, i, indent ); - } - - if ( s ) - printf( "%s ", s ); - - level += which; -} diff --git a/jam-files/engine/compile.h b/jam-files/engine/compile.h deleted file mode 100644 index 7d5191f0..00000000 --- a/jam-files/engine/compile.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -#ifndef COMPILE_DWA20011022_H -# define COMPILE_DWA20011022_H - -# include "frames.h" -# include "parse.h" -# include "regexp.h" - -/* - * compile.h - compile parsed jam statements - */ - -void compile_builtins(); - -LIST *compile_append( PARSE *parse, FRAME *frame ); -LIST *compile_foreach( PARSE *parse, FRAME *frame ); -LIST *compile_if( PARSE *parse, FRAME *frame ); -LIST *compile_eval( PARSE *parse, FRAME *args ); -LIST *compile_include( PARSE *parse, FRAME *frame ); -LIST *compile_list( PARSE *parse, FRAME *frame ); -LIST *compile_local( PARSE *parse, FRAME *frame ); -LIST *compile_module( PARSE *parse, FRAME *frame ); -LIST *compile_class( PARSE *parse, FRAME *frame ); -LIST *compile_null( PARSE *parse, FRAME *frame ); -LIST *compile_on( PARSE *parse, FRAME *frame ); -LIST *compile_rule( PARSE *parse, FRAME *frame ); -LIST *compile_rules( PARSE *parse, FRAME *frame ); -LIST *compile_set( PARSE *parse, FRAME *frame ); -LIST *compile_setcomp( PARSE *parse, FRAME *frame ); -LIST *compile_setexec( PARSE *parse, FRAME *frame ); -LIST *compile_settings( PARSE *parse, FRAME *frame ); -LIST *compile_switch( PARSE *parse, FRAME *frame ); -LIST *compile_while( PARSE *parse, FRAME *frame ); - -LIST *evaluate_rule( char *rulename, FRAME *frame ); -LIST *call_rule( char *rulename, FRAME* caller_frame, ...); - -regexp* regex_compile( const char* pattern ); - -/* Flags for compile_set(), etc */ - -# define ASSIGN_SET 0x00 /* = assign variable */ -# define ASSIGN_APPEND 0x01 /* += append variable */ -# define ASSIGN_DEFAULT 0x02 /* set only if unset */ - -/* Flags for compile_setexec() */ - -# define EXEC_UPDATED 0x01 /* executes updated */ -# define EXEC_TOGETHER 0x02 /* executes together */ -# define EXEC_IGNORE 0x04 /* executes ignore */ -# define EXEC_QUIETLY 0x08 /* executes quietly */ -# define EXEC_PIECEMEAL 0x10 /* executes piecemeal */ -# define EXEC_EXISTING 0x20 /* executes existing */ - -/* 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 */ - -#endif - diff --git a/jam-files/engine/debian/changelog b/jam-files/engine/debian/changelog deleted file mode 100644 index 29084289..00000000 --- a/jam-files/engine/debian/changelog +++ /dev/null @@ -1,72 +0,0 @@ -bjam (3.1.12-1) unstable; urgency=low - - * New upstream release. - - -- Rene Rivera <grafik@redshift-software.com> Sat, 01 Oct 2005 00:00:00 +0000 - -bjam (3.1.11-1) unstable; urgency=low - - * New upstream release. - - -- Rene Rivera <grafik@redshift-software.com> Sat, 30 Apr 2005 00:00:00 +0000 - -bjam (3.1.10-1) unstable; urgency=low - - * New upstream release. - - -- Rene Rivera <grafik@redshift-software.com> Tue, 1 Jun 2004 05:42:35 +0000 - -bjam (3.1.9-2) unstable; urgency=low - - * Use default value of BOOST_BUILD_PATH is not is set in environment. - - -- Vladimir Prus <ghost@zigzag.lvk.cs.msu.su> Wed, 17 Dec 2003 16:44:35 +0300 - -bjam (3.1.9-1) unstable; urgency=low - - * Implement NATIVE_FILE builtin and several native rules. - - -- Vladimir Prus <ghost@zigzag.lvk.cs.msu.su> Thu, 11 Dec 2003 13:15:26 +0300 - -bjam (3.1.8-1) unstable; urgency=low - - * New upstream release. - - -- Vladimir Prus <ghost@zigzag.lvk.cs.msu.su> Tue, 4 Nov 2003 20:50:43 +0300 - -bjam (3.1.7-1) unstable; urgency=low - - * New upstream release. - - -- Vladimir Prus <ghost@zigzag.lvk.cs.msu.su> Thu, 11 Sep 2003 10:45:44 +0400 - -bjam (3.1.6-1) unstable; urgency=low - - * New upstream release. - - -- Vladimir Prus <ghost@zigzag.lvk.cs.msu.su> Tue, 1 Jul 2003 09:12:18 +0400 - -bjam (3.1.5-1) unstable; urgency=low - - * New upstream release. - - -- Vladimir Prus <ghost@zigzag.lvk.cs.msu.su> Mon, 19 May 2003 14:05:13 +0400 - -bjam (3.1.3-2) unstable; urgency=low - - * Changed Debian package to be similar to Jam's package. - - -- Vladimir Prus <ghost@cs.msu.su> Thu, 10 Oct 2002 18:43:26 +0400 - -bjam (3.1.3-1) unstable; urgency=low - - * New upstream release. - - -- Vladimir Prus <ghost@zigzag.lvk.cs.msu.su> Fri, 4 Oct 2002 18:16:54 +0400 - -bjam (3.1.2-1) unstable; urgency=low - - * Initial Release. - - -- Vladimir Prus <ghost@cs.msu.su> Wed, 14 Aug 2002 14:08:00 +0400 - diff --git a/jam-files/engine/debian/control b/jam-files/engine/debian/control deleted file mode 100644 index c7f15193..00000000 --- a/jam-files/engine/debian/control +++ /dev/null @@ -1,16 +0,0 @@ -Source: bjam -Section: devel -Priority: optional -Maintainer: Vladimir Prus <ghost@cs.msu.su> -Build-Depends: debhelper (>> 3.0.0), docbook-to-man, bison -Standards-Version: 3.5.2 - -Package: bjam -Architecture: any -Depends: ${shlibs:Depends} -Description: Build tool - Boost.Jam is a portable build tool with its own interpreted language, which - allows to implement rather complex logic in a readable way and without - resorting to external programs. It is a descendant of Jam/MR tool modified to - suit the needs of Boost.Build. In particular, modules and rule parameters - were added, as well as several new builtins. diff --git a/jam-files/engine/debian/copyright b/jam-files/engine/debian/copyright deleted file mode 100644 index f72e4e3a..00000000 --- a/jam-files/engine/debian/copyright +++ /dev/null @@ -1,25 +0,0 @@ -This package was debianized by Vladimir Prus <ghost@cs.msu.su> on -Wed, 17 July 2002, 19:27:00 +0400. - -Copyright: - - /+\ - +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - \+/ - - This is Release 2.4 of Jam/MR, 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. - -Some portions are also: - - Copyright 2001-2006 David Abrahams. - Copyright 2002-2006 Rene Rivera. - Copyright 2003-2006 Vladimir Prus. - - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) diff --git a/jam-files/engine/debian/jam.man.sgml b/jam-files/engine/debian/jam.man.sgml deleted file mode 100644 index ee21d4d8..00000000 --- a/jam-files/engine/debian/jam.man.sgml +++ /dev/null @@ -1,236 +0,0 @@ -<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [ - -<!-- Process this file with docbook-to-man to generate an nroff manual - page: `docbook-to-man manpage.sgml > manpage.1'. You may view - the manual page with: `docbook-to-man manpage.sgml | nroff -man | - less'. A typical entry in a Makefile or Makefile.am is: - -manpage.1: manpage.sgml - docbook-to-man $< > $@ - --> - - <!ENTITY dhfirstname "<firstname>Yann</firstname>"> - <!ENTITY dhsurname "<surname>Dirson</surname>"> - <!-- Please adjust the date whenever revising the manpage. --> - <!ENTITY dhdate "<date>mai 23, 2001</date>"> - <!ENTITY dhemail "<email>dirson@debian.org</email>"> - <!ENTITY dhusername "Yann Dirson"> - <!ENTITY dhpackage "jam"> - - <!ENTITY debian "<productname>Debian GNU/Linux</productname>"> - <!ENTITY gnu "<acronym>GNU</acronym>"> -]> - -<refentry> - <refentryinfo> - <address> - &dhemail; - </address> - <author> - &dhfirstname; - &dhsurname; - </author> - <copyright> - <year>2001</year> - <holder>&dhusername;</holder> - </copyright> - &dhdate; - </refentryinfo> - - <refmeta> - <refentrytitle>JAM</refentrytitle> - <manvolnum>1</manvolnum> - </refmeta> - - <refnamediv> - <refname>Jam/MR</refname> - <refpurpose>Make(1) Redux</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis> - <command>jam</command> - - <arg><option>-a</option></arg> - <arg><option>-n</option></arg> - <arg><option>-v</option></arg> - - <arg><option>-d <replaceable/debug/</option></arg> - <arg><option>-f <replaceable/jambase/</option></arg> - <arg><option>-j <replaceable/jobs/</option></arg> - <arg><option>-o <replaceable/actionsfile/</option></arg> - <arg><option>-s <replaceable/var/=<replaceable/value/</option></arg> - <arg><option>-t <replaceable/target/</option></arg> - - <arg repeat><option><replaceable/target/</option></arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1> - <title>DESCRIPTION</title> - - <para>Jam is a program construction tool, like make(1).</para> - - <para>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.</para> - </refsect1> - - <refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term><option/-a/</term> - <listitem> - <para>Build all targets anyway, even if they are up-to-date.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-d <replaceable/n/</option></term> - <listitem> - <para>Enable cummulative debugging levels from 1 to - <replaceable/n/. Interesting values are: - - <glosslist> - <glossentry><glossterm/1/ <glossdef><simpara/Show - actions (the default)/</glossdef></glossentry> - - <glossentry><glossterm/2/ <glossdef><simpara/Show - "quiet" actions and display all action - text/</glossdef></glossentry> - - <glossentry><glossterm/3/ <glossdef><simpara>Show - dependency analysis, and target/source - timestamps/paths</simpara></glossdef></glossentry> - - <glossentry><glossterm/4/ <glossdef><simpara/Show shell - arguments/</glossdef></glossentry> - - <glossentry><glossterm/5/ <glossdef><simpara/Show rule - invocations and variable - expansions/</glossdef></glossentry> - - <glossentry><glossterm/6/ <glossdef><simpara>Show - directory/header file/archive - scans</simpara></glossdef></glossentry> - - <glossentry><glossterm/7/ <glossdef><simpara/Show - variable settings/</glossdef></glossentry> - - <glossentry><glossterm/8/ <glossdef><simpara/Show - variable fetches/</glossdef></glossentry> - - <glossentry><glossterm/9/ <glossdef><simpara/Show - variable manipulation, scanner - tokens/</glossdef></glossentry> - </glosslist> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-d +<replaceable/n/</option></term> - <listitem> - <para>Enable debugging level <replaceable/n/.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option/-d 0/</term> - <listitem> - <para>Turn off all debugging levels. Only errors are not - suppressed.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-f <replaceable/jambase/</option></term> - <listitem> - <para>Read <replaceable/jambase/ instead of using the - built-in Jambase. Only one <option/-f/ flag is permitted, - but the <replaceable/jambase/ may explicitly include other - files.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-j <replaceable/n/</option></term> - <listitem> - <para>Run up to <replaceable/n/ shell commands concurrently - (UNIX and NT only). The default is 1.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option/-n/</term> - <listitem> - <para>Don't actually execute the updating actions, but do - everything else. This changes the debug level default to - <option/-d2/.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-o <replaceable/file/</option></term> - <listitem> - <para>Write the updating actions to the specified file - instead of running them (or outputting them, as on the - Mac).</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-s <replaceable/var/=<replaceable/value/</option></term> - <listitem> - <para>Set the variable <replaceable/var/ to - <replaceable/value/, overriding both internal variables and - variables imported from the environment. </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-t <replaceable/target/</option></term> - <listitem> - <para>Rebuild <replaceable/target/ and everything that - depends on it, even if it is up-to-date.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option/-v/</term> - <listitem> - <para>Print the version of jam and exit.</para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1> - <title>SEE ALSO</title> - - <para>Jam is documented fully in HTML pages available on Debian - systems from - <filename>/usr/share/doc/jam/Jam.html</filename>.</para> - </refsect1> - - <refsect1> - <title>AUTHOR</title> - - <para>This manual page was created by &dhusername; &dhemail; from - the <filename/Jam.html/ documentation, for the &debian; system - (but may be used by others).</para> - </refsect1> -</refentry> - -<!-- Keep this comment at the end of the file -Local variables: -sgml-omittag:t -sgml-shorttag:t -End: ---> diff --git a/jam-files/engine/debian/rules b/jam-files/engine/debian/rules deleted file mode 100755 index 756052a3..00000000 --- a/jam-files/engine/debian/rules +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/make -f -# Sample debian/rules that uses debhelper. -# GNU copyright 1997 to 1999 by Joey Hess. -# GNU copyright 2001 by Yann Dirson. - -# This is the debian/rules file for packages jam and ftjam -# It should be usable with both packages without any change - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -# This is the debhelper compatability version to use. -export DH_COMPAT=3 - -topdir=$(shell pwd) - -jam=bjam -binname=bjam - -build: build-stamp -build-stamp: debian/jam.1 - dh_testdir - - ./build.sh - - touch build-stamp - -%.1: %.man.sgml - /usr/bin/docbook-to-man $< > $@ - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - rm -rf bin.* - rm -f jam0 debian/jam.1 - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - install -d ${topdir}/debian/${jam}/usr/bin - install -m755 bin.linuxx86/bjam ${topdir}/debian/${jam}/usr/bin/ - install -d ${topdir}/debian/${jam}/usr/share/man/man1/ - install -m644 debian/jam.1 ${topdir}/debian/${jam}/usr/share/man/man1/${binname}.1 - - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installdocs README RELNOTES Jambase *.html -# dh_installemacsen -# dh_undocumented - dh_installchangelogs - dh_strip - dh_compress - dh_fixperms - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/jam-files/engine/debug.c b/jam-files/engine/debug.c deleted file mode 100644 index 7290555a..00000000 --- a/jam-files/engine/debug.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - Copyright Rene Rivera 2005. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -*/ - -#include "jam.h" - -#include "hash.h" - -#include <time.h> -#include <assert.h> - - -static profile_frame * profile_stack = 0; -static struct hash * profile_hash = 0; -static profile_info profile_other = { "[OTHER]", 0, 0, 0, 0, 0 }; -static profile_info profile_total = { "[TOTAL]", 0, 0, 0, 0, 0 }; - - -profile_frame * profile_init( char * rulename, profile_frame * frame ) -{ - if ( DEBUG_PROFILE ) profile_enter( rulename, frame ); - return frame; -} - - -void profile_enter( char * rulename, profile_frame * frame ) -{ - if ( DEBUG_PROFILE ) - { - clock_t start = clock(); - profile_info info; - profile_info * p = &info; - - if ( !rulename ) p = &profile_other; - - if ( !profile_hash && rulename ) - profile_hash = hashinit( sizeof( profile_info ), "profile" ); - - info.name = rulename; - - if ( rulename && hashenter( profile_hash, (HASHDATA * *)&p ) ) - p->cumulative = p->net = p->num_entries = p->stack_count = p->memory = 0; - - ++p->num_entries; - ++p->stack_count; - - frame->info = p; - - frame->caller = profile_stack; - profile_stack = frame; - - frame->entry_time = clock(); - frame->overhead = 0; - frame->subrules = 0; - - /* caller pays for the time it takes to play with the hash table */ - if ( frame->caller ) - frame->caller->overhead += frame->entry_time - start; - } -} - - -void profile_memory( long mem ) -{ - if ( DEBUG_PROFILE ) - if ( profile_stack && profile_stack->info ) - profile_stack->info->memory += mem; -} - - -void profile_exit( profile_frame * frame ) -{ - if ( DEBUG_PROFILE ) - { - /* Cumulative time for this call. */ - clock_t t = clock() - frame->entry_time - frame->overhead; - /* If this rule is already present on the stack, don't add the time for - * this instance. - */ - if ( frame->info->stack_count == 1 ) - frame->info->cumulative += t; - /* Net time does not depend on presense of the same rule in call stack. - */ - frame->info->net += t - frame->subrules; - - if ( frame->caller ) - { - /* Caller's cumulative time must account for this overhead. */ - frame->caller->overhead += frame->overhead; - frame->caller->subrules += t; - } - /* Pop this stack frame. */ - --frame->info->stack_count; - profile_stack = frame->caller; - } -} - - -static void dump_profile_entry( void * p_, void * ignored ) -{ - profile_info * p = (profile_info *)p_; - unsigned long mem_each = ( p->memory / ( p->num_entries ? p->num_entries : 1 ) ); - double cumulative = p->cumulative; - double net = p->net; - double q = p->net; - q /= ( p->num_entries ? p->num_entries : 1 ); - cumulative /= CLOCKS_PER_SEC; - net /= CLOCKS_PER_SEC; - q /= CLOCKS_PER_SEC; - if ( !ignored ) - { - profile_total.cumulative += p->net; - profile_total.memory += p->memory; - } - printf( "%10ld %12.6f %12.6f %12.8f %10ld %10ld %s\n", p->num_entries, - cumulative, net, q, p->memory, mem_each, p->name ); -} - - -void profile_dump() -{ - if ( profile_hash ) - { - printf( "%10s %12s %12s %12s %10s %10s %s\n", "--count--", "--gross--", - "--net--", "--each--", "--mem--", "--each--", "--name--" ); - hashenumerate( profile_hash, dump_profile_entry, 0 ); - dump_profile_entry( &profile_other, 0 ); - dump_profile_entry( &profile_total, (void *)1 ); - } -} diff --git a/jam-files/engine/debug.h b/jam-files/engine/debug.h deleted file mode 100644 index 115a8873..00000000 --- a/jam-files/engine/debug.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright Rene Rivera 2005. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -*/ -#ifndef BJAM_DEBUG_H -#define BJAM_DEBUG_H - -#include "jam.h" -#include <time.h> - - -struct profile_info -{ - /* name of rule being called */ - char* name; - /* cumulative time spent in rule */ - clock_t cumulative; - /* time spent in rule proper */ - clock_t net; - /* number of time rule was entered */ - unsigned long num_entries; - /* number of the times this function is present in stack */ - unsigned long stack_count; - /* bytes of memory allocated by the call */ - unsigned long memory; -}; -typedef struct profile_info profile_info; - -struct profile_frame -{ - /* permanent storage where data accumulates */ - profile_info* info; - /* overhead for profiling in this call */ - clock_t overhead; - /* time of last entry to rule */ - clock_t entry_time; - /* stack frame of caller */ - struct profile_frame* caller; - /* time spent in subrules */ - clock_t subrules; -}; -typedef struct profile_frame profile_frame; - -profile_frame * profile_init( char * rulename, profile_frame * frame ); -void profile_enter( char* rulename, profile_frame * frame ); -void profile_memory( long mem ); -void profile_exit( profile_frame * frame ); -void profile_dump(); - -#define PROFILE_ENTER( scope ) profile_frame PROF_ ## scope, *PROF_ ## scope ## _p = profile_init( #scope, &PROF_ ## scope ) -#define PROFILE_EXIT( scope ) profile_exit( PROF_ ## scope ## _p ) - -#endif diff --git a/jam-files/engine/execcmd.h b/jam-files/engine/execcmd.h deleted file mode 100644 index 67f2b839..00000000 --- a/jam-files/engine/execcmd.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * execcmd.h - execute a shell script. - * - * Defines the interface to be implemented in platform specific implementation - * modules. - * - * 05/04/94 (seiwald) - async multiprocess interface - */ - -#ifndef EXECCMD_H -#define EXECCMD_H - -#include <time.h> - -typedef struct timing_info -{ - double system; - double user; - time_t start; - time_t end; -} timing_info; - -void exec_cmd -( - char * string, - void (* func)( void * closure, int status, timing_info *, char *, char * ), - void * closure, - LIST * shell, - char * action, - char * target -); - -int exec_wait(); - -#define EXEC_CMD_OK 0 -#define EXEC_CMD_FAIL 1 -#define EXEC_CMD_INTR 2 - -#endif diff --git a/jam-files/engine/execmac.c b/jam-files/engine/execmac.c deleted file mode 100644 index 2ddddedd..00000000 --- a/jam-files/engine/execmac.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 <errno.h> - -#ifdef OS_MAC - -/* - * 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: - * exec_cmd() - launch an async command execution. - * exec_wait() - 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 - */ - - -/* - * exec_cmd() - launch an async command execution. - */ - -void exec_cmd -( - char * string, - void (* func)( void * closure, int status, timing_info *, char *, char * ), - void * closure, - LIST * shell -) -{ - printf( "%s", string ); - (*func)( closure, EXEC_CMD_OK ); -} - -/* - * exec_wait() - wait and drive at most one execution completion. - */ - -int exec_wait() -{ - return 0; -} - -#endif /* OS_MAC */ diff --git a/jam-files/engine/execnt.c b/jam-files/engine/execnt.c deleted file mode 100644 index 76420451..00000000 --- a/jam-files/engine/execnt.c +++ /dev/null @@ -1,1296 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Copyright 2007 Rene Rivera. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -#include "jam.h" -#include "lists.h" -#include "execcmd.h" -#include "pathsys.h" -#include "string.h" -#include "output.h" -#include <errno.h> -#include <assert.h> -#include <ctype.h> -#include <time.h> -#include <math.h> - -#ifdef USE_EXECNT - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <process.h> -#include <tlhelp32.h> - -/* - * execnt.c - execute a shell command on Windows NT - * - * 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: - * exec_cmd() - launch an async command execution. - * exec_wait() - 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 - */ - -/* get the maximum command line length according to the OS */ -int maxline(); - -/* delete and argv list */ -static void free_argv(char**); -/* Convert a command string into arguments for spawnvp. */ -static char** string_to_args(const char*); -/* bump intr to note command interruption */ -static void onintr(int); -/* If the command is suitable for execution via spawnvp */ -long can_spawn(char*); -/* Add two 64-bit unsigned numbers, h1l1 and h2l2 */ -static FILETIME add_64( - unsigned long h1, unsigned long l1, - unsigned long h2, unsigned long l2); -static FILETIME add_FILETIME(FILETIME t1, FILETIME t2); -static FILETIME negate_FILETIME(FILETIME t); -/* Convert a FILETIME to a number of seconds */ -static double filetime_seconds(FILETIME t); -/* record the timing info for the process */ -static void record_times(HANDLE, timing_info*); -/* calc the current running time of an *active* process */ -static double running_time(HANDLE); -/* */ -DWORD get_process_id(HANDLE); -/* terminate the given process, after terminating all its children */ -static void kill_process_tree(DWORD, HANDLE); -/* waits for a command to complete or for the given timeout, whichever is first */ -static int try_wait(int timeoutMillis); -/* reads any pending output for running commands */ -static void read_output(); -/* checks if a command ran out of time, and kills it */ -static int try_kill_one(); -/* */ -static double creation_time(HANDLE); -/* Recursive check if first process is parent (directly or indirectly) of -the second one. */ -static int is_parent_child(DWORD, DWORD); -/* */ -static void close_alert(HANDLE); -/* close any alerts hanging around */ -static void close_alerts(); - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -static int intr = 0; -static int cmdsrunning = 0; -static void (* istat)( int ); - - -/* The list of commands we run. */ -static struct -{ - string action; /* buffer to hold action */ - string target; /* buffer to hold target */ - string command; /* buffer to hold command being invoked */ - - /* Temporary batch file used to execute the action when needed. */ - char * tempfile_bat; - - /* Pipes for communicating with the child process. Parent reads from (0), - * child writes to (1). - */ - HANDLE pipe_out[ 2 ]; - HANDLE pipe_err[ 2 ]; - - string buffer_out; /* buffer to hold stdout, if any */ - string buffer_err; /* buffer to hold stderr, if any */ - - PROCESS_INFORMATION pi; /* running process information */ - DWORD exit_code; /* executed command's exit code */ - int exit_reason; /* reason why a command completed */ - - /* Function called when the command completes. */ - void (* func)( void * closure, int status, timing_info *, char *, char * ); - - /* Opaque data passed back to the 'func' callback called when the command - * completes. - */ - void * closure; -} -cmdtab[ MAXJOBS ] = { { 0 } }; - - -/* - * Execution unit tests. - */ - -void execnt_unit_test() -{ -#if !defined( NDEBUG ) - /* vc6 preprocessor is broken, so assert with these strings gets confused. - * Use a table instead. - */ - typedef struct test { char * command; int result; } test; - test tests[] = { - { "x", 0 }, - { "x\n ", 0 }, - { "x\ny", 1 }, - { "x\n\n y", 1 }, - { "echo x > foo.bar", 1 }, - { "echo x < foo.bar", 1 }, - { "echo x \">\" foo.bar", 0 }, - { "echo x \"<\" foo.bar", 0 }, - { "echo x \\\">\\\" foo.bar", 1 }, - { "echo x \\\"<\\\" foo.bar", 1 } }; - int i; - for ( i = 0; i < sizeof( tests ) / sizeof( *tests ); ++i ) - assert( !can_spawn( tests[ i ].command ) == tests[ i ].result ); - - { - char * long_command = BJAM_MALLOC_ATOMIC( MAXLINE + 10 ); - assert( long_command != 0 ); - memset( long_command, 'x', MAXLINE + 9 ); - long_command[ MAXLINE + 9 ] = 0; - assert( can_spawn( long_command ) == MAXLINE + 9 ); - BJAM_FREE( long_command ); - } - - { - /* Work around vc6 bug; it doesn't like escaped string - * literals inside assert - */ - char * * argv = string_to_args(" \"g++\" -c -I\"Foobar\"" ); - char const expected[] = "-c -I\"Foobar\""; - - assert( !strcmp( argv[ 0 ], "g++" ) ); - assert( !strcmp( argv[ 1 ], expected ) ); - free_argv( argv ); - } -#endif -} - - -/* - * exec_cmd() - launch an async command execution. - */ - -void exec_cmd -( - char * command, - void (* func)( void * closure, int status, timing_info *, char * invoked_command, char * command_output ), - void * closure, - LIST * shell, - char * action, - char * target -) -{ - int slot; - int raw_cmd = 0 ; - char * argv_static[ MAXARGC + 1 ]; /* +1 for NULL */ - char * * argv = argv_static; - char * p; - char * command_orig = command; - - /* Check to see if we need to hack around the line-length limitation. Look - * for a JAMSHELL setting of "%", indicating that the command should be - * invoked directly. - */ - if ( shell && !strcmp( shell->string, "%" ) && !list_next( shell ) ) - { - raw_cmd = 1; - shell = 0; - } - - /* Find a slot in the running commands table for this one. */ - for ( slot = 0; slot < MAXJOBS; ++slot ) - if ( !cmdtab[ slot ].pi.hProcess ) - break; - if ( slot == MAXJOBS ) - { - printf( "no slots for child!\n" ); - exit( EXITBAD ); - } - - /* Compute the name of a temp batch file, for possible use. */ - if ( !cmdtab[ slot ].tempfile_bat ) - { - char const * tempdir = path_tmpdir(); - DWORD procID = GetCurrentProcessId(); - - /* SVA - allocate 64 bytes extra just to be safe. */ - cmdtab[ slot ].tempfile_bat = BJAM_MALLOC_ATOMIC( strlen( tempdir ) + 64 ); - - sprintf( cmdtab[ slot ].tempfile_bat, "%s\\jam%d-%02d.bat", - tempdir, procID, slot ); - } - - /* Trim leading, -ending- white space */ - while ( *( command + 1 ) && isspace( *command ) ) - ++command; - - /* Write to .BAT file unless the line would be too long and it meets the - * other spawnability criteria. - */ - if ( raw_cmd && ( can_spawn( command ) >= MAXLINE ) ) - { - if ( DEBUG_EXECCMD ) - printf("Executing raw command directly\n"); - } - else - { - FILE * f = 0; - int tries = 0; - raw_cmd = 0; - - /* Write command to bat file. For some reason this open can fail - * intermitently. But doing some retries works. Most likely this is due - * to a previously existing file of the same name that happens to be - * opened by an active virus scanner. Pointed out and fixed by Bronek - * Kozicki. - */ - for ( ; !f && ( tries < 4 ); ++tries ) - { - f = fopen( cmdtab[ slot ].tempfile_bat, "w" ); - if ( !f && ( tries < 4 ) ) Sleep( 250 ); - } - if ( !f ) - { - printf( "failed to write command file!\n" ); - exit( EXITBAD ); - } - fputs( command, f ); - fclose( f ); - - command = cmdtab[ slot ].tempfile_bat; - - if ( DEBUG_EXECCMD ) - { - if ( shell ) - printf( "using user-specified shell: %s", shell->string ); - else - printf( "Executing through .bat file\n" ); - } - } - - /* Formulate argv; If shell was defined, be prepared for % and ! subs. - * Otherwise, use stock cmd.exe. - */ - 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 ] = command; ++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++ ] = command; - - argv[ i ] = 0; - } - else if ( raw_cmd ) - { - argv = string_to_args( command ); - } - else - { - argv[ 0 ] = "cmd.exe"; - argv[ 1 ] = "/Q/C"; /* anything more is non-portable */ - argv[ 2 ] = command; - argv[ 3 ] = 0; - } - - /* Catch interrupts whenever commands are running. */ - if ( !cmdsrunning++ ) - istat = signal( SIGINT, onintr ); - - /* Start the command. */ - { - SECURITY_ATTRIBUTES sa - = { sizeof( SECURITY_ATTRIBUTES ), 0, 0 }; - SECURITY_DESCRIPTOR sd; - STARTUPINFO si - = { sizeof( STARTUPINFO ), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - string cmd; - - /* Init the security data. */ - InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ); - SetSecurityDescriptorDacl( &sd, TRUE, NULL, FALSE ); - sa.lpSecurityDescriptor = &sd; - sa.bInheritHandle = TRUE; - - /* Create the stdout, which is also the merged out + err, pipe. */ - if ( !CreatePipe( &cmdtab[ slot ].pipe_out[ 0 ], - &cmdtab[ slot ].pipe_out[ 1 ], &sa, 0 ) ) - { - perror( "CreatePipe" ); - exit( EXITBAD ); - } - - /* Create the stdout, which is also the merged out+err, pipe. */ - if ( globs.pipe_action == 2 ) - { - if ( !CreatePipe( &cmdtab[ slot ].pipe_err[ 0 ], - &cmdtab[ slot ].pipe_err[ 1 ], &sa, 0 ) ) - { - perror( "CreatePipe" ); - exit( EXITBAD ); - } - } - - /* Set handle inheritance off for the pipe ends the parent reads from. */ - SetHandleInformation( cmdtab[ slot ].pipe_out[ 0 ], HANDLE_FLAG_INHERIT, 0 ); - if ( globs.pipe_action == 2 ) - SetHandleInformation( cmdtab[ slot ].pipe_err[ 0 ], HANDLE_FLAG_INHERIT, 0 ); - - /* Hide the child window, if any. */ - si.dwFlags |= STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; - - /* Set the child outputs to the pipes. */ - si.dwFlags |= STARTF_USESTDHANDLES; - si.hStdOutput = cmdtab[ slot ].pipe_out[ 1 ]; - if ( globs.pipe_action == 2 ) - { - /* Pipe stderr to the action error output. */ - si.hStdError = cmdtab[ slot ].pipe_err[ 1 ]; - } - else if ( globs.pipe_action == 1 ) - { - /* Pipe stderr to the console error output. */ - si.hStdError = GetStdHandle( STD_ERROR_HANDLE ); - } - else - { - /* Pipe stderr to the action merged output. */ - si.hStdError = cmdtab[ slot ].pipe_out[ 1 ]; - } - - /* Let the child inherit stdin, as some commands assume it's available. */ - si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - - /* Save the operation for exec_wait() to find. */ - cmdtab[ slot ].func = func; - cmdtab[ slot ].closure = closure; - if ( action && target ) - { - string_copy( &cmdtab[ slot ].action, action ); - string_copy( &cmdtab[ slot ].target, target ); - } - else - { - string_free( &cmdtab[ slot ].action ); - string_new ( &cmdtab[ slot ].action ); - string_free( &cmdtab[ slot ].target ); - string_new ( &cmdtab[ slot ].target ); - } - string_copy( &cmdtab[ slot ].command, command_orig ); - - /* Put together the command we run. */ - { - char * * argp = argv; - string_new( &cmd ); - string_copy( &cmd, *(argp++) ); - while ( *argp ) - { - string_push_back( &cmd, ' ' ); - string_append( &cmd, *(argp++) ); - } - } - - /* Create output buffers. */ - string_new( &cmdtab[ slot ].buffer_out ); - string_new( &cmdtab[ slot ].buffer_err ); - - /* Run the command by creating a sub-process for it. */ - if ( - ! CreateProcess( - NULL , /* application name */ - cmd.value , /* command line */ - NULL , /* process attributes */ - NULL , /* thread attributes */ - TRUE , /* inherit handles */ - CREATE_NEW_PROCESS_GROUP, /* create flags */ - NULL , /* env vars, null inherits env */ - NULL , /* current dir, null is our */ - /* current dir */ - &si , /* startup info */ - &cmdtab[ slot ].pi /* child process info, if created */ - ) - ) - { - perror( "CreateProcess" ); - exit( EXITBAD ); - } - - /* Clean up temporary stuff. */ - string_free( &cmd ); - } - - /* Wait until we are under the limit of concurrent commands. Do not trust - * globs.jobs alone. - */ - while ( ( cmdsrunning >= MAXJOBS ) || ( cmdsrunning >= globs.jobs ) ) - if ( !exec_wait() ) - break; - - if ( argv != argv_static ) - free_argv( argv ); -} - - -/* - * exec_wait() - * * wait and drive at most one execution completion. - * * waits for one command to complete, while processing the i/o for all - * ongoing commands. - * - * Returns 0 if called when there were no more commands being executed or 1 - * otherwise. - */ - -int exec_wait() -{ - int i = -1; - - /* Handle naive make1() which does not know if cmds are running. */ - if ( !cmdsrunning ) - return 0; - - /* Wait for a command to complete, while snarfing up any output. */ - do - { - /* Check for a complete command, briefly. */ - i = try_wait(500); - /* Read in the output of all running commands. */ - read_output(); - /* Close out pending debug style dialogs. */ - close_alerts(); - /* Check if a command ran out of time. */ - if ( i < 0 ) i = try_kill_one(); - } - while ( i < 0 ); - - /* We have a command... process it. */ - --cmdsrunning; - { - timing_info time; - int rstat; - - /* The time data for the command. */ - record_times( cmdtab[ i ].pi.hProcess, &time ); - - /* Clear the temp file. */ - if ( cmdtab[ i ].tempfile_bat ) - { - unlink( cmdtab[ i ].tempfile_bat ); - BJAM_FREE( cmdtab[ i ].tempfile_bat ); - cmdtab[ i ].tempfile_bat = NULL; - } - - /* Find out the process exit code. */ - GetExitCodeProcess( cmdtab[ i ].pi.hProcess, &cmdtab[ i ].exit_code ); - - /* The dispossition of the command. */ - if ( intr ) - rstat = EXEC_CMD_INTR; - else if ( cmdtab[ i ].exit_code != 0 ) - rstat = EXEC_CMD_FAIL; - else - rstat = EXEC_CMD_OK; - - /* Output the action block. */ - out_action( - cmdtab[ i ].action.size > 0 ? cmdtab[ i ].action.value : 0, - cmdtab[ i ].target.size > 0 ? cmdtab[ i ].target.value : 0, - cmdtab[ i ].command.size > 0 ? cmdtab[ i ].command.value : 0, - cmdtab[ i ].buffer_out.size > 0 ? cmdtab[ i ].buffer_out.value : 0, - cmdtab[ i ].buffer_err.size > 0 ? cmdtab[ i ].buffer_err.value : 0, - cmdtab[ i ].exit_reason ); - - /* Call the callback, may call back to jam rule land. Assume -p0 in - * effect so only pass buffer containing merged output. - */ - (*cmdtab[ i ].func)( - cmdtab[ i ].closure, - rstat, - &time, - cmdtab[ i ].command.value, - cmdtab[ i ].buffer_out.value ); - - /* Clean up the command data, process, etc. */ - string_free( &cmdtab[ i ].action ); string_new( &cmdtab[ i ].action ); - string_free( &cmdtab[ i ].target ); string_new( &cmdtab[ i ].target ); - string_free( &cmdtab[ i ].command ); string_new( &cmdtab[ i ].command ); - if ( cmdtab[ i ].pi.hProcess ) { CloseHandle( cmdtab[ i ].pi.hProcess ); cmdtab[ i ].pi.hProcess = 0; } - if ( cmdtab[ i ].pi.hThread ) { CloseHandle( cmdtab[ i ].pi.hThread ); cmdtab[ i ].pi.hThread = 0; } - if ( cmdtab[ i ].pipe_out[ 0 ] ) { CloseHandle( cmdtab[ i ].pipe_out[ 0 ] ); cmdtab[ i ].pipe_out[ 0 ] = 0; } - if ( cmdtab[ i ].pipe_out[ 1 ] ) { CloseHandle( cmdtab[ i ].pipe_out[ 1 ] ); cmdtab[ i ].pipe_out[ 1 ] = 0; } - if ( cmdtab[ i ].pipe_err[ 0 ] ) { CloseHandle( cmdtab[ i ].pipe_err[ 0 ] ); cmdtab[ i ].pipe_err[ 0 ] = 0; } - if ( cmdtab[ i ].pipe_err[ 1 ] ) { CloseHandle( cmdtab[ i ].pipe_err[ 1 ] ); cmdtab[ i ].pipe_err[ 1 ] = 0; } - string_free( &cmdtab[ i ].buffer_out ); string_new( &cmdtab[ i ].buffer_out ); - string_free( &cmdtab[ i ].buffer_err ); string_new( &cmdtab[ i ].buffer_err ); - cmdtab[ i ].exit_code = 0; - cmdtab[ i ].exit_reason = EXIT_OK; - } - - return 1; -} - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -static void free_argv( char * * args ) -{ - BJAM_FREE( args[ 0 ] ); - BJAM_FREE( args ); -} - - -/* - * For more details on Windows cmd.exe shell command-line length limitations see - * the following MSDN article: - * http://support.microsoft.com/default.aspx?scid=kb;en-us;830473 - */ - -int maxline() -{ - OSVERSIONINFO os_info; - os_info.dwOSVersionInfoSize = sizeof( os_info ); - GetVersionEx( &os_info ); - - if ( os_info.dwMajorVersion >= 5 ) return 8191; /* XP > */ - if ( os_info.dwMajorVersion == 4 ) return 2047; /* NT 4.x */ - return 996; /* NT 3.5.1 */ -} - - -/* - * Convert a command string into arguments for spawnvp(). The original code, - * inherited from ftjam, tried to break up every argument on the command-line, - * dealing with quotes, but that is really a waste of time on Win32, at least. - * It turns out that all you need to do is get the raw path to the executable in - * the first argument to spawnvp(), and you can pass all the rest of the - * command-line arguments to spawnvp() in one, un-processed string. - * - * New strategy: break the string in at most one place. - */ - -static char * * string_to_args( char const * string ) -{ - int src_len; - int in_quote; - char * line; - char const * src; - char * dst; - char * * argv; - - /* Drop leading and trailing whitespace if any. */ - while ( isspace( *string ) ) - ++string; - - src_len = strlen( string ); - while ( ( src_len > 0 ) && isspace( string[ src_len - 1 ] ) ) - --src_len; - - /* Copy the input string into a buffer we can modify. */ - line = (char *)BJAM_MALLOC_ATOMIC( src_len + 1 ); - if ( !line ) - return 0; - - /* Allocate the argv array. - * element 0: stores the path to the executable - * element 1: stores the command-line arguments to the executable - * element 2: NULL terminator - */ - argv = (char * *)BJAM_MALLOC( 3 * sizeof( char * ) ); - if ( !argv ) - { - BJAM_FREE( line ); - return 0; - } - - /* Strip quotes from the first command-line argument and find where it ends. - * Quotes are illegal in Win32 pathnames, so we do not need to worry about - * preserving escaped quotes here. Spaces can not be escaped in Win32, only - * enclosed in quotes, so removing backslash escapes is also a non-issue. - */ - in_quote = 0; - for ( src = string, dst = line ; *src; ++src ) - { - if ( *src == '"' ) - in_quote = !in_quote; - else if ( !in_quote && isspace( *src ) ) - break; - else - *dst++ = *src; - } - *dst++ = 0; - argv[ 0 ] = line; - - /* Skip whitespace in src. */ - while ( isspace( *src ) ) - ++src; - - argv[ 1 ] = dst; - - /* Copy the rest of the arguments verbatim. */ - src_len -= src - string; - - /* Use strncat() because it appends a trailing nul. */ - *dst = 0; - strncat( dst, src, src_len ); - - argv[ 2 ] = 0; - - return argv; -} - - -static void onintr( int disp ) -{ - ++intr; - printf( "...interrupted\n" ); -} - - -/* - * can_spawn() - If the command is suitable for execution via spawnvp(), return - * a number >= the number of characters it would occupy on the command-line. - * Otherwise, return zero. - */ - -long can_spawn( char * command ) -{ - char * p; - char inquote = 0; - - /* Move to the first non-whitespace. */ - command += strspn( command, " \t" ); - - p = command; - - /* Look for newlines and unquoted i/o redirection. */ - do - { - p += strcspn( p, "'\n\"<>|" ); - - switch ( *p ) - { - case '\n': - /* Skip over any following spaces. */ - while ( isspace( *p ) ) - ++p; - /* Must use a .bat file if there is anything significant following - * the newline. - */ - if ( *p ) - return 0; - break; - - case '"': - case '\'': - if ( ( p > command ) && ( p[ -1 ] != '\\' ) ) - { - if ( inquote == *p ) - inquote = 0; - else if ( inquote == 0 ) - inquote = *p; - } - ++p; - break; - - case '<': - case '>': - case '|': - if ( !inquote ) - return 0; - ++p; - break; - } - } - while ( *p ); - - /* Return the number of characters the command will occupy. */ - return p - command; -} - - -/* 64-bit arithmetic helpers. */ - -/* Compute the carry bit from the addition of two 32-bit unsigned numbers. */ -#define add_carry_bit( a, b ) ( (((a) | (b)) >> 31) & (~((a) + (b)) >> 31) & 0x1 ) - -/* Compute the high 32 bits of the addition of two 64-bit unsigned numbers, h1l1 and h2l2. */ -#define add_64_hi( h1, l1, h2, l2 ) ((h1) + (h2) + add_carry_bit(l1, l2)) - - -/* - * Add two 64-bit unsigned numbers, h1l1 and h2l2. - */ - -static FILETIME add_64 -( - unsigned long h1, unsigned long l1, - unsigned long h2, unsigned long l2 -) -{ - FILETIME result; - result.dwLowDateTime = l1 + l2; - result.dwHighDateTime = add_64_hi( h1, l1, h2, l2 ); - return result; -} - - -static FILETIME add_FILETIME( FILETIME t1, FILETIME t2 ) -{ - return add_64( t1.dwHighDateTime, t1.dwLowDateTime, t2.dwHighDateTime, - t2.dwLowDateTime ); -} - - -static FILETIME negate_FILETIME( FILETIME t ) -{ - /* 2s complement negation */ - return add_64( ~t.dwHighDateTime, ~t.dwLowDateTime, 0, 1 ); -} - - -/* - * Convert a FILETIME to a number of seconds. - */ - -static double filetime_seconds( FILETIME t ) -{ - return t.dwHighDateTime * ( (double)( 1UL << 31 ) * 2.0 * 1.0e-7 ) + t.dwLowDateTime * 1.0e-7; -} - - -/* - * What should be a simple conversion, turns out to be horribly complicated by - * the defficiencies of MSVC and the Win32 API. - */ - -static time_t filetime_dt( FILETIME t_utc ) -{ - static int calc_time_diff = 1; - static double time_diff; - if ( calc_time_diff ) - { - struct tm t0_; - FILETIME f0_local; - FILETIME f0_; - SYSTEMTIME s0_; - GetSystemTime( &s0_ ); - t0_.tm_year = s0_.wYear-1900; - t0_.tm_mon = s0_.wMonth-1; - t0_.tm_wday = s0_.wDayOfWeek; - t0_.tm_mday = s0_.wDay; - t0_.tm_hour = s0_.wHour; - t0_.tm_min = s0_.wMinute; - t0_.tm_sec = s0_.wSecond; - t0_.tm_isdst = 0; - SystemTimeToFileTime( &s0_, &f0_local ); - LocalFileTimeToFileTime( &f0_local, &f0_ ); - time_diff = filetime_seconds( f0_ ) - (double)mktime( &t0_ ); - calc_time_diff = 0; - } - return ceil( filetime_seconds( t_utc ) - time_diff ); -} - - -static void record_times( HANDLE process, timing_info * time ) -{ - FILETIME creation; - FILETIME exit; - FILETIME kernel; - FILETIME user; - if ( GetProcessTimes( process, &creation, &exit, &kernel, &user ) ) - { - time->system = filetime_seconds( kernel ); - time->user = filetime_seconds( user ); - time->start = filetime_dt ( creation ); - time->end = filetime_dt ( exit ); - } -} - - -#define IO_BUFFER_SIZE ( 16 * 1024 ) - -static char ioBuffer[ IO_BUFFER_SIZE + 1 ]; - - -static void read_pipe -( - HANDLE in, /* the pipe to read from */ - string * out -) -{ - DWORD bytesInBuffer = 0; - DWORD bytesAvailable = 0; - - do - { - /* check if we have any data to read */ - if ( !PeekNamedPipe( in, ioBuffer, IO_BUFFER_SIZE, &bytesInBuffer, &bytesAvailable, NULL ) ) - bytesAvailable = 0; - - /* read in the available data */ - if ( bytesAvailable > 0 ) - { - /* we only read in the available bytes, to avoid blocking */ - if ( ReadFile( in, ioBuffer, - bytesAvailable <= IO_BUFFER_SIZE ? bytesAvailable : IO_BUFFER_SIZE, - &bytesInBuffer, NULL ) ) - { - if ( bytesInBuffer > 0 ) - { - /* Clean up some illegal chars. */ - int i; - for ( i = 0; i < bytesInBuffer; ++i ) - { - if ( ( (unsigned char)ioBuffer[ i ] < 1 ) ) - ioBuffer[ i ] = '?'; - } - /* Null, terminate. */ - ioBuffer[ bytesInBuffer ] = '\0'; - /* Append to the output. */ - string_append( out, ioBuffer ); - /* Subtract what we read in. */ - bytesAvailable -= bytesInBuffer; - } - else - { - /* Likely read a error, bail out. */ - bytesAvailable = 0; - } - } - else - { - /* Definitely read a error, bail out. */ - bytesAvailable = 0; - } - } - } - while ( bytesAvailable > 0 ); -} - - -static void read_output() -{ - int i; - for ( i = 0; i < globs.jobs && i < MAXJOBS; ++i ) - { - /* Read stdout data. */ - if ( cmdtab[ i ].pipe_out[ 0 ] ) - read_pipe( cmdtab[ i ].pipe_out[ 0 ], & cmdtab[ i ].buffer_out ); - /* Read stderr data. */ - if ( cmdtab[ i ].pipe_err[ 0 ] ) - read_pipe( cmdtab[ i ].pipe_err[ 0 ], & cmdtab[ i ].buffer_err ); - } -} - - -/* - * Waits for a single child process command to complete, or the timeout, - * whichever comes first. Returns the index of the completed command in the - * cmdtab array, or -1. - */ - -static int try_wait( int timeoutMillis ) -{ - int i; - int num_active; - int wait_api_result; - HANDLE active_handles[ MAXJOBS ]; - int active_procs[ MAXJOBS ]; - - /* Prepare a list of all active processes to wait for. */ - for ( num_active = 0, i = 0; i < globs.jobs; ++i ) - { - if ( cmdtab[ i ].pi.hProcess ) - { - active_handles[ num_active ] = cmdtab[ i ].pi.hProcess; - active_procs[ num_active ] = i; - ++num_active; - } - } - - /* Wait for a child to complete, or for our timeout window to expire. */ - wait_api_result = WaitForMultipleObjects( num_active, active_handles, - FALSE, timeoutMillis ); - if ( ( WAIT_OBJECT_0 <= wait_api_result ) && - ( wait_api_result < WAIT_OBJECT_0 + num_active ) ) - { - /* Rerminated process detected - return its index. */ - return active_procs[ wait_api_result - WAIT_OBJECT_0 ]; - } - - /* Timeout. */ - return -1; -} - - -static int try_kill_one() -{ - /* Only need to check if a timeout was specified with the -l option. */ - if ( globs.timeout > 0 ) - { - int i; - for ( i = 0; i < globs.jobs; ++i ) - { - double t = running_time( cmdtab[ i ].pi.hProcess ); - if ( t > (double)globs.timeout ) - { - /* The job may have left an alert dialog around, try and get rid - * of it before killing - */ - close_alert( cmdtab[ i ].pi.hProcess ); - /* We have a "runaway" job, kill it. */ - kill_process_tree( 0, cmdtab[ i ].pi.hProcess ); - /* And return it marked as a timeout. */ - cmdtab[ i ].exit_reason = EXIT_TIMEOUT; - return i; - } - } - } - return -1; -} - - -static void close_alerts() -{ - /* We only attempt this every 5 seconds, or so, because it is not a cheap - * operation, and we will catch the alerts eventually. This check uses - * floats as some compilers define CLOCKS_PER_SEC as a float or double. - */ - if ( ( (float)clock() / (float)( CLOCKS_PER_SEC * 5 ) ) < ( 1.0 / 5.0 ) ) - { - int i; - for ( i = 0; i < globs.jobs; ++i ) - close_alert( cmdtab[ i ].pi.hProcess ); - } -} - - -/* - * Calc the current running time of an *active* process. - */ - -static double running_time( HANDLE process ) -{ - FILETIME creation; - FILETIME exit; - FILETIME kernel; - FILETIME user; - FILETIME current; - if ( GetProcessTimes( process, &creation, &exit, &kernel, &user ) ) - { - /* Compute the elapsed time. */ - GetSystemTimeAsFileTime( ¤t ); - return filetime_seconds( add_FILETIME( current, - negate_FILETIME( creation ) ) ); - } - return 0.0; -} - - -/* It is just stupidly silly that one has to do this. */ -typedef struct PROCESS_BASIC_INFORMATION__ -{ - LONG ExitStatus; - PVOID PebBaseAddress; - ULONG AffinityMask; - LONG BasePriority; - ULONG UniqueProcessId; - ULONG InheritedFromUniqueProcessId; -} PROCESS_BASIC_INFORMATION_; -typedef LONG (__stdcall * NtQueryInformationProcess__)( - HANDLE ProcessHandle, - LONG ProcessInformationClass, - PVOID ProcessInformation, - ULONG ProcessInformationLength, - PULONG ReturnLength); -static NtQueryInformationProcess__ NtQueryInformationProcess_ = NULL; -static HMODULE NTDLL_ = NULL; -DWORD get_process_id( HANDLE process ) -{ - PROCESS_BASIC_INFORMATION_ pinfo; - if ( !NtQueryInformationProcess_ ) - { - if ( ! NTDLL_ ) - NTDLL_ = GetModuleHandleA( "ntdll" ); - if ( NTDLL_ ) - NtQueryInformationProcess_ - = (NtQueryInformationProcess__)GetProcAddress( NTDLL_, "NtQueryInformationProcess" ); - } - if ( NtQueryInformationProcess_ ) - { - LONG r = (*NtQueryInformationProcess_)( process, - /* ProcessBasicInformation == */ 0, &pinfo, - sizeof( PROCESS_BASIC_INFORMATION_ ), NULL ); - return pinfo.UniqueProcessId; - } - return 0; -} - - -/* - * Not really optimal, or efficient, but it is easier this way, and it is not - * like we are going to be killing thousands, or even tens of processes. - */ - -static void kill_process_tree( DWORD pid, HANDLE process ) -{ - HANDLE process_snapshot_h = INVALID_HANDLE_VALUE; - if ( !pid ) - pid = get_process_id( process ); - process_snapshot_h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); - - if ( INVALID_HANDLE_VALUE != process_snapshot_h ) - { - BOOL ok = TRUE; - PROCESSENTRY32 pinfo; - pinfo.dwSize = sizeof( PROCESSENTRY32 ); - for ( - ok = Process32First( process_snapshot_h, &pinfo ); - ok == TRUE; - ok = Process32Next( process_snapshot_h, &pinfo ) ) - { - if ( pinfo.th32ParentProcessID == pid ) - { - /* Found a child, recurse to kill it and anything else below it. - */ - HANDLE ph = OpenProcess( PROCESS_ALL_ACCESS, FALSE, - pinfo.th32ProcessID ); - if ( NULL != ph ) - { - kill_process_tree( pinfo.th32ProcessID, ph ); - CloseHandle( ph ); - } - } - } - CloseHandle( process_snapshot_h ); - } - /* Now that the children are all dead, kill the root. */ - TerminateProcess( process, -2 ); -} - - -static double creation_time( HANDLE process ) -{ - FILETIME creation; - FILETIME exit; - FILETIME kernel; - FILETIME user; - FILETIME current; - return GetProcessTimes( process, &creation, &exit, &kernel, &user ) - ? filetime_seconds( creation ) - : 0.0; -} - - -/* - * Recursive check if first process is parent (directly or indirectly) of the - * second one. Both processes are passed as process ids, not handles. Special - * return value 2 means that the second process is smss.exe and its parent - * process is System (first argument is ignored). - */ - -static int is_parent_child( DWORD parent, DWORD child ) -{ - HANDLE process_snapshot_h = INVALID_HANDLE_VALUE; - - if ( !child ) - return 0; - if ( parent == child ) - return 1; - - process_snapshot_h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); - if ( INVALID_HANDLE_VALUE != process_snapshot_h ) - { - BOOL ok = TRUE; - PROCESSENTRY32 pinfo; - pinfo.dwSize = sizeof( PROCESSENTRY32 ); - for ( - ok = Process32First( process_snapshot_h, &pinfo ); - ok == TRUE; - ok = Process32Next( process_snapshot_h, &pinfo ) ) - { - if ( pinfo.th32ProcessID == child ) - { - /* Unfortunately, process ids are not really unique. There might - * be spurious "parent and child" relationship match between two - * non-related processes if real parent process of a given - * process has exited (while child process kept running as an - * "orphan") and the process id of such parent process has been - * reused by internals of the operating system when creating - * another process. - * - * Thus additional check is needed - process creation time. This - * check may fail (i.e. return 0) for system processes due to - * insufficient privileges, and that is OK. - */ - double tchild = 0.0; - double tparent = 0.0; - HANDLE hchild = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pinfo.th32ProcessID ); - CloseHandle( process_snapshot_h ); - - /* csrss.exe may display message box like following: - * xyz.exe - Unable To Locate Component - * This application has failed to start because - * boost_foo-bar.dll was not found. Re-installing the - * application may fix the problem - * This actually happens when starting test process that depends - * on a dynamic library which failed to build. We want to - * automatically close these message boxes even though csrss.exe - * is not our child process. We may depend on the fact that (in - * all current versions of Windows) csrss.exe is directly child - * of the smss.exe process, which in turn is directly child of - * the System process, which always has process id == 4. This - * check must be performed before comparison of process creation - * times. - */ - if ( !stricmp( pinfo.szExeFile, "csrss.exe" ) && - ( is_parent_child( parent, pinfo.th32ParentProcessID ) == 2 ) ) - return 1; - if ( !stricmp( pinfo.szExeFile, "smss.exe" ) && - ( pinfo.th32ParentProcessID == 4 ) ) - return 2; - - if ( hchild ) - { - HANDLE hparent = OpenProcess( PROCESS_QUERY_INFORMATION, - FALSE, pinfo.th32ParentProcessID ); - if ( hparent ) - { - tchild = creation_time( hchild ); - tparent = creation_time( hparent ); - CloseHandle( hparent ); - } - CloseHandle( hchild ); - } - - /* Return 0 if one of the following is true: - * 1. we failed to read process creation time - * 2. child was created before alleged parent - */ - if ( ( tchild == 0.0 ) || ( tparent == 0.0 ) || - ( tchild < tparent ) ) - return 0; - - return is_parent_child( parent, pinfo.th32ParentProcessID ) & 1; - } - } - - CloseHandle( process_snapshot_h ); - } - - return 0; -} - -typedef struct PROCESS_HANDLE_ID { HANDLE h; DWORD pid; } PROCESS_HANDLE_ID; - - -/* - * This function is called by the operating system for each topmost window. - */ - -BOOL CALLBACK close_alert_window_enum( HWND hwnd, LPARAM lParam ) -{ - char buf[ 7 ] = { 0 }; - PROCESS_HANDLE_ID p = *( (PROCESS_HANDLE_ID *)lParam ); - DWORD pid = 0; - DWORD tid = 0; - - /* We want to find and close any window that: - * 1. is visible and - * 2. is a dialog and - * 3. is displayed by any of our child processes - */ - if ( !IsWindowVisible( hwnd ) ) - return TRUE; - - if ( !GetClassNameA( hwnd, buf, sizeof( buf ) ) ) - return TRUE; /* Failed to read class name; presume it is not a dialog. */ - - if ( strcmp( buf, "#32770" ) ) - return TRUE; /* Not a dialog */ - - /* GetWindowThreadProcessId() returns 0 on error, otherwise thread id of - * window message pump thread. - */ - tid = GetWindowThreadProcessId( hwnd, &pid ); - - if ( tid && is_parent_child( p.pid, pid ) ) - { - /* Ask really nice. */ - PostMessageA( hwnd, WM_CLOSE, 0, 0 ); - /* Now wait and see if it worked. If not, insist. */ - if ( WaitForSingleObject( p.h, 200 ) == WAIT_TIMEOUT ) - { - PostThreadMessageA( tid, WM_QUIT, 0, 0 ); - WaitForSingleObject( p.h, 300 ); - } - - /* Done, we do not want to check any other window now. */ - return FALSE; - } - - return TRUE; -} - - -static void close_alert( HANDLE process ) -{ - DWORD pid = get_process_id( process ); - /* If process already exited or we just can not get its process id, do not - * go any further. - */ - if ( pid ) - { - PROCESS_HANDLE_ID p; - p.h = process; - p.pid = pid; - EnumWindows( &close_alert_window_enum, (LPARAM)&p ); - } -} - -#endif /* USE_EXECNT */ diff --git a/jam-files/engine/execunix.c b/jam-files/engine/execunix.c deleted file mode 100644 index ef9dba00..00000000 --- a/jam-files/engine/execunix.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * Copyright 2007 Noel Belcourt. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -#include "jam.h" -#include "lists.h" -#include "execcmd.h" -#include "output.h" -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <time.h> -#include <unistd.h> /* needed for vfork(), _exit() prototypes */ -#include <sys/resource.h> -#include <sys/times.h> -#include <sys/wait.h> - -#if defined(sun) || defined(__sun) || defined(linux) - #include <wait.h> -#endif - -#ifdef USE_EXECUNIX - -#include <sys/times.h> - -#if defined(__APPLE__) - #define NO_VFORK -#endif - -#ifdef NO_VFORK - #define vfork() fork() -#endif - - -/* - * 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) does - * not include a %, it is tacked on as the last argument. - * - * Do not just set JAMSHELL to /bin/sh or cmd.exe - it will not work! - * - * External routines: - * exec_cmd() - launch an async command execution. - * exec_wait() - 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 clock_t tps = 0; -static struct timeval tv; -static int select_timeout = 0; -static int intr = 0; -static int cmdsrunning = 0; -static struct tms old_time; - -#define OUT 0 -#define ERR 1 - -static struct -{ - int pid; /* on win32, a real process handle */ - int fd[2]; /* file descriptors for stdout and stderr */ - FILE *stream[2]; /* child's stdout (0) and stderr (1) file stream */ - clock_t start_time; /* start time of child process */ - int exit_reason; /* termination status */ - int action_length; /* length of action string */ - int target_length; /* length of target string */ - char *action; /* buffer to hold action and target invoked */ - char *target; /* buffer to hold action and target invoked */ - char *command; /* buffer to hold command being invoked */ - char *buffer[2]; /* buffer to hold stdout and stderr, if any */ - void (*func)( void *closure, int status, timing_info*, char *, char * ); - void *closure; - time_t start_dt; /* start of command timestamp */ -} cmdtab[ MAXJOBS ] = {{0}}; - -/* - * onintr() - bump intr to note command interruption - */ - -void onintr( int disp ) -{ - ++intr; - printf( "...interrupted\n" ); -} - - -/* - * exec_cmd() - launch an async command execution. - */ - -void exec_cmd -( - char * string, - void (*func)( void *closure, int status, timing_info*, char *, char * ), - void * closure, - LIST * shell, - char * action, - char * target -) -{ - static int initialized = 0; - int out[2]; - int err[2]; - int slot; - int len; - char * argv[ MAXARGC + 1 ]; /* +1 for NULL */ - - /* 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 ); - } - - /* 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 - { - argv[ 0 ] = "/bin/sh"; - argv[ 1 ] = "-c"; - argv[ 2 ] = string; - argv[ 3 ] = 0; - } - - /* Increment jobs running. */ - ++cmdsrunning; - - /* Save off actual command string. */ - cmdtab[ slot ].command = BJAM_MALLOC_ATOMIC( strlen( string ) + 1 ); - strcpy( cmdtab[ slot ].command, string ); - - /* Initialize only once. */ - if ( !initialized ) - { - times( &old_time ); - initialized = 1; - } - - /* Create pipes from child to parent. */ - { - if ( pipe( out ) < 0 ) - exit( EXITBAD ); - - if ( pipe( err ) < 0 ) - exit( EXITBAD ); - } - - /* Start the command */ - - cmdtab[ slot ].start_dt = time(0); - - if ( 0 < globs.timeout ) - { - /* - * Handle hung processes by manually tracking elapsed time and signal - * process when time limit expires. - */ - struct tms buf; - cmdtab[ slot ].start_time = times( &buf ); - - /* Make a global, only do this once. */ - if ( tps == 0 ) tps = sysconf( _SC_CLK_TCK ); - } - - if ( ( cmdtab[ slot ].pid = vfork() ) == 0 ) - { - int pid = getpid(); - - close( out[0] ); - close( err[0] ); - - dup2( out[1], STDOUT_FILENO ); - - if ( globs.pipe_action == 0 ) - dup2( out[1], STDERR_FILENO ); - else - dup2( err[1], STDERR_FILENO ); - - close( out[1] ); - close( err[1] ); - - /* Make this process a process group leader so that when we kill it, all - * child processes of this process are terminated as well. We use - * killpg(pid, SIGKILL) to kill the process group leader and all its - * children. - */ - if ( 0 < globs.timeout ) - { - struct rlimit r_limit; - r_limit.rlim_cur = globs.timeout; - r_limit.rlim_max = globs.timeout; - setrlimit( RLIMIT_CPU, &r_limit ); - } - setpgid( pid,pid ); - execvp( argv[0], argv ); - perror( "execvp" ); - _exit( 127 ); - } - else if ( cmdtab[ slot ].pid == -1 ) - { - perror( "vfork" ); - exit( EXITBAD ); - } - - setpgid( cmdtab[ slot ].pid, cmdtab[ slot ].pid ); - - /* close write end of pipes */ - close( out[1] ); - close( err[1] ); - - /* set both file descriptors to non-blocking */ - fcntl(out[0], F_SETFL, O_NONBLOCK); - fcntl(err[0], F_SETFL, O_NONBLOCK); - - /* child writes stdout to out[1], parent reads from out[0] */ - cmdtab[ slot ].fd[ OUT ] = out[0]; - cmdtab[ slot ].stream[ OUT ] = fdopen( cmdtab[ slot ].fd[ OUT ], "rb" ); - if ( cmdtab[ slot ].stream[ OUT ] == NULL ) - { - perror( "fdopen" ); - exit( EXITBAD ); - } - - /* child writes stderr to err[1], parent reads from err[0] */ - if (globs.pipe_action == 0) - { - close(err[0]); - } - else - { - cmdtab[ slot ].fd[ ERR ] = err[0]; - cmdtab[ slot ].stream[ ERR ] = fdopen( cmdtab[ slot ].fd[ ERR ], "rb" ); - if ( cmdtab[ slot ].stream[ ERR ] == NULL ) - { - perror( "fdopen" ); - exit( EXITBAD ); - } - } - - /* Ensure enough room for rule and target name. */ - if ( action && target ) - { - len = strlen( action ) + 1; - if ( cmdtab[ slot ].action_length < len ) - { - BJAM_FREE( cmdtab[ slot ].action ); - cmdtab[ slot ].action = BJAM_MALLOC_ATOMIC( len ); - cmdtab[ slot ].action_length = len; - } - strcpy( cmdtab[ slot ].action, action ); - len = strlen( target ) + 1; - if ( cmdtab[ slot ].target_length < len ) - { - BJAM_FREE( cmdtab[ slot ].target ); - cmdtab[ slot ].target = BJAM_MALLOC_ATOMIC( len ); - cmdtab[ slot ].target_length = len; - } - strcpy( cmdtab[ slot ].target, target ); - } - else - { - BJAM_FREE( cmdtab[ slot ].action ); - BJAM_FREE( cmdtab[ slot ].target ); - cmdtab[ slot ].action = 0; - cmdtab[ slot ].target = 0; - cmdtab[ slot ].action_length = 0; - cmdtab[ slot ].target_length = 0; - } - - /* Save the operation for exec_wait() to find. */ - cmdtab[ slot ].func = func; - cmdtab[ slot ].closure = closure; - - /* Wait until we are under the limit of concurrent commands. Do not trust - * globs.jobs alone. - */ - while ( ( cmdsrunning >= MAXJOBS ) || ( cmdsrunning >= globs.jobs ) ) - if ( !exec_wait() ) - break; -} - - -/* Returns 1 if file is closed, 0 if descriptor is still live. - * - * i is index into cmdtab - * - * s (stream) indexes: - * - cmdtab[ i ].stream[ s ] - * - cmdtab[ i ].buffer[ s ] - * - cmdtab[ i ].fd [ s ] - */ - -int read_descriptor( int i, int s ) -{ - int ret; - int len; - char buffer[BUFSIZ]; - - while ( 0 < ( ret = fread( buffer, sizeof(char), BUFSIZ-1, cmdtab[ i ].stream[ s ] ) ) ) - { - buffer[ret] = 0; - if ( !cmdtab[ i ].buffer[ s ] ) - { - /* Never been allocated. */ - cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( ret + 1 ); - memcpy( cmdtab[ i ].buffer[ s ], buffer, ret + 1 ); - } - else - { - /* Previously allocated. */ - char * tmp = cmdtab[ i ].buffer[ s ]; - len = strlen( tmp ); - cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( len + ret + 1 ); - memcpy( cmdtab[ i ].buffer[ s ], tmp, len ); - memcpy( cmdtab[ i ].buffer[ s ] + len, buffer, ret + 1 ); - BJAM_FREE( tmp ); - } - } - - return feof(cmdtab[ i ].stream[ s ]); -} - - -void close_streams( int i, int s ) -{ - /* Close the stream and pipe descriptor. */ - fclose(cmdtab[ i ].stream[ s ]); - cmdtab[ i ].stream[ s ] = 0; - - close(cmdtab[ i ].fd[ s ]); - cmdtab[ i ].fd[ s ] = 0; -} - - -void populate_file_descriptors( int * fmax, fd_set * fds) -{ - int i, fd_max = 0; - struct tms buf; - clock_t current = times( &buf ); - select_timeout = globs.timeout; - - /* Compute max read file descriptor for use in select. */ - FD_ZERO(fds); - for ( i = 0; i < globs.jobs; ++i ) - { - if ( 0 < cmdtab[ i ].fd[ OUT ] ) - { - fd_max = fd_max < cmdtab[ i ].fd[ OUT ] ? cmdtab[ i ].fd[ OUT ] : fd_max; - FD_SET(cmdtab[ i ].fd[ OUT ], fds); - } - if ( globs.pipe_action != 0 ) - { - if (0 < cmdtab[ i ].fd[ ERR ]) - { - fd_max = fd_max < cmdtab[ i ].fd[ ERR ] ? cmdtab[ i ].fd[ ERR ] : fd_max; - FD_SET(cmdtab[ i ].fd[ ERR ], fds); - } - } - - if (globs.timeout && cmdtab[ i ].pid) { - clock_t consumed = (current - cmdtab[ i ].start_time) / tps; - clock_t process_timesout = globs.timeout - consumed; - if (0 < process_timesout && process_timesout < select_timeout) { - select_timeout = process_timesout; - } - if ( globs.timeout <= consumed ) - { - killpg( cmdtab[ i ].pid, SIGKILL ); - cmdtab[ i ].exit_reason = EXIT_TIMEOUT; - } - } - } - *fmax = fd_max; -} - - -/* - * exec_wait() - wait and drive at most one execution completion. - */ - -int exec_wait() -{ - int i; - int ret; - int fd_max; - int pid; - int status; - int finished; - int rstat; - timing_info time_info; - fd_set fds; - struct tms new_time; - - /* Handle naive make1() which does not know if commands are running. */ - if ( !cmdsrunning ) - return 0; - - /* Process children that signaled. */ - finished = 0; - while ( !finished && cmdsrunning ) - { - /* Compute max read file descriptor for use in select(). */ - populate_file_descriptors( &fd_max, &fds ); - - if ( 0 < globs.timeout ) - { - /* Force select() to timeout so we can terminate expired processes. - */ - tv.tv_sec = select_timeout; - tv.tv_usec = 0; - - /* select() will wait until: i/o on a descriptor, a signal, or we - * time out. - */ - ret = select( fd_max + 1, &fds, 0, 0, &tv ); - } - else - { - /* select() will wait until i/o on a descriptor or a signal. */ - ret = select( fd_max + 1, &fds, 0, 0, 0 ); - } - - if ( 0 < ret ) - { - for ( i = 0; i < globs.jobs; ++i ) - { - int out = 0; - int err = 0; - if ( FD_ISSET( cmdtab[ i ].fd[ OUT ], &fds ) ) - out = read_descriptor( i, OUT ); - - if ( ( globs.pipe_action != 0 ) && - ( FD_ISSET( cmdtab[ i ].fd[ ERR ], &fds ) ) ) - err = read_descriptor( i, ERR ); - - /* If feof on either descriptor, then we are done. */ - if ( out || err ) - { - /* Close the stream and pipe descriptors. */ - close_streams( i, OUT ); - if ( globs.pipe_action != 0 ) - close_streams( i, ERR ); - - /* Reap the child and release resources. */ - pid = waitpid( cmdtab[ i ].pid, &status, 0 ); - - if ( pid == cmdtab[ i ].pid ) - { - finished = 1; - pid = 0; - cmdtab[ i ].pid = 0; - - /* Set reason for exit if not timed out. */ - if ( WIFEXITED( status ) ) - { - cmdtab[ i ].exit_reason = 0 == WEXITSTATUS( status ) - ? EXIT_OK - : EXIT_FAIL; - } - - /* Print out the rule and target name. */ - out_action( cmdtab[ i ].action, cmdtab[ i ].target, - cmdtab[ i ].command, cmdtab[ i ].buffer[ OUT ], - cmdtab[ i ].buffer[ ERR ], cmdtab[ i ].exit_reason - ); - - times( &new_time ); - - time_info.system = (double)( new_time.tms_cstime - old_time.tms_cstime ) / CLOCKS_PER_SEC; - time_info.user = (double)( new_time.tms_cutime - old_time.tms_cutime ) / CLOCKS_PER_SEC; - time_info.start = cmdtab[ i ].start_dt; - time_info.end = time( 0 ); - - old_time = new_time; - - /* Drive the completion. */ - --cmdsrunning; - - if ( intr ) - rstat = EXEC_CMD_INTR; - else if ( status != 0 ) - rstat = EXEC_CMD_FAIL; - else - rstat = EXEC_CMD_OK; - - /* Assume -p0 in effect so only pass buffer[ 0 ] - * containing merged output. - */ - (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat, - &time_info, cmdtab[ i ].command, - cmdtab[ i ].buffer[ 0 ] ); - - BJAM_FREE( cmdtab[ i ].buffer[ OUT ] ); - cmdtab[ i ].buffer[ OUT ] = 0; - - BJAM_FREE( cmdtab[ i ].buffer[ ERR ] ); - cmdtab[ i ].buffer[ ERR ] = 0; - - BJAM_FREE( cmdtab[ i ].command ); - cmdtab[ i ].command = 0; - - cmdtab[ i ].func = 0; - cmdtab[ i ].closure = 0; - cmdtab[ i ].start_time = 0; - } - else - { - printf( "unknown pid %d with errno = %d\n", pid, errno ); - exit( EXITBAD ); - } - } - } - } - } - - return 1; -} - -# endif /* USE_EXECUNIX */ diff --git a/jam-files/engine/execvms.c b/jam-files/engine/execvms.c deleted file mode 100644 index 729917d3..00000000 --- a/jam-files/engine/execvms.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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" - -#ifdef OS_VMS - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <iodef.h> -#include <ssdef.h> -#include <descrip.h> -#include <dvidef.h> -#include <clidef.h> - -/* - * 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 do not 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) - do not put -'s between "'s - */ - -#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 exec_cmd -( - char * string, - void (* func)( void * closure, int status, timing_info *, char *, char * ), - void * closure, - LIST * shell, - char * rule_name, - char * target -) -{ - char * s; - char * e; - cahr * 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 exec_wait() -{ - return 0; -} - -# endif /* VMS */ diff --git a/jam-files/engine/expand.c b/jam-files/engine/expand.c deleted file mode 100644 index d8e58827..00000000 --- a/jam-files/engine/expand.c +++ /dev/null @@ -1,733 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -# include "jam.h" -# include "lists.h" -# include "variable.h" -# include "expand.h" -# include "pathsys.h" -# include "newstr.h" -# include <assert.h> -# include <stdlib.h> -# include <limits.h> - -# ifdef OS_CYGWIN -# include <sys/cygwin.h> -# include <windows.h> -# endif - -/* - * 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/11/01 (seiwald) - added support for :E=emptyvalue, :J=joinval - */ - -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 to_slashes; /* :T -- convert "\" to "/" */ - char to_windows; /* :W -- convert cygwin to native paths */ - PATHPART empty; /* :E -- default for empties */ - PATHPART join; /* :J -- join list with char */ -} VAR_EDITS ; - -static void var_edit_parse( char * mods, VAR_EDITS * edits ); -static void var_edit_file ( char * in, string * out, VAR_EDITS * edits ); -static void var_edit_shift( string * out, VAR_EDITS * edits ); - -#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, char * in, char * end, LOL * lol, int cancopyin ) -{ - char out_buf[ MAXSYM ]; - string buf[ 1 ]; - string out1[ 1 ]; /* temporary buffer */ - size_t prefix_length; - char * out; - 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 a lot of cases: $(<) and $(>). */ - if - ( - ( in[ 0 ] == '$' ) && - ( in[ 1 ] == '(' ) && - ( in[ 3 ] == ')' ) && - ( in[ 4 ] == '\0' ) - ) - { - switch ( in[ 2 ] ) - { - case '<': return list_copy( l, lol_get( lol, 0 ) ); - case '>': return list_copy( l, lol_get( lol, 1 ) ); - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return list_copy( l, lol_get( lol, in[ 2 ] - '1' ) ); - } - } - else if ( in[0] == '$' && in[1] == '(' && in[2] == '1' && in[4] == ')' && - in[5] == '\0') { - - switch( in[3] ) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return list_copy( l, lol_get( lol, in[3]-'0'+10-1 ) ); - } - } - - /* Expand @() files, to single item plus accompanying file. */ - if ( ( in[ 0 ] == '@' ) && ( in[ 1 ] == '(' ) && ( *( end - 1 ) == ')' ) ) - { - /* We try the expansion until it fits within the propective output - * buffer. - */ - char * at_buf = 0; - int at_size = MAXJPATH; - int at_len = 0; - do - { - BJAM_FREE( at_buf ); - at_buf = (char *)BJAM_MALLOC_ATOMIC( at_size + 1 ); - at_len = var_string( in, at_buf, at_size, lol ); - at_size *= 2; - } - while ( ( at_len < 0 ) && ( at_size < INT_MAX / 2 ) ); - /* Return the result as a single item list. */ - if ( at_len > 0 ) - { - LIST * r; - string_copy( buf, at_buf ); - r = list_new( l, newstr( buf->value ) ); - string_free( buf ); - BJAM_FREE( at_buf ); - return r; - } - BJAM_FREE( at_buf ); - } - - /* Just try simple copy of in to out. */ - while ( in < end ) - if ( ( *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 copystr() to put it on the new list. Otherwise, we use the slower - * newstr(). - */ - if ( cancopyin ) - return list_new( l, copystr( inp ) ); - - { - LIST * r; - string_new( buf ); - string_append_range( buf, inp, end ); - r = list_new( l, newstr( buf->value ) ); - string_free( buf ); - return r; - } - -expand: - string_new( buf ); - string_append_range( buf, inp, in - 1 ); /* Copy the part before '$'. */ - /* - * 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; - inp = ++in; /* Skip over the '('. */ - - while ( ( in < end ) && depth ) - { - switch ( *in++ ) - { - case '(': ++depth; break; - case ')': --depth; break; - } - } - - /* - * Input so far (ignore blanks): - * - * stuff-in-outbuf $(variable) remainder - * ^ ^ ^ - * inp in end - */ - prefix_length = buf->size; - string_append_range( buf, inp, in - 1 ); - - out = buf->value + prefix_length; - for ( ov = out; ov < buf->value + buf->size; ++ov ) - { - switch ( *ov ) - { - case ':': *ov = MAGIC_COLON; break; - case '[': *ov = MAGIC_LEFT ; break; - case ']': *ov = MAGIC_RIGHT; break; - } - } - - /* - * 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 will 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 = 0; - LIST * evalue = 0; - char * colon; - char * bracket; - string variable[1]; - char * varname; - int sub1 = 0; - int sub2 = -1; - VAR_EDITS edits; - - /* Look for a : modifier in the variable name. Must copy into - * varname so we can modify it. - */ - string_copy( variable, vars->string ); - varname = variable->value; - - if ( ( colon = strchr( varname, MAGIC_COLON ) ) ) - { - string_truncate( variable, colon - varname ); - var_edit_parse( colon + 1, &edits ); - } - - /* Look for [x-y] subscripting. sub1 and sub2 are x and y. */ - if ( ( bracket = strchr( varname, MAGIC_LEFT ) ) ) - { - /* Make all syntax errors in [] subscripting result in the same - * behavior: silenty return an empty expansion (by setting sub2 - * = 0). Brute force parsing; May get moved into yacc someday. - */ - - char * s = bracket + 1; - - string_truncate( variable, bracket - varname ); - - do /* so we can use "break" */ - { - /* Allow negative indexes. */ - if ( !isdigit( *s ) && ( *s != '-' ) ) - { - sub2 = 0; - break; - } - sub1 = atoi( s ); - - /* Skip over the first symbol, which is either a digit or dash. */ - ++s; - while ( isdigit( *s ) ) ++s; - - if ( *s == MAGIC_RIGHT ) - { - sub2 = sub1; - break; - } - - if ( *s != '-' ) - { - sub2 = 0; - break; - } - - ++s; - - if ( *s == MAGIC_RIGHT ) - { - sub2 = -1; - break; - } - - if ( !isdigit( *s ) && ( *s != '-' ) ) - { - sub2 = 0; - break; - } - - /* First, compute the index of the last element. */ - sub2 = atoi( s ); - while ( isdigit( *++s ) ); - - if ( *s != MAGIC_RIGHT ) - sub2 = 0; - - } while ( 0 ); - - /* Anything but the end of the string, or the colon introducing - * a modifier is a syntax error. - */ - ++s; - if ( *s && ( *s != MAGIC_COLON ) ) - sub2 = 0; - - *bracket = '\0'; - } - - /* Get variable value, with special handling for $(<), $(>), $(n). - */ - if ( !varname[1] ) - { - if ( varname[0] == '<' ) - value = lol_get( lol, 0 ); - else if ( varname[0] == '>' ) - value = lol_get( lol, 1 ); - else if ( ( varname[0] >= '1' ) && ( varname[0] <= '9' ) ) - value = lol_get( lol, varname[0] - '1' ); - else if( varname[0] == '1' && varname[1] >= '0' && - varname[1] <= '9' && !varname[2] ) - value = lol_get( lol, varname[1] - '0' + 10 - 1 ); - } - - if ( !value ) - value = var_get( varname ); - - /* Handle negitive indexes: part two. */ - { - int length = list_length( value ); - - if ( sub1 < 0 ) - sub1 = length + sub1; - else - sub1 -= 1; - - if ( sub2 < 0 ) - sub2 = length + 1 + sub2 - sub1; - else - sub2 -= sub1; - /* The "sub2 < 0" test handles the semantic error of sub2 < - * sub1. - */ - if ( sub2 < 0 ) - sub2 = 0; - } - - /* The fast path: $(x) - just copy the variable value. This is only - * an optimization. - */ - if ( ( out == out_buf ) && !bracket && !colon && ( in == end ) ) - { - string_free( variable ); - 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, newstr( edits.empty.ptr ) ); - - /* For each variable value. */ - string_new( out1 ); - for ( ; value; value = list_next( value ) ) - { - LIST * rem; - size_t postfix_start; - - /* Handle end subscript (length actually). */ - - if ( sub2 >= 0 && --sub2 < 0 ) - break; - - string_truncate( buf, prefix_length ); - - /* Apply : mods, if present */ - - if ( colon && edits.filemods ) - var_edit_file( value->string, out1, &edits ); - else - string_append( out1, value->string ); - - if ( colon && ( edits.upshift || edits.downshift || edits.to_slashes || edits.to_windows ) ) - var_edit_shift( out1, &edits ); - - /* Handle :J=joinval */ - /* If we have more values for this var, just keep appending them - * (using the join value) rather than creating separate LIST - * elements. - */ - if ( colon && edits.join.ptr && - ( list_next( value ) || list_next( vars ) ) ) - { - string_append( out1, edits.join.ptr ); - continue; - } - - string_append( buf, out1->value ); - string_free( out1 ); - string_new( out1 ); - - /* If no remainder, append result to output chain. */ - if ( in == end ) - { - l = list_new( l, newstr( buf->value ) ); - 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'. - */ - postfix_start = buf->size; - for ( rem = remainder; rem; rem = list_next( rem ) ) - { - string_truncate( buf, postfix_start ); - string_append( buf, rem->string ); - l = list_new( l, newstr( buf->value ) ); - } - } - string_free( out1 ); - - /* Toss used empty. */ - if ( evalue ) - list_free( evalue ); - - string_free( variable ); - } - - /* 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" ); - } - - string_free( buf ); - 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 <grist> - * 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( 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 '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; - case 'T': edits->to_slashes = 1; continue; - case 'W': edits->to_windows = 1; continue; - 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 != '=' ) - { - if ( !havezeroed++ ) - { - int i; - 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( char * in, string * 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( string * out, VAR_EDITS * edits ) -{ - /* Handle upshifting, downshifting and slash translation now. */ - char * p; - for ( p = out->value; *p; ++p) - { - if ( edits->upshift ) - *p = toupper( *p ); - else if ( edits->downshift ) - *p = tolower( *p ); - if ( edits->to_slashes && ( *p == '\\' ) ) - *p = '/'; -# ifdef OS_CYGWIN - if ( edits->to_windows ) - { - char result[ MAX_PATH + 1 ]; - cygwin_conv_to_win32_path( out->value, result ); - assert( strlen( result ) <= MAX_PATH ); - string_free( out ); - string_copy( out, result ); - } -# endif - } - out->size = p - out->value; -} - - -#ifndef NDEBUG -void var_expand_unit_test() -{ - LOL lol[ 1 ]; - LIST * l; - LIST * l2; - LIST * expected = list_new( list_new( L0, newstr( "axb" ) ), newstr( "ayb" ) ); - LIST * e2; - char axyb[] = "a$(xy)b"; - char azb[] = "a$($(z))b"; - char path[] = "$(p:W)"; - -# ifdef OS_CYGWIN - char cygpath[ 256 ]; - cygwin_conv_to_posix_path( "c:\\foo\\bar", cygpath ); -# else - char cygpath[] = "/cygdrive/c/foo/bar"; -# endif - - lol_init(lol); - var_set( "xy", list_new( list_new( L0, newstr( "x" ) ), newstr( "y" ) ), VAR_SET ); - var_set( "z", list_new( L0, newstr( "xy" ) ), VAR_SET ); - var_set( "p", list_new( L0, newstr( cygpath ) ), VAR_SET ); - - l = var_expand( 0, axyb, axyb + sizeof( axyb ) - 1, lol, 0 ); - for ( l2 = l, e2 = expected; l2 && e2; l2 = list_next( l2 ), e2 = list_next( e2 ) ) - assert( !strcmp( e2->string, l2->string ) ); - assert( l2 == 0 ); - assert( e2 == 0 ); - list_free( l ); - - l = var_expand( 0, azb, azb + sizeof( azb ) - 1, lol, 0 ); - for ( l2 = l, e2 = expected; l2 && e2; l2 = list_next( l2 ), e2 = list_next( e2 ) ) - assert( !strcmp( e2->string, l2->string ) ); - assert( l2 == 0 ); - assert( e2 == 0 ); - list_free( l ); - - l = var_expand( 0, path, path + sizeof( path ) - 1, lol, 0 ); - assert( l != 0 ); - assert( list_next( l ) == 0 ); -# ifdef OS_CYGWIN - /* On some installations of cygwin the drive letter is expanded to other - * case. This has been reported to be the case if cygwin has been installed - * to C:\ as opposed to C:\cygwin. Since case of the drive letter will not - * matter, we allow for both. - */ - assert( !strcmp( l->string, "c:\\foo\\bar" ) || - !strcmp( l->string, "C:\\foo\\bar" ) ); -# else - assert( !strcmp( l->string, cygpath ) ); -# endif - list_free( l ); - list_free( expected ); - lol_free( lol ); -} -#endif diff --git a/jam-files/engine/expand.h b/jam-files/engine/expand.h deleted file mode 100644 index cc25d190..00000000 --- a/jam-files/engine/expand.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * 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 - */ - -#include "lists.h" - -LIST *var_expand( LIST *l, char *in, char *end, LOL *lol, int cancopyin ); -void var_expand_unit_test(); diff --git a/jam-files/engine/filemac.c b/jam-files/engine/filemac.c deleted file mode 100644 index e69aa648..00000000 --- a/jam-files/engine/filemac.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_MAC - -#include <Files.h> -#include <Folders.h> - -# include <:sys:stat.h> - -/* - * 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 - */ - - -void CopyC2PStr( char const * 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( char * dir, scanback func, void * closure ) -{ - PATHNAME f; - string filename[ 1 ]; - 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; - - string_new( filename ); - 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; - - string_truncate( filename, 0 ); - path_build( &f, filename, 0 ); - (*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 ); - } - string_free( filename ); -} - - -/* - * file_time() - get timestamp of file, if not done by file_dirscan(). - */ - -int file_time( char * filename, time_t * time ) -{ - struct stat statbuf; - - if ( stat( filename, &statbuf ) < 0 ) - return -1; - - *time = statbuf.st_mtime; - - return 0; -} - - -int file_is_file( char * filename ) -{ - struct stat statbuf; - if ( stat( filename, &statbuf ) < 0 ) - return -1; - return S_ISREG( statbuf.st_mode ) ? 1 : 0; -} - -int file_mkdir(char *pathname) -{ - return mkdir(pathname, 0766); -} - - -/* - * file_archscan() - scan an archive for files. - */ - -void file_archscan( char * archive, scanback func, void * closure ) -{ -} - - -# endif /* macintosh */ diff --git a/jam-files/engine/filent.c b/jam-files/engine/filent.c deleted file mode 100644 index ab189576..00000000 --- a/jam-files/engine/filent.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Copyright 2005 Rene Rivera. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" - -# include "filesys.h" -# include "pathsys.h" -# include "strings.h" -# include "newstr.h" - -# ifdef OS_NT - -# ifdef __BORLANDC__ -# if __BORLANDC__ < 0x550 -# include <dir.h> -# include <dos.h> -# endif -# undef FILENAME /* cpp namespace collision */ -# define _finddata_t ffblk -# endif - -# include <io.h> -# include <sys/stat.h> -# include <ctype.h> -# include <direct.h> - -/* - * 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 - */ - -/* - * file_dirscan() - scan a directory for files - */ - -void file_dirscan( char * dir, scanback func, void * closure ) -{ - PROFILE_ENTER( FILE_DIRSCAN ); - - file_info_t * d = 0; - - dir = short_path_to_long_path( dir ); - - /* First enter directory itself */ - - d = file_query( dir ); - - if ( !d || !d->is_dir ) - { - PROFILE_EXIT( FILE_DIRSCAN ); - return; - } - - if ( !d->files ) - { - PATHNAME f; - string filespec[ 1 ]; - string filename[ 1 ]; - long handle; - int ret; - struct _finddata_t finfo[ 1 ]; - LIST * files = L0; - int d_length = strlen( d->name ); - - memset( (char *)&f, '\0', sizeof( f ) ); - - f.f_dir.ptr = d->name; - f.f_dir.len = d_length; - - /* Now enter contents of directory */ - - /* Prepare file search specification for the findfirst() API. */ - if ( d_length == 0 ) - string_copy( filespec, ".\\*" ); - else - { - /* - * We can not simply assume the given folder name will never include - * its trailing path separator or otherwise we would not support the - * Windows root folder specified without its drive letter, i.e. '\'. - */ - char trailingChar = d->name[ d_length - 1 ] ; - string_copy( filespec, d->name ); - if ( ( trailingChar != '\\' ) && ( trailingChar != '/' ) ) - string_append( filespec, "\\" ); - string_append( filespec, "*" ); - } - - if ( DEBUG_BINDSCAN ) - printf( "scan directory %s\n", dir ); - - #if defined(__BORLANDC__) && __BORLANDC__ < 0x550 - if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) ) - { - string_free( filespec ); - PROFILE_EXIT( FILE_DIRSCAN ); - return; - } - - string_new ( filename ); - while ( !ret ) - { - file_info_t * ff = 0; - - f.f_base.ptr = finfo->ff_name; - f.f_base.len = strlen( finfo->ff_name ); - - string_truncate( filename, 0 ); - path_build( &f, filename ); - - files = list_new( files, newstr(filename->value) ); - ff = file_info( filename->value ); - ff->is_file = finfo->ff_attrib & FA_DIREC ? 0 : 1; - ff->is_dir = finfo->ff_attrib & FA_DIREC ? 1 : 0; - ff->size = finfo->ff_fsize; - ff->time = (finfo->ff_ftime << 16) | finfo->ff_ftime; - - ret = findnext( finfo ); - } - # else - handle = _findfirst( filespec->value, finfo ); - - if ( ret = ( handle < 0L ) ) - { - string_free( filespec ); - PROFILE_EXIT( FILE_DIRSCAN ); - return; - } - - string_new( filename ); - while ( !ret ) - { - file_info_t * ff = 0; - - f.f_base.ptr = finfo->name; - f.f_base.len = strlen( finfo->name ); - - string_truncate( filename, 0 ); - path_build( &f, filename, 0 ); - - files = list_new( files, newstr( filename->value ) ); - ff = file_info( filename->value ); - ff->is_file = finfo->attrib & _A_SUBDIR ? 0 : 1; - ff->is_dir = finfo->attrib & _A_SUBDIR ? 1 : 0; - ff->size = finfo->size; - ff->time = finfo->time_write; - - ret = _findnext( handle, finfo ); - } - - _findclose( handle ); - # endif - string_free( filename ); - string_free( filespec ); - - d->files = files; - } - - /* Special case \ or d:\ : enter it */ - { - unsigned long len = strlen(d->name); - if ( len == 1 && d->name[0] == '\\' ) - (*func)( closure, d->name, 1 /* stat()'ed */, d->time ); - else if ( len == 3 && d->name[1] == ':' ) { - (*func)( closure, d->name, 1 /* stat()'ed */, d->time ); - /* We've just entered 3-letter drive name spelling (with trailing - slash), into the hash table. Now enter two-letter variant, - without trailing slash, so that if we try to check whether - "c:" exists, we hit it. - - Jam core has workarounds for that. Given: - x = c:\whatever\foo ; - p = $(x:D) ; - p2 = $(p:D) ; - There will be no trailing slash in $(p), but there will be one - in $(p2). But, that seems rather fragile. - */ - d->name[2] = 0; - (*func)( closure, d->name, 1 /* stat()'ed */, d->time ); - } - } - - /* Now enter contents of directory */ - if ( d->files ) - { - LIST * files = d->files; - while ( files ) - { - file_info_t * ff = file_info( files->string ); - (*func)( closure, ff->name, 1 /* stat()'ed */, ff->time ); - files = list_next( files ); - } - } - - PROFILE_EXIT( FILE_DIRSCAN ); -} - -file_info_t * file_query( char * filename ) -{ - file_info_t * ff = file_info( filename ); - if ( ! ff->time ) - { - struct stat statbuf; - - if ( stat( *filename ? filename : ".", &statbuf ) < 0 ) - return 0; - - ff->is_file = statbuf.st_mode & S_IFREG ? 1 : 0; - ff->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0; - ff->size = statbuf.st_size; - ff->time = statbuf.st_mtime ? statbuf.st_mtime : 1; - } - return ff; -} - -/* - * file_time() - get timestamp of file, if not done by file_dirscan() - */ - -int -file_time( - char *filename, - time_t *time ) -{ - file_info_t * ff = file_query( filename ); - if ( !ff ) return -1; - *time = ff->time; - return 0; -} - -int file_is_file(char* filename) -{ - file_info_t * ff = file_query( filename ); - if ( !ff ) return -1; - return ff->is_file; -} - -int file_mkdir(char *pathname) -{ - return _mkdir(pathname); -} - -/* - * file_archscan() - scan an archive for files - */ - -/* Straight from SunOS */ - -#define ARMAG "!<arch>\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( - char *archive, - scanback func, - void *closure ) -{ - struct ar_hdr ar_hdr; - char *string_table = 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 = BJAM_MALLOC_ATOMIC(lar_size+1); - if (read(fd, string_table, lar_size) != lar_size) - printf("error reading string table\n"); - string_table[lar_size] = '\0'; - offset += SARHDR + lar_size; - continue; - } - 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. - */ - - name = string_table + atoi( ar_hdr.ar_name + 1 ); - for ( endname = name; *endname && *endname != '\n'; ++endname) {} - } - else - { - /* normal name */ - name = ar_hdr.ar_name; - endname = name + sizeof( ar_hdr.ar_name ); - } - - /* strip trailing white-space, slashes, and backslashes */ - - while ( endname-- > name ) - if ( !isspace(*endname) && ( *endname != '\\' ) && ( *endname != '/' ) ) - break; - *++endname = 0; - - /* strip leading directory names, an NT specialty */ - - if ( c = strrchr( name, '/' ) ) - name = c + 1; - if ( c = strrchr( name, '\\' ) ) - name = c + 1; - - sprintf( buf, "%s(%.*s)", archive, endname - name, name ); - (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date ); - - offset += SARHDR + lar_size; - lseek( fd, offset, 0 ); - } - - close( fd ); -} - -# endif /* NT */ diff --git a/jam-files/engine/fileos2.c b/jam-files/engine/fileos2.c deleted file mode 100644 index af2373ea..00000000 --- a/jam-files/engine/fileos2.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -/* note that we use "fileunix.c" when compiling with EMX on OS/2 */ -# if defined(OS_OS2) && !defined(__EMX__) - -# include <io.h> -# include <dos.h> - -/* - * 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 - * 09/22/00 (seiwald) handle \ and c:\ specially: don't add extra / - */ - -/* - * file_dirscan() - scan a directory for files - */ - -void -file_dirscan( - char *dir, - scanback func, - void *closure ) -{ - PATHNAME f; - string filespec[1]; - 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 */ - string_copy( 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 - string_push_back( filespec, '/' ); - - string_push_back( filespec, '*' ); - - /* Now enter contents of directory */ - - if ( DEBUG_BINDSCAN ) - printf( "scan directory %s\n", filespec->value ); - - /* 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->value, _A_NORMAL|_A_RDONLY|_A_SUBDIR, finfo ) ) - { - string filename[1]; - string_new( filename ); - do - { - f.f_base.ptr = finfo->name; - f.f_base.len = strlen( finfo->name ); - - string_truncate( filename, 0 ); - path_build( &f, filename, 0 ); - (*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 ); - } - while ( !_dos_findnext( finfo ) ); - string_free( filename ); - } -} - -/* - * file_time() - get timestamp of file, if not done by file_dirscan() - */ - -int -file_time( - 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( - char *archive, - scanback func, - void *closure ) -{ -} - -# endif /* OS2 && !__EMX__ */ - diff --git a/jam-files/engine/filesys.c b/jam-files/engine/filesys.c deleted file mode 100644 index eb62ed40..00000000 --- a/jam-files/engine/filesys.c +++ /dev/null @@ -1,83 +0,0 @@ -# include "jam.h" -# include "pathsys.h" -# include "strings.h" -# include "newstr.h" -# include "filesys.h" -# include "lists.h" - -void file_build1( PATHNAME * f, string * file ) -{ - 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 ); - printf( "\n" ); - } - - /* 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] != '<' ) - string_push_back( file, '<' ); - string_append_range( - file, f->f_grist.ptr, f->f_grist.ptr + f->f_grist.len ); - if ( file->value[file->size - 1] != '>' ) - string_push_back( file, '>' ); - } -} - -static struct hash * filecache_hash = 0; -static file_info_t filecache_finfo; - -file_info_t * file_info(char * filename) -{ - file_info_t *finfo = &filecache_finfo; - - if ( !filecache_hash ) - filecache_hash = hashinit( sizeof( file_info_t ), "file_info" ); - - finfo->name = filename; - finfo->is_file = 0; - finfo->is_dir = 0; - finfo->size = 0; - finfo->time = 0; - finfo->files = 0; - if ( hashenter( filecache_hash, (HASHDATA**)&finfo ) ) - { - /* printf( "file_info: %s\n", filename ); */ - finfo->name = newstr( finfo->name ); - } - - return finfo; -} - -static LIST * files_to_remove = L0; - -static void remove_files_atexit(void) -{ - /* we do pop front in case this exit function is called - more than once */ - while ( files_to_remove ) - { - remove( files_to_remove->string ); - files_to_remove = list_pop_front( files_to_remove ); - } -} - -void file_done() -{ - remove_files_atexit(); - hashdone( filecache_hash ); -} - -void file_remove_atexit( const char * path ) -{ - files_to_remove = list_new( files_to_remove, newstr((char*)path) ); -} diff --git a/jam-files/engine/filesys.h b/jam-files/engine/filesys.h deleted file mode 100644 index efc081d1..00000000 --- a/jam-files/engine/filesys.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * filesys.h - OS specific file routines - */ - -#ifndef FILESYS_DWA20011025_H -# define FILESYS_DWA20011025_H - -# include "pathsys.h" -#include "hash.h" -#include "lists.h" - -typedef void (*scanback)( void *closure, char *file, int found, time_t t ); - -void file_dirscan( char *dir, scanback func, void *closure ); -void file_archscan( char *arch, scanback func, void *closure ); - -int file_time( char *filename, time_t *time ); - -void file_build1(PATHNAME *f, string* file) ; -int file_is_file(char* filename); -int file_mkdir(char *pathname); - -typedef struct file_info_t file_info_t ; -struct file_info_t -{ - char * name; - short is_file; - short is_dir; - unsigned long size; - time_t time; - LIST * files; -}; - - -/* Creates a pointer to information about file 'filename', creating it as - * necessary. If created, the structure will be default initialized. - */ -file_info_t * file_info( char * filename ); - -/* Returns information about a file, queries the OS if needed. */ -file_info_t * file_query( char * filename ); - -void file_done(); - -/* Marks a path/file to be removed when jam exits. */ -void file_remove_atexit( const char * path ); - -#endif diff --git a/jam-files/engine/fileunix.c b/jam-files/engine/fileunix.c deleted file mode 100644 index 680c3f53..00000000 --- a/jam-files/engine/fileunix.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Copyright 2005 Rene Rivera. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" -# include "filesys.h" -# include "strings.h" -# include "pathsys.h" -# include "newstr.h" -# include <stdio.h> -# include <sys/stat.h> - -#if defined(sun) || defined(__sun) || defined(linux) -# include <unistd.h> /* needed for read and close prototype */ -#endif - -# ifdef USE_FILEUNIX - -#if defined(sun) || defined(__sun) -# include <unistd.h> /* needed for read and close prototype */ -#endif - -# if defined( OS_SEQUENT ) || \ - defined( OS_DGUX ) || \ - defined( OS_SCO ) || \ - defined( OS_ISC ) -# define PORTAR 1 -# endif - -# ifdef __EMX__ -# include <sys/types.h> -# include <sys/stat.h> -# endif - -# if defined( OS_RHAPSODY ) || \ - defined( OS_MACOSX ) || \ - defined( OS_NEXT ) -/* need unistd for rhapsody's proper lseek */ -# include <sys/dir.h> -# include <unistd.h> -# define STRUCT_DIRENT struct direct -# else -# include <dirent.h> -# define STRUCT_DIRENT struct dirent -# endif - -# ifdef OS_COHERENT -# include <arcoff.h> -# define HAVE_AR -# endif - -# if defined( OS_MVS ) || \ - defined( OS_INTERIX ) - -#define ARMAG "!<arch>\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 OS_AIX -/* Define those for AIX to get the definitions for both the small and the - * big variant of the archive file format. */ -# define __AR_SMALL__ -# define __AR_BIG__ -# endif - -# include <ar.h> -# endif - -/* - * 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 - */ - - -/* - * file_dirscan() - scan a directory for files. - */ - -void file_dirscan( char * dir, scanback func, void * closure ) -{ - PROFILE_ENTER( FILE_DIRSCAN ); - - file_info_t * d = 0; - - d = file_query( dir ); - - if ( !d || !d->is_dir ) - { - PROFILE_EXIT( FILE_DIRSCAN ); - return; - } - - if ( ! d->files ) - { - LIST* files = L0; - PATHNAME f; - DIR *dd; - STRUCT_DIRENT *dirent; - string filename[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 : "."; - - /* Now enter contents of directory. */ - - if ( !( dd = opendir( dir ) ) ) - { - PROFILE_EXIT( FILE_DIRSCAN ); - return; - } - - if ( DEBUG_BINDSCAN ) - printf( "scan directory %s\n", dir ); - - string_new( filename ); - while ( ( dirent = readdir( dd ) ) ) - { - # 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 ); - - string_truncate( filename, 0 ); - path_build( &f, filename, 0 ); - - files = list_new( files, newstr(filename->value) ); - file_query( filename->value ); - } - string_free( filename ); - - closedir( dd ); - - d->files = files; - } - - /* Special case / : enter it */ - { - unsigned long len = strlen(d->name); - if ( ( len == 1 ) && ( d->name[0] == '/' ) ) - (*func)( closure, d->name, 1 /* stat()'ed */, d->time ); - } - - /* Now enter contents of directory */ - if ( d->files ) - { - LIST * files = d->files; - while ( files ) - { - file_info_t * ff = file_info( files->string ); - (*func)( closure, ff->name, 1 /* stat()'ed */, ff->time ); - files = list_next( files ); - } - } - - PROFILE_EXIT( FILE_DIRSCAN ); -} - - -file_info_t * file_query( char * filename ) -{ - file_info_t * ff = file_info( filename ); - if ( ! ff->time ) - { - struct stat statbuf; - - if ( stat( *filename ? filename : ".", &statbuf ) < 0 ) - return 0; - - ff->is_file = statbuf.st_mode & S_IFREG ? 1 : 0; - ff->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0; - ff->size = statbuf.st_size; - ff->time = statbuf.st_mtime ? statbuf.st_mtime : 1; - } - return ff; -} - -/* - * file_time() - get timestamp of file, if not done by file_dirscan() - */ - -int -file_time( - char *filename, - time_t *time ) -{ - file_info_t * ff = file_query( filename ); - if ( !ff ) return -1; - *time = ff->time; - return 0; -} - -int file_is_file(char* filename) -{ - file_info_t * ff = file_query( filename ); - if ( !ff ) return -1; - return ff->is_file; -} - -int file_mkdir(char* pathname) -{ - return mkdir(pathname, 0766); -} - -/* - * file_archscan() - scan an archive for files - */ - -# ifndef AIAMAG /* God-fearing UNIX */ - -# define SARFMAG 2 -# define SARHDR sizeof( struct ar_hdr ) - -void -file_archscan( - 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 ) -#ifdef ARFZMAG - /* OSF also has a compressed format */ - && memcmp( ar_hdr.ar_fmag, ARFZMAG, SARFMAG ) -#endif - ) ) - { - char lar_name_[257]; - char * lar_name = lar_name_ + 1; - long lar_date; - long lar_size; - long lar_offset; - char * c; - char * src; - char * dest; - - strncpy( lar_name, ar_hdr.ar_name, sizeof(ar_hdr.ar_name) ); - - sscanf( ar_hdr.ar_date, "%ld", &lar_date ); - sscanf( ar_hdr.ar_size, "%ld", &lar_size ); - - if (ar_hdr.ar_name[0] == '/') - { - 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 *)BJAM_MALLOC_ATOMIC(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. - */ - dest = lar_name; - lar_offset = atoi(lar_name + 1); - src = &string_table[lar_offset]; - while (*src != '/') - *dest++ = *src++; - *dest = '/'; - } - } - - c = lar_name - 1; - while ( ( *++c != ' ' ) && ( *c != '/' ) ) ; - *c = '\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 ); - - offset += SARHDR + ( ( lar_size + 1 ) & ~1 ); - lseek( fd, offset, 0 ); - } - - if (string_table) - BJAM_FREE(string_table); - - close( fd ); - -# endif /* NO_AR */ - -} - -# else /* AIAMAG - RS6000 AIX */ - -static void file_archscan_small( - int fd, char const *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; - - if ( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ) - return; - - 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 ); - } -} - -/* Check for OS version which supports the big variant. */ -#ifdef AR_HSZ_BIG - -static void file_archscan_big( - int fd, char const *archive, scanback func, void *closure) -{ - struct fl_hdr_big fl_hdr; - - struct { - struct ar_hdr_big hdr; - char pad[ 256 ]; - } ar_hdr ; - - char buf[ MAXJPATH ]; - long long offset; - - if ( read( fd, (char *)&fl_hdr, FL_HSZ_BIG) != FL_HSZ_BIG) - return; - - sscanf( fl_hdr.fl_fstmoff, "%lld", &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, "%lld", &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 ); - } - -} - -#endif /* AR_HSZ_BIG */ - -void file_archscan(char *archive, scanback func, void *closure) -{ - int fd; - char fl_magic[SAIAMAG]; - - if (( fd = open(archive, O_RDONLY, 0)) < 0) - return; - - if (read( fd, fl_magic, SAIAMAG) != SAIAMAG - || lseek(fd, 0, SEEK_SET) == -1) - { - close(fd); - return; - } - - if (strncmp(AIAMAG, fl_magic, SAIAMAG) == 0) - { - /* read small variant */ - file_archscan_small(fd, archive, func, closure); - } -#ifdef AR_HSZ_BIG - else if (strncmp(AIAMAGBIG, fl_magic, SAIAMAG) == 0) - { - /* read big variant */ - file_archscan_big(fd, archive, func, closure); - } -#endif - - close( fd ); -} - -# endif /* AIAMAG - RS6000 AIX */ - -# endif /* USE_FILEUNIX */ diff --git a/jam-files/engine/filevms.c b/jam-files/engine/filevms.c deleted file mode 100644 index d2ab2047..00000000 --- a/jam-files/engine/filevms.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_VMS - -/* - * 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 - */ - -# include <rms.h> -# include <iodef.h> -# include <ssdef.h> -# include <string.h> -# include <stdlib.h> -# include <stdio.h> -# include <descrip.h> - -#include <lbrdef.h> -#include <credef.h> -#include <mhddef.h> -#include <lhidef.h> -#include <lib$routines.h> -#include <starlet.h> - -/* Supply missing prototypes for lbr$-routines*/ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -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 ** ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -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( - char *dir, - scanback func, - void *closure ) -{ - - struct FAB xfab; - struct NAM xnam; - struct XABDAT xab; - char esa[256]; - char filename[256]; - string filename2[1]; - 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 = 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 */ ); - } - - string_new( filename2 ); - 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; - } - - string_truncate( filename2, 0 ); - 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->value, 1 /* time valid */, time ); - } - string_free( filename2 ); -} - -int -file_time( - 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( 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 = archive; - VMS_func = func; - VMS_closure = closure; - - status = lbr$ini_control( &context, &lfunc, &typ, NULL ); - if ( !( status & 1 ) ) - return; - - library.dsc$a_pointer = 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 */ diff --git a/jam-files/engine/frames.c b/jam-files/engine/frames.c deleted file mode 100644 index 84889f09..00000000 --- a/jam-files/engine/frames.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "frames.h" -# include "lists.h" - -void frame_init( FRAME* frame ) -{ - frame->prev = 0; - lol_init(frame->args); - frame->module = root_module(); - frame->rulename = "module scope"; - frame->procedure = 0; -} - -void frame_free( FRAME* frame ) -{ - lol_free( frame->args ); -} diff --git a/jam-files/engine/frames.h b/jam-files/engine/frames.h deleted file mode 100644 index 693d77fa..00000000 --- a/jam-files/engine/frames.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef FRAMES_DWA20011021_H -#define FRAMES_DWA20011021_H - -#include "lists.h" -#include "modules.h" - -typedef struct _PARSE PARSE; -typedef struct frame FRAME; - -struct frame -{ - FRAME * prev; - /* The nearest enclosing frame for which module->user_module is true. */ - FRAME * prev_user; - LOL args[ 1 ]; - module_t * module; - PARSE * procedure; - char * rulename; -}; - - -/* When call into Python is in progress, this variable points to the bjam frame - * that was current at the moment of call. When the call completes, the variable - * is not defined. Further, if Jam calls Python which calls Jam and so on, this - * variable only keeps the most recent Jam frame. - */ -extern struct frame * frame_before_python_call; - -void frame_init( FRAME * ); /* implemented in compile.c */ -void frame_free( FRAME * ); /* implemented in compile.c */ - -#endif diff --git a/jam-files/engine/glob.c b/jam-files/engine/glob.c deleted file mode 100644 index 527d6c80..00000000 --- a/jam-files/engine/glob.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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 - */ - -# 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( char * s, char * e, char * b ); - - -/* - * glob() - match a string against a simple pattern. - */ - -int glob( char * c, char * s ) -{ - char bitlist[ BITLISTSIZE ]; - 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; - 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( char * s, 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; - } - - /* Do not include \0 in either $[chars] or $[^chars]. */ - b[0] &= 0376; -} diff --git a/jam-files/engine/hash.c b/jam-files/engine/hash.c deleted file mode 100644 index fbd1a899..00000000 --- a/jam-files/engine/hash.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -# include "jam.h" -# include "hash.h" -# include "compile.h" -# include <assert.h> - -/* - * 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 - */ - -/* */ -#define HASH_DEBUG_PROFILE 1 -/* */ - -char *hashsccssid="@(#)hash.c 1.14 () 6/20/88"; - -/* 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(). Its 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 ] */ - ITEM *free; /* free list of items */ - 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; - - char * name; /* just for hashstats() */ -}; - -static void hashrehash( struct hash *hp ); -static void hashstat( struct hash *hp ); -static void * hash_mem_alloc(size_t datalen, size_t size); -static void hash_mem_free(size_t datalen, void * data); -#ifdef OPT_BOEHM_GC -static void hash_mem_finalizer(char * key, struct hash * hp); -#endif - -static unsigned int jenkins_one_at_a_time_hash(const unsigned char *key) -{ - unsigned int hash = 0; - - while ( *key ) - { - hash += *key++; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash; -} - -/* -static unsigned int knuth_hash(const unsigned char *key) -{ - unsigned int keyval = *key; - while ( *key ) - keyval = keyval * 2147059363 + *key++; - return keyval; -} -*/ - -static unsigned int hash_keyval( const char * key_ ) -{ - /* - return knuth_hash((const unsigned char *)key_); - */ - return jenkins_one_at_a_time_hash((const unsigned char *)key_); -} - -#define hash_bucket(hp,keyval) ((hp)->tab.base + ( (keyval) % (hp)->tab.nel )) - -/* Find the hash item for the given data. Returns pointer to the - item and if given a pointer to the item before the found item. - If it's the first item in a bucket, there is no previous item, - and zero is returned for the previous item instead. -*/ -static ITEM * hash_search( - struct hash *hp, - unsigned int keyval, - const char * keydata, - ITEM * * previous ) -{ - ITEM * i = *hash_bucket(hp,keyval); - ITEM * p = 0; - - for ( ; i; i = i->hdr.next ) - { - if ( ( keyval == i->hdr.keyval ) && - !strcmp( i->data.key, keydata ) ) - { - if (previous) - { - *previous = p; - } - return i; - } - p = i; - } - - return 0; -} - -/* - * hash_free() - remove the given item from the table if it's there. - * Returns 1 if found, 0 otherwise. - * - * NOTE: 2nd argument is HASHDATA*, not HASHDATA** as elsewhere. - */ -int -hash_free( - register struct hash *hp, - HASHDATA *data) -{ - ITEM * i = 0; - ITEM * prev = 0; - unsigned int keyval = hash_keyval(data->key); - - i = hash_search( hp, keyval, data->key, &prev ); - if (i) - { - /* mark it free so we skip it during enumeration */ - i->data.key = 0; - /* unlink the record from the hash chain */ - if (prev) prev->hdr.next = i->hdr.next; - else *hash_bucket(hp,keyval) = i->hdr.next; - /* link it into the freelist */ - i->hdr.next = hp->items.free; - hp->items.free = i; - /* we have another item */ - hp->items.more++; - - return 1; - } - return 0; -} - -/* - * hashitem() - find a record in the table, and optionally enter a new one - */ - -int -hashitem( - register struct hash *hp, - HASHDATA **data, - int enter ) -{ - register ITEM *i; - char *b = (*data)->key; - unsigned int keyval = hash_keyval(b); - - #ifdef HASH_DEBUG_PROFILE - profile_frame prof[1]; - if ( DEBUG_PROFILE ) - profile_enter( 0, prof ); - #endif - - if ( enter && !hp->items.more ) - hashrehash( hp ); - - if ( !enter && !hp->items.nel ) - { - #ifdef HASH_DEBUG_PROFILE - if ( DEBUG_PROFILE ) - profile_exit( prof ); - #endif - return 0; - } - - i = hash_search( hp, keyval, (*data)->key, 0 ); - if (i) - { - *data = &i->data; - #ifdef HASH_DEBUG_PROFILE - if ( DEBUG_PROFILE ) profile_exit( prof ); - #endif - return !0; - } - - if ( enter ) - { - ITEM * * base = hash_bucket(hp,keyval); - - /* try to grab one from the free list */ - if ( hp->items.free ) - { - i = hp->items.free; - hp->items.free = i->hdr.next; - assert( i->data.key == 0 ); - } - else - { - 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; - #ifdef OPT_BOEHM_GC - if (sizeof(HASHDATA) == hp->items.datalen) - { - GC_REGISTER_FINALIZER(i->data.key,&hash_mem_finalizer,hp,0,0); - } - #endif - } - - #ifdef HASH_DEBUG_PROFILE - if ( DEBUG_PROFILE ) - profile_exit( prof ); - #endif - 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 *)hash_mem_alloc( hp->items.datalen, hp->items.more * hp->items.size ); - hp->items.free = 0; - - 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 ) - hash_mem_free( hp->items.datalen, (char *)hp->tab.base ); - - hp->tab.nel = hp->items.nel * hp->bloat; - hp->tab.base = (ITEM **)hash_mem_alloc( hp->items.datalen, 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; - /* code currently assumes rehashing only when there are no free items */ - assert( i->data.key != 0 ); - - i->hdr.next = *ip; - *ip = i; - } - } -} - -void hashenumerate( struct hash * hp, void (* f)( void *, void * ), void * data ) -{ - int i; - for ( i = 0; i <= hp->items.list; ++i ) - { - char * next = hp->items.lists[i].base; - int nel = hp->items.lists[i].nel; - if ( i == hp->items.list ) - nel -= hp->items.more; - - for ( ; nel--; next += hp->items.size ) - { - ITEM * i = (ITEM *)next; - if ( i->data.key != 0 ) /* DO not enumerate freed items. */ - f( &i->data, data ); - } - } -} - -/* --- */ - -# define ALIGNED(x) ( ( x + sizeof( ITEM ) - 1 ) & ~( sizeof( ITEM ) - 1 ) ) - -/* - * hashinit() - initialize a hash table, returning a handle - */ - -struct hash * -hashinit( - int datalen, - char *name ) -{ - struct hash *hp = (struct hash *)hash_mem_alloc( datalen, sizeof( *hp ) ); - - hp->bloat = 3; - hp->tab.nel = 0; - hp->tab.base = (ITEM **)0; - hp->items.more = 0; - hp->items.free = 0; - hp->items.datalen = datalen; - hp->items.size = sizeof( struct hashhdr ) + ALIGNED( datalen ); - hp->items.list = -1; - hp->items.nel = 0; - hp->inel = 11 /* 47 */; - 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 || DEBUG_PROFILE ) - hashstat( hp ); - - if ( hp->tab.base ) - hash_mem_free( hp->items.datalen, (char *)hp->tab.base ); - for ( i = 0; i <= hp->items.list; ++i ) - hash_mem_free( hp->items.datalen, hp->items.lists[i].base ); - hash_mem_free( hp->items.datalen, (char *)hp ); -} - -static void * hash_mem_alloc(size_t datalen, size_t size) -{ - if (sizeof(HASHDATA) == datalen) - { - return BJAM_MALLOC_RAW(size); - } - else - { - return BJAM_MALLOC(size); - } -} - -static void hash_mem_free(size_t datalen, void * data) -{ - if (sizeof(HASHDATA) == datalen) - { - BJAM_FREE_RAW(data); - } - else - { - BJAM_FREE(data); - } -} - -#ifdef OPT_BOEHM_GC -static void hash_mem_finalizer(char * key, struct hash * hp) -{ - HASHDATA d; - d.key = key; - hash_free(hp,&d); -} -#endif - - -/* ---- */ - -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; - int 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+%luK) items+table+hash, %f density\n", - hp->name, - count, - hp->items.nel, - hp->tab.nel, - hp->items.nel * hp->items.size / 1024, - (long unsigned)hp->tab.nel * sizeof( ITEM ** ) / 1024, - (float)count / (float)sets ); -} diff --git a/jam-files/engine/hash.h b/jam-files/engine/hash.h deleted file mode 100644 index 7195b414..00000000 --- a/jam-files/engine/hash.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * hash.h - simple in-memory hashing routines - */ - -#ifndef BOOST_JAM_HASH_H -#define BOOST_JAM_HASH_H - -typedef struct hashdata HASHDATA; - -struct hash * hashinit ( int datalen, char * name ); -int hashitem ( struct hash * hp, HASHDATA * * data, int enter ); -void hashdone ( struct hash * hp ); -void hashenumerate( struct hash * hp, void (* f)( void *, void * ), void * data ); -int hash_free ( struct hash * hp, HASHDATA * data); - -#define hashenter( hp, data ) ( !hashitem( hp, data, !0 ) ) -#define hashcheck( hp, data ) hashitem( hp, data, 0 ) - -#endif diff --git a/jam-files/engine/hcache.c b/jam-files/engine/hcache.c deleted file mode 100644 index 70bb798c..00000000 --- a/jam-files/engine/hcache.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * This file has been donated to Jam. - */ - -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "rules.h" -# include "regexp.h" -# include "headers.h" -# include "newstr.h" -# include "hash.h" -# include "hcache.h" -# include "variable.h" -# include "search.h" - -#ifdef OPT_HEADER_CACHE_EXT - -/* - * Craig W. McPheeters, Alias|Wavefront. - * - * hcache.c hcache.h - handle cacheing of #includes in source files. - * - * Create a cache of files scanned for headers. When starting jam, look for the - * cache file and load it if present. When finished the binding phase, create a - * new header cache. The cache contains files, their timestamps and the header - * files found in their scan. During the binding phase of jam, look in the - * header cache first for the headers contained in a file. If the cache is - * present and valid, use its contents. This results in dramatic speedups with - * large projects (eg. 3min -> 1min startup for one project.) - * - * External routines: - * hcache_init() - read and parse the local .jamdeps file. - * hcache_done() - write a new .jamdeps file. - * hcache() - return list of headers on target. Use cache or do a scan. - * - * The dependency file format is an ASCII file with 1 line per target. Each line - * has the following fields: - * @boundname@ timestamp @file@ @file@ @file@ ... \n - */ - -typedef struct hcachedata HCACHEDATA ; - -struct hcachedata -{ - char * boundname; - time_t time; - LIST * includes; - LIST * hdrscan; /* the HDRSCAN value for this target */ - int age; /* if too old, we'll remove it from cache */ - HCACHEDATA * next; -}; - - -static struct hash * hcachehash = 0; -static HCACHEDATA * hcachelist = 0; - -static int queries = 0; -static int hits = 0; - -#define CACHE_FILE_VERSION "version 4" -#define CACHE_RECORD_HEADER "header" -#define CACHE_RECORD_END "end" - - -/* - * Return the name of the header cache file. May return NULL. - * - * The user sets this by setting the HCACHEFILE variable in a Jamfile. We cache - * the result so the user can not change the cache file during header scanning. - */ - -static char * cache_name( void ) -{ - static char * name = 0; - if ( !name ) - { - LIST * hcachevar = var_get( "HCACHEFILE" ); - - if ( hcachevar ) - { - TARGET * t = bindtarget( hcachevar->string ); - - pushsettings( t->settings ); - /* Do not expect the cache file to be generated, so pass 0 as the - * third argument to search. Expect the location to be specified via - * LOCATE, so pass 0 as the fourth arugment. - */ - t->boundname = search( t->name, &t->time, 0, 0 ); - popsettings( t->settings ); - - if ( hcachevar ) - name = copystr( t->boundname ); - } - } - return name; -} - - -/* - * Return the maximum age a cache entry can have before it is purged ftom the - * cache. - */ - -static int cache_maxage( void ) -{ - int age = 100; - LIST * var = var_get( "HCACHEMAXAGE" ); - if ( var ) - { - age = atoi( var->string ); - if ( age < 0 ) - age = 0; - } - return age; -} - - -/* - * Read a netstring. The caveat is that the string can not contain ASCII 0. The - * returned value is as returned by newstr(), so it need not be freed. - */ - -char * read_netstring( FILE * f ) -{ - unsigned long len; - static char * buf = NULL; - static unsigned long buf_len = 0; - - if ( fscanf( f, " %9lu", &len ) != 1 ) - return NULL; - if ( fgetc( f ) != (int)'\t' ) - return NULL; - - if ( len > 1024 * 64 ) - return NULL; /* sanity check */ - - if ( len > buf_len ) - { - unsigned long new_len = buf_len * 2; - if ( new_len < len ) - new_len = len; - buf = (char *)BJAM_REALLOC( buf, new_len + 1 ); - if ( buf ) - buf_len = new_len; - } - - if ( !buf ) - return NULL; - - if ( fread( buf, 1, len, f ) != len ) - return NULL; - if ( fgetc( f ) != (int)'\n' ) - return NULL; - - buf[ len ] = 0; - return newstr( buf ); -} - - -/* - * Write a netstring. - */ - -void write_netstring( FILE * f, char const * s ) -{ - if ( !s ) - s = ""; - fprintf( f, "%lu\t%s\n", (long unsigned)strlen( s ), s ); -} - - -void hcache_init() -{ - HCACHEDATA cachedata; - HCACHEDATA * c; - FILE * f; - char * version; - int header_count = 0; - char * hcachename; - - hcachehash = hashinit( sizeof( HCACHEDATA ), "hcache" ); - - if ( !( hcachename = cache_name() ) ) - return; - - if ( !( f = fopen( hcachename, "rb" ) ) ) - return; - - version = read_netstring( f ); - if ( !version || strcmp( version, CACHE_FILE_VERSION ) ) - { - fclose( f ); - return; - } - - while ( 1 ) - { - char * record_type; - char * time_str; - char * age_str; - char * includes_count_str; - char * hdrscan_count_str; - int i; - int count; - LIST * l; - - record_type = read_netstring( f ); - if ( !record_type ) - { - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - if ( !strcmp( record_type, CACHE_RECORD_END ) ) - break; - if ( strcmp( record_type, CACHE_RECORD_HEADER ) ) - { - fprintf( stderr, "invalid %s with record separator <%s>\n", - hcachename, record_type ? record_type : "<null>" ); - goto bail; - } - - c = &cachedata; - - c->boundname = read_netstring( f ); - time_str = read_netstring( f ); - age_str = read_netstring( f ); - includes_count_str = read_netstring( f ); - - if ( !c->boundname || !time_str || !age_str || !includes_count_str ) - { - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - - c->time = atoi( time_str ); - c->age = atoi( age_str ) + 1; - - count = atoi( includes_count_str ); - for ( l = 0, i = 0; i < count; ++i ) - { - char * s = read_netstring( f ); - if ( !s ) - { - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - l = list_new( l, s ); - } - c->includes = l; - - hdrscan_count_str = read_netstring( f ); - if ( !includes_count_str ) - { - list_free( c->includes ); - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - - count = atoi( hdrscan_count_str ); - for ( l = 0, i = 0; i < count; ++i ) - { - char * s = read_netstring( f ); - if ( !s ) - { - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - l = list_new( l, s ); - } - c->hdrscan = l; - - if ( !hashenter( hcachehash, (HASHDATA * *)&c ) ) - { - fprintf( stderr, "can't insert header cache item, bailing on %s\n", - hcachename ); - goto bail; - } - - c->next = hcachelist; - hcachelist = c; - - ++header_count; - } - - if ( DEBUG_HEADER ) - printf( "hcache read from file %s\n", hcachename ); - - bail: - fclose( f ); -} - - -void hcache_done() -{ - FILE * f; - HCACHEDATA * c; - int header_count = 0; - char * hcachename; - int maxage; - - if ( !hcachehash ) - return; - - if ( !( hcachename = cache_name() ) ) - return; - - if ( !( f = fopen( hcachename, "wb" ) ) ) - return; - - maxage = cache_maxage(); - - /* Print out the version. */ - write_netstring( f, CACHE_FILE_VERSION ); - - c = hcachelist; - for ( c = hcachelist; c; c = c->next ) - { - LIST * l; - char time_str[ 30 ]; - char age_str[ 30 ]; - char includes_count_str[ 30 ]; - char hdrscan_count_str[ 30 ]; - - if ( maxage == 0 ) - c->age = 0; - else if ( c->age > maxage ) - continue; - - sprintf( includes_count_str, "%lu", (long unsigned) list_length( c->includes ) ); - sprintf( hdrscan_count_str, "%lu", (long unsigned) list_length( c->hdrscan ) ); - sprintf( time_str, "%lu", (long unsigned) c->time ); - sprintf( age_str, "%lu", (long unsigned) c->age ); - - write_netstring( f, CACHE_RECORD_HEADER ); - write_netstring( f, c->boundname ); - write_netstring( f, time_str ); - write_netstring( f, age_str ); - write_netstring( f, includes_count_str ); - for ( l = c->includes; l; l = list_next( l ) ) - write_netstring( f, l->string ); - write_netstring( f, hdrscan_count_str ); - for ( l = c->hdrscan; l; l = list_next( l ) ) - write_netstring( f, l->string ); - fputs( "\n", f ); - ++header_count; - } - write_netstring( f, CACHE_RECORD_END ); - - if ( DEBUG_HEADER ) - printf( "hcache written to %s. %d dependencies, %.0f%% hit rate\n", - hcachename, header_count, queries ? 100.0 * hits / queries : 0 ); - - fclose ( f ); -} - - -LIST * hcache( TARGET * t, int rec, regexp * re[], LIST * hdrscan ) -{ - HCACHEDATA cachedata; - HCACHEDATA * c = &cachedata; - - LIST * l = 0; - - ++queries; - - c->boundname = t->boundname; - - if (hashcheck (hcachehash, (HASHDATA **) &c)) - { - if (c->time == t->time) - { - LIST *l1 = hdrscan, *l2 = c->hdrscan; - while (l1 && l2) { - if (l1->string != l2->string) { - l1 = NULL; - } else { - l1 = list_next(l1); - l2 = list_next(l2); - } - } - if (l1 || l2) { - if (DEBUG_HEADER) - printf("HDRSCAN out of date in cache for %s\n", - t->boundname); - - printf("HDRSCAN out of date for %s\n", t->boundname); - printf(" real : "); - list_print(hdrscan); - printf("\n cached: "); - list_print(c->hdrscan); - printf("\n"); - - list_free(c->includes); - list_free(c->hdrscan); - c->includes = 0; - c->hdrscan = 0; - } else { - if (DEBUG_HEADER) - printf ("using header cache for %s\n", t->boundname); - c->age = 0; - ++hits; - l = list_copy (0, c->includes); - return l; - } - } else { - if (DEBUG_HEADER) - printf ("header cache out of date for %s\n", t->boundname); - list_free (c->includes); - list_free(c->hdrscan); - c->includes = 0; - c->hdrscan = 0; - } - } else { - if (hashenter (hcachehash, (HASHDATA **)&c)) { - c->boundname = newstr (c->boundname); - c->next = hcachelist; - hcachelist = c; - } - } - - /* 'c' points at the cache entry. Its out of date. */ - - l = headers1 (0, t->boundname, rec, re); - - c->time = t->time; - c->age = 0; - c->includes = list_copy (0, l); - c->hdrscan = list_copy(0, hdrscan); - - return l; -} - -#endif diff --git a/jam-files/engine/hcache.h b/jam-files/engine/hcache.h deleted file mode 100644 index c316e3bc..00000000 --- a/jam-files/engine/hcache.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * This file is not part of Jam - */ - -/* - * hcache.h - handle #includes in source files - */ -#ifndef HCACHE_H -# define HCACHE_H - -# include "regexp.h" -# include "lists.h" - -void hcache_init(void); -void hcache_done(void); -LIST *hcache(TARGET *t, int rec, regexp *re[], LIST *hdrscan); - -#endif diff --git a/jam-files/engine/hdrmacro.c b/jam-files/engine/hdrmacro.c deleted file mode 100644 index 43031d48..00000000 --- a/jam-files/engine/hdrmacro.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# 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" -# include "strings.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) <target> : <resolved included files> ; - * - * 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. - */ - -/* this type is used to store a dictionary of file header macros */ -typedef struct header_macro -{ - char * symbol; - 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 ) -{ - static regexp *re = 0; - FILE *f; - char buf[ 1024 ]; - - 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.. */ - if ( re == 0 ) - { - re = regex_compile( - "^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*" - "[<\"]([^\">]*)[\">].*$" ); - } - - if ( !( f = fopen( t->boundname, "r" ) ) ) - return; - - while ( fgets( buf, sizeof( buf ), f ) ) - { - HEADER_MACRO var; - HEADER_MACRO *v = &var; - - if ( regexec( re, buf ) && re->startp[1] ) - { - /* we detected a line that looks like "#define MACRO filename */ - re->endp[1][0] = '\0'; - re->endp[2][0] = '\0'; - - if ( DEBUG_HEADER ) - printf( "macro '%s' used to define filename '%s' in '%s'\n", - re->startp[1], re->startp[2], t->boundname ); - - /* add macro definition to hash table */ - if ( !header_macros_hash ) - header_macros_hash = hashinit( sizeof( HEADER_MACRO ), "hdrmacros" ); - - v->symbol = re->startp[1]; - v->filename = 0; - if ( hashenter( header_macros_hash, (HASHDATA **)&v ) ) - { - v->symbol = newstr( re->startp[1] ); /* never freed */ - v->filename = newstr( re->startp[2] ); /* never freed */ - } - /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */ - /* WE MIGHT AS WELL USE A LIST TO STORE THEM.. */ - } - } - - fclose( f ); -} - - -char * macro_header_get( const char * macro_name ) -{ - HEADER_MACRO var; - HEADER_MACRO * 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 v->filename; - } - return 0; -} diff --git a/jam-files/engine/hdrmacro.h b/jam-files/engine/hdrmacro.h deleted file mode 100644 index 08cc1116..00000000 --- a/jam-files/engine/hdrmacro.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * 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 <filename> or - * #define MACRO "filename" definitions - */ - -void macro_headers( TARGET *t ); - -char* macro_header_get( const char* macro_name ); diff --git a/jam-files/engine/headers.c b/jam-files/engine/headers.c deleted file mode 100644 index b9d8f637..00000000 --- a/jam-files/engine/headers.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# 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 "hdrmacro.h" -# include "newstr.h" - -#ifdef OPT_HEADER_CACHE_EXT -# include "hcache.h" -#endif - -/* - * 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) <target> : <include files> ; - * - * 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. - */ - -#ifndef OPT_HEADER_CACHE_EXT -static LIST *headers1( LIST *l, char *file, int rec, regexp *re[]); -#endif - -/* - * headers() - scan a target for include files and call HDRRULE - */ - -# define MAXINC 10 - -void -headers( TARGET *t ) -{ - LIST * hdrscan; - LIST * hdrrule; - #ifndef OPT_HEADER_CACHE_EXT - LIST * headlist = 0; - #endif - regexp * re[ MAXINC ]; - int rec = 0; - - if ( !( hdrscan = var_get( "HDRSCAN" ) ) || - !( hdrrule = var_get( "HDRRULE" ) ) ) - return; - - if ( DEBUG_HEADER ) - printf( "header scan %s\n", t->name ); - - /* Compile all regular expressions in HDRSCAN */ - while ( ( rec < MAXINC ) && hdrscan ) - { - re[ rec++ ] = regex_compile( hdrscan->string ); - hdrscan = list_next( hdrscan ); - } - - /* Doctor up call to HDRRULE rule */ - /* Call headers1() to get LIST of included files. */ - { - FRAME frame[1]; - frame_init( frame ); - lol_add( frame->args, list_new( L0, t->name ) ); -#ifdef OPT_HEADER_CACHE_EXT - lol_add( frame->args, hcache( t, rec, re, hdrscan ) ); -#else - lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) ); -#endif - - if ( lol_get( frame->args, 1 ) ) - { - /* The third argument to HDRRULE is the bound name of - * $(<) */ - lol_add( frame->args, list_new( L0, t->boundname ) ); - - list_free( evaluate_rule( hdrrule->string, frame ) ); - } - - /* Clean up. */ - frame_free( frame ); - } -} - - -/* - * headers1() - using regexp, scan a file and build include LIST. - */ - -#ifdef OPT_HEADER_CACHE_EXT -LIST * -#else -static LIST * -#endif -headers1( - LIST * l, - char * file, - int rec, - regexp * re[] ) -{ - FILE * f; - char buf[ 1024 ]; - int i; - static regexp * re_macros = 0; - -#ifdef OPT_IMPROVED_PATIENCE_EXT - static int count = 0; - ++count; - if ( ((count == 100) || !( count % 1000 )) && DEBUG_MAKE ) - printf("...patience...\n"); -#endif - - /* the following regexp is used to detect cases where a */ - /* file is included through a line line "#include MACRO" */ - if ( re_macros == 0 ) - re_macros = regex_compile( - "^[ ]*#[ ]*include[ ]*([A-Za-z][A-Za-z0-9_]*).*$" ); - - if ( !( f = fopen( file, "r" ) ) ) - return l; - - while ( fgets( buf, sizeof( buf ), f ) ) - { - int size = strlen( buf ); - /* Remove trailing \r and \n, if any. */ - while ( ( size > 0 ) && - ( buf[ size - 1 ] == '\n' ) && - ( buf[ size - 1 ] == '\r' ) ) - { - buf[ size - 1 ] = '\0'; - --size; - } - - for ( i = 0; i < rec; ++i ) - if ( regexec( re[i], buf ) && re[i]->startp[1] ) - { - re[i]->endp[1][0] = '\0'; - - if ( DEBUG_HEADER ) - printf( "header found: %s\n", re[i]->startp[1] ); - - l = list_new( l, newstr( re[i]->startp[1] ) ); - } - - /* special treatment for #include MACRO */ - if ( regexec( re_macros, buf ) && re_macros->startp[1] ) - { - char* header_filename; - - re_macros->endp[1][0] = '\0'; - - if ( DEBUG_HEADER ) - printf( "macro header found: %s", re_macros->startp[1] ); - - header_filename = macro_header_get( re_macros->startp[1] ); - if ( header_filename ) - { - if ( DEBUG_HEADER ) - printf( " resolved to '%s'\n", header_filename ); - l = list_new( l, newstr( header_filename ) ); - } - else - { - if ( DEBUG_HEADER ) - printf( " ignored !!\n" ); - } - } - } - - fclose( f ); - - return l; -} - - -void regerror( char * s ) -{ - printf( "re error %s\n", s ); -} diff --git a/jam-files/engine/headers.h b/jam-files/engine/headers.h deleted file mode 100644 index 624475fe..00000000 --- a/jam-files/engine/headers.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 ); - -#ifdef OPT_HEADER_CACHE_EXT -struct regexp; -LIST *headers1( LIST *l, char *file, int rec, struct regexp *re[] ); -#endif diff --git a/jam-files/engine/jam.c b/jam-files/engine/jam.c deleted file mode 100644 index e11d082b..00000000 --- a/jam-files/engine/jam.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * /+\ - * +\ 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. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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 - * hdrmacro.c - handle header file parsing for filename macro definitions - * 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 - */ - - -#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" -#include "strings.h" -#include "expand.h" -#include "filesys.h" -#include "output.h" - -/* Macintosh is "special" */ -#ifdef OS_MAC - #include <QuickDraw.h> -#endif - -/* And UNIX for this. */ -#ifdef unix - #include <sys/utsname.h> - #include <signal.h> -#endif - -struct globs globs = -{ - 0, /* noexec */ - 1, /* jobs */ - 0, /* quitquick */ - 0, /* newestfirst */ - 0, /* pipes action stdout and stderr merged to action output */ -#ifdef OS_MAC - { 0, 0 }, /* debug - suppress tracing output */ -#else - { 0, 1 }, /* debug ... */ -#endif - 0, /* output commands, not run them */ - 0 /* action timeout */ -}; - -/* Symbols to be defined as true for use in Jambase. */ -static 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 - -/* on Win32-LCC */ -#if defined( OS_NT ) && defined( __LCC__ ) - #define use_environ _environ -#endif - -# if defined( __MWERKS__) - #define use_environ _environ - extern char * * _environ; -#endif - -#ifndef use_environ - #define use_environ environ - #if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT ) - extern char **environ; - #endif -#endif - -#if YYDEBUG != 0 - extern int yydebug; -#endif - -#ifndef NDEBUG -static void run_unit_tests() -{ -#if defined( USE_EXECNT ) - extern void execnt_unit_test(); - execnt_unit_test(); -#endif - string_unit_test(); - var_expand_unit_test(); -} -#endif - -int anyhow = 0; - -#ifdef HAVE_PYTHON - extern PyObject * bjam_call ( PyObject * self, PyObject * args ); - extern PyObject * bjam_import_rule ( PyObject * self, PyObject * args ); - extern PyObject * bjam_define_action( PyObject * self, PyObject * args ); - extern PyObject * bjam_variable ( PyObject * self, PyObject * args ); - extern PyObject * bjam_backtrace ( PyObject * self, PyObject * args ); - extern PyObject * bjam_caller ( PyObject * self, PyObject * args ); -#endif - -char *saved_argv0; - -int main( int argc, char * * argv, char * * arg_environ ) -{ - int n; - char * s; - struct bjam_option optv[N_OPTS]; - char const * all = "all"; - int status; - int arg_c = argc; - char * * arg_v = argv; - char const * progname = argv[0]; - - saved_argv0 = argv[0]; - - BJAM_MEM_INIT(); - -# ifdef OS_MAC - InitGraf(&qd.thePort); -# endif - - --argc; - ++argv; - - if ( getoptions( argc, argv, "-:l:d:j:p:f:gs:t:ano:qv", optv ) < 0 ) - { - printf( "\nusage: %s [ options ] targets...\n\n", progname ); - - printf( "-a Build all targets, even if they are current.\n" ); - printf( "-dx Set the debug level to x (0-9).\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( "-lx Limit actions to x number of seconds after which they are stopped.\n" ); - printf( "-n Don't actually execute the updating actions.\n" ); - printf( "-ox Write the updating actions to file x.\n" ); - printf( "-px x=0, pipes action stdout and stderr merged into action output.\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" ); - printf( "--x Option is ignored.\n\n" ); - - exit( EXITBAD ); - } - - /* Version info. */ - if ( ( s = getoptval( optv, 'v', 0 ) ) ) - { - printf( "Boost.Jam " ); - printf( "Version %s. %s.\n", VERSION, OSMINOR ); - printf( " Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. \n" ); - printf( " Copyright 2001 David Turner.\n" ); - printf( " Copyright 2001-2004 David Abrahams.\n" ); - printf( " Copyright 2002-2008 Rene Rivera.\n" ); - printf( " Copyright 2003-2008 Vladimir Prus.\n" ); - - return EXITOK; - } - - /* Pick up interesting options. */ - if ( ( s = getoptval( optv, 'n', 0 ) ) ) - globs.noexec++, globs.debug[2] = 1; - - if ( ( s = getoptval( optv, 'p', 0 ) ) ) - { - /* Undocumented -p3 (acts like both -p1 -p2) means separate pipe action - * stdout and stderr. - */ - globs.pipe_action = atoi( s ); - if ( ( 3 < globs.pipe_action ) || ( globs.pipe_action < 0 ) ) - { - printf( - "Invalid pipe descriptor '%d', valid values are -p[0..3].\n", - globs.pipe_action ); - exit( EXITBAD ); - } - } - - 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 (globs.jobs == 0) - { - printf("Invalid value for the '-j' option.\n"); - exit(EXITBAD); - } - } - - if ( ( s = getoptval( optv, 'g', 0 ) ) ) - globs.newestfirst = 1; - - if ( ( s = getoptval( optv, 'l', 0 ) ) ) - globs.timeout = atoi( s ); - - /* Turn on/off debugging */ - for ( n = 0; ( s = getoptval( optv, 'd', n ) ); ++n ) - { - int i; - - /* First -d, turn off defaults. */ - if ( !n ) - for ( i = 0; i < DEBUG_MAX; ++i ) - globs.debug[i] = 0; - - i = atoi( s ); - - if ( ( i < 0 ) || ( i >= DEBUG_MAX ) ) - { - printf( "Invalid debug level '%s'.\n", s ); - continue; - } - - /* n turns on levels 1-n. */ - /* +n turns on level n. */ - if ( *s == '+' ) - globs.debug[i] = 1; - else while ( i ) - globs.debug[i--] = 1; - } - - { - PROFILE_ENTER( MAIN ); - -#ifdef HAVE_PYTHON - { - PROFILE_ENTER( MAIN_PYTHON ); - Py_Initialize(); - { - static PyMethodDef BjamMethods[] = { - {"call", bjam_call, METH_VARARGS, - "Call the specified bjam rule."}, - {"import_rule", bjam_import_rule, METH_VARARGS, - "Imports Python callable to bjam."}, - {"define_action", bjam_define_action, METH_VARARGS, - "Defines a command line action."}, - {"variable", bjam_variable, METH_VARARGS, - "Obtains a variable from bjam's global module."}, - {"backtrace", bjam_backtrace, METH_VARARGS, - "Returns bjam backtrace from the last call into Python."}, - {"caller", bjam_caller, METH_VARARGS, - "Returns the module from which the last call into Python is made."}, - {NULL, NULL, 0, NULL} - }; - - Py_InitModule( "bjam", BjamMethods ); - } - PROFILE_EXIT( MAIN_PYTHON ); - } -#endif - -#ifndef NDEBUG - run_unit_tests(); -#endif -#if YYDEBUG != 0 - if ( DEBUG_PARSE ) - yydebug = 1; -#endif - - /* Set JAMDATE. */ - var_set( "JAMDATE", list_new( L0, outf_time(time(0)) ), VAR_SET ); - - /* Set JAM_VERSION. */ - var_set( "JAM_VERSION", - list_new( list_new( list_new( L0, - newstr( VERSION_MAJOR_SYM ) ), - newstr( VERSION_MINOR_SYM ) ), - newstr( VERSION_PATCH_SYM ) ), - VAR_SET ); - - /* Set JAMUNAME. */ -#ifdef unix - { - struct utsname u; - - if ( uname( &u ) >= 0 ) - { - var_set( "JAMUNAME", - list_new( - list_new( - list_new( - list_new( - list_new( L0, - newstr( u.sysname ) ), - newstr( u.nodename ) ), - newstr( u.release ) ), - newstr( u.version ) ), - newstr( u.machine ) ), VAR_SET ); - } - } -#endif /* unix */ - - /* Load up environment variables. */ - - /* First into the global module, with splitting, for backward - * compatibility. - */ - var_defines( use_environ, 1 ); - - /* Then into .ENVIRON, without splitting. */ - enter_module( bindmodule(".ENVIRON") ); - var_defines( use_environ, 0 ); - exit_module( bindmodule(".ENVIRON") ); - - /* - * Jam defined variables OS & OSPLAT. We load them after environment, so - * that setting OS in environment does not change Jam's notion of the - * current platform. - */ - var_defines( othersyms, 1 ); - - /* Load up variables set on command line. */ - for ( n = 0; ( s = getoptval( optv, 's', n ) ); ++n ) - { - char *symv[2]; - symv[ 0 ] = s; - symv[ 1 ] = 0; - var_defines( symv, 1 ); - enter_module( bindmodule(".ENVIRON") ); - var_defines( symv, 0 ); - exit_module( bindmodule(".ENVIRON") ); - } - - /* Set the ARGV to reflect the complete list of arguments of invocation. - */ - for ( n = 0; n < arg_c; ++n ) - var_set( "ARGV", list_new( L0, newstr( arg_v[n] ) ), VAR_APPEND ); - - /* Initialize built-in rules. */ - load_builtins(); - - /* Add the targets in the command line to the update list. */ - for ( n = 1; n < arg_c; ++n ) - { - if ( arg_v[ n ][ 0 ] == '-' ) - { - char * f = "-:l:d:j:f:gs:t:ano:qv"; - for ( ; *f; ++f ) if ( *f == arg_v[ n ][ 1 ] ) break; - if ( ( f[ 1 ] == ':' ) && ( arg_v[ n ][ 2 ] == '\0' ) ) ++n; - } - else - { - mark_target_for_updating( arg_v[ n ] ); - } - } - - if (!targets_to_update()) - mark_target_for_updating("all"); - - /* Parse ruleset. */ - { - FRAME frame[ 1 ]; - frame_init( frame ); - for ( n = 0; ( s = getoptval( optv, 'f', n ) ); ++n ) - parse_file( s, frame ); - - if ( !n ) - parse_file( "+", frame ); - } - - status = yyanyerrors(); - - /* Manually touch -t targets. */ - for ( n = 0; ( s = getoptval( optv, 't', n ) ); ++n ) - touch_target( s ); - - /* If an output file is specified, set globs.cmdout to that. */ - if ( ( s = getoptval( optv, 'o', 0 ) ) ) - { - if ( !( globs.cmdout = fopen( s, "w" ) ) ) - { - printf( "Failed to write to '%s'\n", s ); - exit( EXITBAD ); - } - ++globs.noexec; - } - - /* The build system may set the PARALLELISM variable to override -j - options. */ - { - LIST *p = L0; - p = var_get ("PARALLELISM"); - if (p) - { - int j = atoi (p->string); - if (j == -1) - { - printf( "Invalid value of PARALLELISM: %s\n", p->string); - } - else - { - globs.jobs = j; - } - } - } - - /* KEEP_GOING overrides -q option. */ - { - LIST *p = L0; - p = var_get ("KEEP_GOING"); - if (p) - { - int v = atoi (p->string); - if (v == 0) - globs.quitquick = 1; - else - globs.quitquick = 0; - } - } - - /* Now make target. */ - { - PROFILE_ENTER( MAIN_MAKE ); - - LIST * targets = targets_to_update(); - if (targets) - { - int targets_count = list_length( targets ); - const char * * targets2 = (const char * *) - BJAM_MALLOC( targets_count * sizeof( char * ) ); - int n = 0; - for ( ; targets; targets = list_next( targets ) ) - targets2[ n++ ] = targets->string; - status |= make( targets_count, targets2, anyhow ); - free( targets ); - } - else - { - status = last_update_now_status; - } - - PROFILE_EXIT( MAIN_MAKE ); - } - - PROFILE_EXIT( MAIN ); - } - - if ( DEBUG_PROFILE ) - profile_dump(); - - /* Widely scattered cleanup. */ - var_done(); - file_done(); - rules_done(); - stamps_done(); - str_done(); - - /* Close cmdout. */ - if ( globs.cmdout ) - fclose( globs.cmdout ); - -#ifdef HAVE_PYTHON - Py_Finalize(); -#endif - - BJAM_MEM_CLOSE(); - - return status ? EXITBAD : EXITOK; -} - -#if defined(_WIN32) -#include <windows.h> -char *executable_path(char *argv0) { - char buf[1024]; - DWORD ret = GetModuleFileName(NULL, buf, sizeof(buf)); - if (ret == 0 || ret == sizeof(buf)) return NULL; - return strdup (buf); -} -#elif defined(__APPLE__) /* Not tested */ -#include <mach-o/dyld.h> -char *executable_path(char *argv0) { - char buf[1024]; - uint32_t size = sizeof(buf); - int ret = _NSGetExecutablePath(buf, &size); - if (ret != 0) return NULL; - return strdup(buf); -} -#elif defined(sun) || defined(__sun) /* Not tested */ -#include <stdlib.h> - -char *executable_path(char *argv0) { - return strdup(getexecname()); -} -#elif defined(__FreeBSD__) -#include <sys/sysctl.h> -char *executable_path(char *argv0) { - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; - char buf[1024]; - size_t size = sizeof(buf); - sysctl(mib, 4, buf, &size, NULL, 0); - if (size == 0 || size == sizeof(buf)) return NULL; - return strndup(buf, size); -} -#elif defined(__linux__) -#include <unistd.h> -char *executable_path(char *argv0) { - char buf[1024]; - ssize_t ret = readlink("/proc/self/exe", buf, sizeof(buf)); - if (ret == 0 || ret == sizeof(buf)) return NULL; - return strndup(buf, ret); -} -#else -char *executable_path(char *argv0) { - /* If argv0 is absolute path, assume it's the right absolute path. */ - if (argv0[0] == "/") - return strdup(argv0); - return NULL; -} -#endif diff --git a/jam-files/engine/jam.h b/jam-files/engine/jam.h deleted file mode 100644 index 73a7a04c..00000000 --- a/jam-files/engine/jam.h +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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/18/00 (belmonte)- Support for Cygwin. - * 09/12/00 (seiwald) - OSSYMS split to OSMAJOR/OSMINOR/OSPLAT - * 12/29/00 (seiwald) - OSVER dropped. - */ - -#ifndef JAM_H_VP_2003_08_01 -#define JAM_H_VP_2003_08_01 - -#ifdef HAVE_PYTHON -#include <Python.h> -#endif - -/* Assume popen support is available unless known otherwise. */ -#define HAVE_POPEN 1 - -/* - * VMS, OPENVMS - */ - -#ifdef VMS - -#include <types.h> -#include <file.h> -#include <stat.h> -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <unixlib.h> - -#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 - -/* This may be inaccurate. */ -#ifndef __DECC -#define OSPLAT "OSPLAT=VAX" -#endif - -#endif - -/* - * Windows NT - */ - -#ifdef NT - -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include <malloc.h> -#ifndef __MWERKS__ - #include <memory.h> -#endif -#include <signal.h> -#include <string.h> -#include <time.h> - -#define OSMAJOR "NT=true" -#define OSMINOR "OS=NT" -#define OS_NT -#define SPLITPATH ';' -/* Windows NT 3.51 only allows 996 chars per line, but we deal with the problem - * in "execnt.c". - */ -#define MAXLINE (maxline()) /* longest 'together' actions */ -#define USE_EXECNT -#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 - -/* Metrowerks Standard Library on Windows. */ - -#ifdef __MSL__ - #undef HAVE_POPEN -#endif - -# endif - -/* - * Windows MingW32 - */ - -#ifdef MINGW - -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include <malloc.h> -#include <memory.h> -#include <signal.h> -#include <string.h> -#include <time.h> - -#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 <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include <malloc.h> -#include <signal.h> -#include <string.h> -#include <time.h> - -#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 - -#ifdef __EMX__ - #define USE_FILEUNIX -#endif - -#endif - -/* - * Macintosh MPW - */ - -#ifdef macintosh - -#include <time.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#define OSMAJOR "MAC=true" -#define OSMINOR "OS=MAC" -#define OS_MAC -#define SPLITPATH ',' - -#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 MAXLINE 23552 /* 24k - 1k, longest 'together' actions */ - #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 -#if defined(__cygwin__) || defined(__CYGWIN__) - #define OSMINOR "OS=CYGWIN" - #define OS_CYGWIN -#endif -#if defined(__FreeBSD__) && !defined(__DragonFly__) - #define OSMINOR "OS=FREEBSD" - #define OS_FREEBSD -#endif -#ifdef __DragonFly__ - #define OSMINOR "OS=DRAGONFLYBSD" - #define OS_DRAGONFLYBSD -#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__ - #define unix - #ifdef __QNXNTO__ - #define OSMINOR "OS=QNXNTO" - #define OS_QNXNTO - #else - #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__ - #ifndef unix - #define unix - #endif - #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 -#ifdef __OpenBSD__ - #define OSMINOR "OS=OPENBSD" - #define OS_OPENBSD - #define unix -#endif -#if defined (__FreeBSD_kernel__) && !defined(__FreeBSD__) - #define OSMINOR "OS=KFREEBSD" - #define OS_KFREEBSD -#endif -#ifndef OSMINOR - #define OSMINOR "OS=UNKNOWN" -#endif - -/* All the UNIX includes */ - -#include <sys/types.h> -#include <sys/stat.h> - -#ifndef OS_MPEIX - #include <sys/file.h> -#endif - -#include <fcntl.h> -#include <stdio.h> -#include <ctype.h> -#include <signal.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#ifndef OS_QNX - #include <memory.h> -#endif - -#ifndef OS_ULTRIX - #include <stdlib.h> -#endif - -#if !defined( OS_BSDI ) && \ - !defined( OS_FREEBSD ) && \ - !defined( OS_DRAGONFLYBSD ) && \ - !defined( OS_NEXT ) && \ - !defined( OS_MACHTEN ) && \ - !defined( OS_MACOSX ) && \ - !defined( OS_RHAPSODY ) && \ - !defined( OS_MVS ) && \ - !defined( OS_OPENBSD ) - #include <malloc.h> -#endif - -#endif - -/* - * OSPLAT definitions - suppressed when it is a one-of-a-kind. - */ - -#if defined( _M_PPC ) || \ - defined( PPC ) || \ - defined( ppc ) || \ - 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( __i386 ) || \ - defined( _M_IX86 ) - #define OSPLAT "OSPLAT=X86" -#endif - -#if defined( __ia64__ ) || \ - defined( __IA64__ ) || \ - defined( __ia64 ) - #define OSPLAT "OSPLAT=IA64" -#endif - -#if defined( __x86_64__ ) || \ - defined( __amd64__ ) || \ - defined( _M_AMD64 ) - #define OSPLAT "OSPLAT=X86_64" -#endif - - -#if defined( __sparc__ ) || \ - defined( __sparc ) - #define OSPLAT "OSPLAT=SPARC" -#endif - -#ifdef __mips__ - #define OSPLAT "OSPLAT=MIPS" -#endif - -#ifdef __arm__ - #define OSPLAT "OSPLAT=ARM" -#endif - -#ifdef __s390__ - #define OSPLAT "OSPLAT=390" -#endif - -#ifdef __hppa - #define OSPLAT "OSPLAT=PARISC" -#endif - -#ifndef OSPLAT - #define OSPLAT "" -#endif - -/* - * Jam implementation misc. - */ - -#ifndef MAXLINE - #define MAXLINE 102400 /* longest 'together' actions' */ -#endif - -#ifndef EXITOK - #define EXITOK 0 - #define EXITBAD 1 -#endif - -#ifndef SPLITPATH - #define SPLITPATH ':' -#endif - -/* You probably do not need to muck with these. */ - -#define MAXSYM 1024 /* longest symbol in the environment */ -#define MAXJPATH 1024 /* longest filename */ - -#define MAXJOBS 64 /* silently enforced -j limit */ -#define MAXARGC 32 /* words in $(JAMSHELL) */ - -/* Jam private definitions below. */ - -#define DEBUG_MAX 14 - - -struct globs -{ - int noexec; - int jobs; - int quitquick; - int newestfirst; /* build newest sources first */ - int pipe_action; - char debug[ DEBUG_MAX ]; - FILE * cmdout; /* print cmds, not run them */ - long timeout; /* number of seconds to limit actions to, - * default 0 for no limit. - */ - int dart; /* output build and test results formatted for Dart */ -}; - -extern struct globs globs; - -#define DEBUG_MAKE ( globs.debug[ 1 ] ) /* show actions when executed */ -#define DEBUG_MAKEQ ( globs.debug[ 2 ] ) /* show even quiet actions */ -#define DEBUG_EXEC ( globs.debug[ 2 ] ) /* show text of actons */ -#define DEBUG_MAKEPROG ( globs.debug[ 3 ] ) /* show progress of make0 */ -#define DEBUG_BIND ( globs.debug[ 3 ] ) /* show when files bound */ - -#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_PROFILE ( globs.debug[ 10 ] ) /* dump rule execution times */ -#define DEBUG_PARSE ( globs.debug[ 11 ] ) /* debug parsing */ -#define DEBUG_GRAPH ( globs.debug[ 12 ] ) /* debug dependencies */ -#define DEBUG_FATE ( globs.debug[ 13 ] ) /* show changes to fate in make0() */ - -/* Everyone gets the memory definitions. */ -#include "mem.h" - -/* They also get the profile functions. */ -#include "debug.h" - -#endif diff --git a/jam-files/engine/jambase.c b/jam-files/engine/jambase.c deleted file mode 100644 index b15282bc..00000000 --- a/jam-files/engine/jambase.c +++ /dev/null @@ -1,1691 +0,0 @@ -/* Generated by mkjambase from Jambase */ -char *jambase[] = { -/* Jambase */ -"if $(NT)\n", -"{\n", -"SLASH ?= \\\\ ;\n", -"}\n", -"SLASH ?= / ;\n", -"rule find-to-root ( dir : patterns + )\n", -"{\n", -"local globs = [ GLOB $(dir) : $(patterns) ] ;\n", -"while ! $(globs) && $(dir:P) != $(dir)\n", -"{\n", -"dir = $(dir:P) ;\n", -"globs = [ GLOB $(dir) : $(patterns) ] ;\n", -"}\n", -"return $(globs) ;\n", -"}\n", -".boost-build-file = ;\n", -".bootstrap-file = ;\n", -"BOOST_BUILD_PATH.user-value = $(BOOST_BUILD_PATH) ;\n", -"if ! $(BOOST_BUILD_PATH) && $(UNIX)\n", -"{\n", -"BOOST_BUILD_PATH = /usr/share/boost-build ;\n", -"}\n", -"rule _poke ( module-name ? : variables + : value * )\n", -"{\n", -"module $(<)\n", -"{\n", -"$(>) = $(3) ;\n", -"}\n", -"}\n", -"rule boost-build ( dir ? )\n", -"{\n", -"if $(.bootstrap-file)\n", -"{\n", -"ECHO \"Error: Illegal attempt to re-bootstrap the build system by invoking\" ;\n", -"ECHO ;\n", -"ECHO \" 'boost-build\" $(dir) \";'\" ;\n", -"ECHO ;\n", -"EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n", -"}\n", -"BOOST_BUILD_PATH = $(dir:R=$(.boost-build-file:D)) $(BOOST_BUILD_PATH) ;\n", -"_poke .ENVIRON : BOOST_BUILD_PATH : $(BOOST_BUILD_PATH) ;\n", -"local bootstrap-file = [ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;\n", -".bootstrap-file = $(bootstrap-file[1]) ;\n", -"if ! $(.bootstrap-file)\n", -"{\n", -"ECHO \"Unable to load Boost.Build: could not find build system.\" ;\n", -"ECHO --------------------------------------------------------- ;\n", -"ECHO \"$(.boost-build-file) attempted to load the build system by invoking\" ;\n", -"ECHO ;\n", -"ECHO \" 'boost-build\" $(dir) \";'\" ;\n", -"ECHO ;\n", -"ECHO \"but we were unable to find \\\"bootstrap.jam\\\" in the specified directory\" ;\n", -"ECHO \"or in BOOST_BUILD_PATH (searching \"$(BOOST_BUILD_PATH:J=\", \")\").\" ;\n", -"ECHO ;\n", -"EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n", -"}\n", -"if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n", -"{\n", -"ECHO \"notice: loading Boost.Build from\"\n", -"[ NORMALIZE_PATH $(.bootstrap-file:D) ] ;\n", -"}\n", -"include $(.bootstrap-file) ;\n", -"}\n", -"if [ MATCH .*(b2).* : $(ARGV[1]:BL) ] \n", -"|| [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]\n", -"|| $(BOOST_ROOT) # A temporary measure so Jam works with Boost.Build v1.\n", -"{\n", -"local search-path = $(BOOST_BUILD_PATH) $(BOOST_ROOT) ;\n", -"local self = [ SELF_PATH ] ;\n", -"local boost-build-relative = ../../share/boost-build ;\n", -"local self-based-path = [ NORMALIZE_PATH $(boost-build-relative:R=$(self)) ] ;\n", -"local boost-build-files =\n", -"[ find-to-root [ PWD ] : boost-build.jam ]\n", -"[ GLOB $(self-based-path) : boost-build.jam ]\n", -"[ GLOB $(search-path) : boost-build.jam ] ;\n", -".boost-build-file = $(boost-build-files[1]) ;\n", -"if ! $(.boost-build-file)\n", -"{\n", -"ECHO \"Unable to load Boost.Build: could not find \\\"boost-build.jam\\\"\" ;\n", -"ECHO --------------------------------------------------------------- ;\n", -"if ! [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]\n", -"{\n", -"ECHO \"BOOST_ROOT must be set, either in the environment, or \" ;\n", -"ECHO \"on the command-line with -sBOOST_ROOT=..., to the root\" ;\n", -"ECHO \"of the boost installation.\" ;\n", -"ECHO ;\n", -"}\n", -"ECHO \"Attempted search from\" [ PWD ] \"up to the root\" ;\n", -"ECHO \"at\" $(self-based-path) ;\n", -"ECHO \"and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: \"$(search-path:J=\", \")\".\" ;\n", -"EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n", -"}\n", -"if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n", -"{\n", -"ECHO \"notice: found boost-build.jam at\"\n", -"[ NORMALIZE_PATH $(.boost-build-file) ] ;\n", -"}\n", -"include $(.boost-build-file) ;\n", -"if ! $(.bootstrap-file)\n", -"{\n", -"ECHO \"Unable to load Boost.Build\" ;\n", -"ECHO -------------------------- ;\n", -"ECHO \"\\\"$(.boost-build-file)\\\" was found by searching from\" [ PWD ] \"up to the root\" ;\n", -"ECHO \"and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: \"$(search-path:J=\", \")\".\" ;\n", -"ECHO ;\n", -"ECHO \"However, it failed to call the \\\"boost-build\\\" rule to indicate\" ;\n", -"ECHO \"the location of the build system.\" ;\n", -"ECHO ;\n", -"EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n", -"}\n", -"}\n", -"else\n", -"{\n", -"if $(NT)\n", -"{\n", -"local SUPPORTED_TOOLSETS = \"BORLANDC\" \"VC7\" \"VISUALC\" \"VISUALC16\" \"INTELC\" \"WATCOM\"\n", -"\"MINGW\" \"LCC\" ;\n", -"TOOLSET = \"\" ;\n", -"if $(JAM_TOOLSET)\n", -"{\n", -"local t ;\n", -"for t in $(SUPPORTED_TOOLSETS)\n", -"{\n", -"$(t) = $($(t):J=\" \") ; # reconstitute paths with spaces in them\n", -"if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; }\n", -"}\n", -"if ! $(TOOLSET)\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", -"for t in $(SUPPORTED_TOOLSETS) { ECHO \" \" $(t) ; }\n", -"EXIT ;\n", -"}\n", -"}\n", -"if ! $(TOOLSET)\n", -"{\n", -"if $(BCCROOT)\n", -"{\n", -"TOOLSET = BORLANDC ;\n", -"BORLANDC = $(BCCROOT:J=\" \") ;\n", -"}\n", -"else if $(MSVC)\n", -"{\n", -"TOOLSET = VISUALC16 ;\n", -"VISUALC16 = $(MSVC:J=\" \") ;\n", -"}\n", -"else if $(MSVCNT)\n", -"{\n", -"TOOLSET = VISUALC ;\n", -"VISUALC = $(MSVCNT:J=\" \") ;\n", -"}\n", -"else if $(MSVCDir)\n", -"{\n", -"TOOLSET = VISUALC ;\n", -"VISUALC = $(MSVCDir:J=\" \") ;\n", -"}\n", -"else if $(MINGW)\n", -"{\n", -"TOOLSET = MINGW ;\n", -"}\n", -"else\n", -"{\n", -"ECHO \"Jam cannot be run because, either:\" ;\n", -"ECHO \" a. You didn't set BOOST_ROOT to indicate the root of your\" ;\n", -"ECHO \" Boost installation.\" ;\n", -"ECHO \" b. You are trying to use stock Jam but didn't indicate which\" ;\n", -"ECHO \" compilation toolset to use. To do so, follow these simple\" ;\n", -"ECHO \" 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 \" BORLANDC Borland C++ BC++ install path\" ;\n", -"ECHO \" VISUALC Microsoft Visual C++ VC++ install path\" ;\n", -"ECHO \" VISUALC16 Microsoft Visual C++ 16 bit VC++ 16 bit install\" ;\n", -"ECHO \" INTELC Intel C/C++ IC++ install path\" ;\n", -"ECHO \" WATCOM Watcom C/C++ Watcom install path\" ;\n", -"ECHO \" MINGW MinGW (gcc) MinGW install path\" ;\n", -"ECHO \" LCC Win32-LCC LCC-Win32 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 VISUALC=C:\\\\Visual6\" ;\n", -"ECHO \" set JAM_TOOLSET=VISUALC\" ;\n", -"EXIT ;\n", -"}\n", -"}\n", -"CP ?= copy ;\n", -"RM ?= del /f/q ;\n", -"SLASH ?= \\\\ ;\n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .obj ;\n", -"SUFEXE ?= .exe ;\n", -"if $(TOOLSET) = BORLANDC\n", -"{\n", -"ECHO \"Compiler is Borland C++\" ;\n", -"AR ?= tlib /C /P64 ;\n", -"CC ?= bcc32 ;\n", -"CCFLAGS ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus ;\n", -"C++ ?= bcc32 ;\n", -"C++FLAGS ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus -P ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= $(CCFLAGS) ;\n", -"STDLIBPATH ?= $(BORLANDC)\\\\lib ;\n", -"STDHDRS ?= $(BORLANDC)\\\\include ;\n", -"NOARSCAN ?= true ;\n", -"}\n", -"else if $(TOOLSET) = VISUALC16\n", -"{\n", -"ECHO \"Compiler is Microsoft Visual C++ 16 bit\" ;\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", -"\\\"$(VISUALC16)\\\\lib\\\\mlibce.lib\\\"\n", -"\\\"$(VISUALC16)\\\\lib\\\\oldnames.lib\\\"\n", -";\n", -"LINKLIBS ?= ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= $(VISUALC16)\\\\include ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = VISUALC\n", -"{\n", -"ECHO \"Compiler is Microsoft Visual C++\" ;\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 ?= \\\"$(VISUALC)\\\\lib\\\\advapi32.lib\\\"\n", -"\\\"$(VISUALC)\\\\lib\\\\gdi32.lib\\\"\n", -"\\\"$(VISUALC)\\\\lib\\\\user32.lib\\\"\n", -"\\\"$(VISUALC)\\\\lib\\\\kernel32.lib\\\" ;\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= $(VISUALC)\\\\include ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = VC7\n", -"{\n", -"ECHO \"Compiler is Microsoft Visual C++ .NET\" ;\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 ?= \\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\advapi32.lib\\\"\n", -"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\gdi32.lib\\\"\n", -"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\user32.lib\\\"\n", -"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\kernel32.lib\\\" ;\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= \\\"$(VISUALC)\\\\include\\\"\n", -"\\\"$(VISUALC)\\\\PlatformSDK\\\\include\\\" ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = INTELC\n", -"{\n", -"ECHO \"Compiler is Intel C/C++\" ;\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", -"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\\\\kernel32.lib\n", -";\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= $(INTELC)\\include $(VISUALC)\\\\include ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = WATCOM\n", -"{\n", -"ECHO \"Compiler is Watcom C/C++\" ;\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", -"}\n", -"else if $(TOOLSET) = MINGW\n", -"{\n", -"ECHO \"Compiler is GCC with Mingw\" ;\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 $(TOOLSET) = LCC\n", -"{\n", -"ECHO \"Compiler is Win32-LCC\" ;\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\n", -"{\n", -"EXIT On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the\n", -"Borland or Microsoft directories. ;\n", -"}\n", -"}\n", -"else if $(OS2)\n", -"{\n", -"local SUPPORTED_TOOLSETS = \"EMX\" \"WATCOM\" ;\n", -"TOOLSET = \"\" ;\n", -"if $(JAM_TOOLSET)\n", -"{\n", -"local t ;\n", -"for t in $(SUPPORTED_TOOLSETS)\n", -"{\n", -"$(t) = $($(t):J=\" \") ; # reconstitute paths with spaces in them\n", -"if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; }\n", -"}\n", -"if ! $(TOOLSET)\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", -"for t in $(SUPPORTED_TOOLSETS) { ECHO \" \" $(t) ; }\n", -"EXIT ;\n", -"}\n", -"}\n", -"if ! $(TOOLSET)\n", -"{\n", -"if $(watcom)\n", -"{\n", -"WATCOM = $(watcom:J=\" \") ;\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 \" VISUALAGE IBM Visual Age C/C++ VisualAge 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", -"RM = del /f ;\n", -"CP = copy ;\n", -"MV ?= move ;\n", -"DOT ?= . ;\n", -"DOTDOT ?= .. ;\n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .obj ;\n", -"SUFEXE ?= .exe ;\n", -"if $(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", -"LINK ?= wcl386 ;\n", -"LINKFLAGS ?= /zq ; # zq=quiet\n", -"LINKLIBS ?= ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= ;\n", -"SLASH ?= \\\\ ;\n", -"STDHDRS ?= $(WATCOM)\\\\h ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(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", -"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", -"CW ?= \"{CW}\" ;\n", -"MACHDRS ?=\n", -"\"$(UMACHDRS):Universal:Interfaces:CIncludes\"\n", -"\"$(CW):MSL:MSL_C:MSL_Common:Include\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Include\" ;\n", -"MACLIBS ?=\n", -"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib\"\n", -"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib\" ;\n", -"MPWLIBS ?=\n", -"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib\" ;\n", -"MPWNLLIBS ?=\n", -"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW(NL).Lib\" ;\n", -"SIOUXHDRS ?= ;\n", -"SIOUXLIBS ?=\n", -"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.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", -"C++ ?= mwcppc ;\n", -"C++FLAGS ?= -w off -nomapcr ;\n", -"CC ?= mwcppc ;\n", -"CCFLAGS ?= -w off -nomapcr ;\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 && $(METROWERKS)\n", -"{\n", -"AR ?= mwld -xml -o ;\n", -"BINDIR ?= /boot/apps ;\n", -"CC ?= mwcc ;\n", -"CCFLAGS ?= -nosyspath ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= -nosyspath ;\n", -"FORTRAN ?= \"\" ;\n", -"LIBDIR ?= /boot/develop/libraries ;\n", -"LINK ?= mwld ;\n", -"LINKFLAGS ?= \"\" ;\n", -"MANDIR ?= /boot/documentation/\"Shell Tools\"/HTML ;\n", -"NOARSCAN ?= true ;\n", -"STDHDRS ?= /boot/develop/headers/posix ;\n", -"}\n", -"else if $(OS) = BEOS\n", -"{\n", -"BINDIR ?= /boot/apps ;\n", -"CC ?= gcc ;\n", -"C++ ?= $(CC) ;\n", -"FORTRAN ?= \"\" ;\n", -"LIBDIR ?= /boot/develop/libraries ;\n", -"LINK ?= gcc ;\n", -"LINKLIBS ?= -lnet ;\n", -"NOARSCAN ?= true ;\n", -"STDHDRS ?= /boot/develop/headers/posix ;\n", -"}\n", -"else if $(UNIX)\n", -"{\n", -"switch $(OS)\n", -"{\n", -"case AIX :\n", -"LINKLIBS ?= -lbsd ;\n", -"case AMIGA :\n", -"CC ?= gcc ;\n", -"YACC ?= \"bison -y\" ;\n", -"case CYGWIN :\n", -"CC ?= gcc ;\n", -"CCFLAGS += -D__cygwin__ ;\n", -"LEX ?= flex ;\n", -"RANLIB ?= \"\" ;\n", -"SUFEXE ?= .exe ;\n", -"YACC ?= \"bison -y\" ;\n", -"case DGUX :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\n", -"case HPUX :\n", -"YACC = ;\n", -"CFLAGS += -Ae ;\n", -"CCFLAGS += -Ae ;\n", -"RANLIB ?= \"\" ;\n", -"case INTERIX :\n", -"CC ?= gcc ;\n", -"RANLIB ?= \"\" ;\n", -"case IRIX :\n", -"RANLIB ?= \"\" ;\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", -"case MVS :\n", -"RANLIB ?= \"\" ;\n", -"case NEXT :\n", -"AR ?= libtool -o ;\n", -"RANLIB ?= \"\" ;\n", -"case MACOSX :\n", -"AR ?= libtool -o ;\n", -"C++ ?= c++ ;\n", -"MANDIR ?= /usr/local/share/man ;\n", -"RANLIB ?= \"\" ;\n", -"case NCR :\n", -"RANLIB ?= \"\" ;\n", -"case PTX :\n", -"RANLIB ?= \"\" ;\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", -"case SCO :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\n", -"case SINIX :\n", -"RANLIB ?= \"\" ;\n", -"case SOLARIS :\n", -"RANLIB ?= \"\" ;\n", -"AR ?= \"/usr/ccs/bin/ar ru\" ;\n", -"case UNICOS :\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= -O0 ;\n", -"case UNIXWARE :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\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", -"YACCFILES ?= y.tab ;\n", -"YACCFLAGS ?= -d ;\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", -"RSH ?= rsh ;\n", -"SED ?= sed ;\n", -"SHELLHEADER ?= \"#!/bin/sh\" ;\n", -"SHELLMODE ?= 755 ;\n", -"SLASH ?= / ;\n", -"STDHDRS ?= /usr/include ;\n", -"SUFEXE ?= \"\" ;\n", -"SUFLIB ?= .a ;\n", -"SUFOBJ ?= .o ;\n", -"UNDEFFLAG ?= \"-u _\" ;\n", -"YACC ?= ;\n", -"YACCFILES ?= ;\n", -"YACCFLAGS ?= ;\n", -"HDRPATTERN =\n", -"\"^[ ]*#[ ]*include[ ]*[<\\\"]([^\\\">]*)[\\\">].*$\" ;\n", -"OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;\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", -"rule As\n", -"{\n", -"DEPENDS $(<) : $(>) ;\n", -"ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;\n", -"}\n", -"rule Bulk\n", -"{\n", -"local i ;\n", -"for i in $(>)\n", -"{\n", -"File $(i:D=$(<)) : $(i) ;\n", -"}\n", -"}\n", -"rule Cc\n", -"{\n", -"local _h ;\n", -"DEPENDS $(<) : $(>) ;\n", -"CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;\n", -"if $(RELOCATE)\n", -"{\n", -"CcMv $(<) : $(>) ;\n", -"}\n", -"_h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n", -"if $(VMS) && $(_h)\n", -"{\n", -"SLASHINC on $(<) = \"/inc=(\" $(_h[1]) ,$(_h[2-]) \")\" ;\n", -"}\n", -"else if $(MAC) && $(_h)\n", -"{\n", -"local _i _j ;\n", -"_j = $(_h[1]) ;\n", -"for _i in $(_h[2-])\n", -"{\n", -"_j = $(_j),$(_i) ;\n", -"}\n", -"MACINC on $(<) = \\\"$(_j)\\\" ;\n", -"}\n", -"}\n", -"rule C++\n", -"{\n", -"local _h ;\n", -"DEPENDS $(<) : $(>) ;\n", -"C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;\n", -"if $(RELOCATE)\n", -"{\n", -"CcMv $(<) : $(>) ;\n", -"}\n", -"_h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n", -"if $(VMS) && $(_h)\n", -"{\n", -"SLASHINC on $(<) = \"/inc=(\" $(_h[1]) ,$(_h[2-]) \")\" ;\n", -"}\n", -"else if $(MAC) && $(_h)\n", -"{\n", -"local _i _j ;\n", -"_j = $(_h[1]) ;\n", -"for _i in $(_h[2-])\n", -"{\n", -"_j = $(_j),$(_i) ;\n", -"}\n", -"MACINC on $(<) = \\\"$(_j)\\\" ;\n", -"}\n", -"}\n", -"rule Chmod\n", -"{\n", -"if $(CHMOD) { Chmod1 $(<) ; }\n", -"}\n", -"rule File\n", -"{\n", -"DEPENDS files : $(<) ;\n", -"DEPENDS $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"MODE on $(<) = $(FILEMODE) ;\n", -"Chmod $(<) ;\n", -"}\n", -"rule Fortran\n", -"{\n", -"DEPENDS $(<) : $(>) ;\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", -"rule GenFile1\n", -"{\n", -"MakeLocate $(<) : $(LOCATE_SOURCE) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"}\n", -"rule HardLink\n", -"{\n", -"DEPENDS files : $(<) ;\n", -"DEPENDS $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"}\n", -"rule HdrMacroFile\n", -"{\n", -"HDRMACRO $(<) ;\n", -"}\n", -"rule HdrRule\n", -"{\n", -"local s ;\n", -"if $(HDRGRIST)\n", -"{\n", -"s = $(>:G=$(HDRGRIST)) ;\n", -"} else {\n", -"s = $(>) ;\n", -"}\n", -"INCLUDES $(<) : $(s) ;\n", -"SEARCH on $(s) = $(HDRSEARCH) ;\n", -"NOCARE $(s) ;\n", -"HDRSEARCH on $(s) = $(HDRSEARCH) ;\n", -"HDRSCAN on $(s) = $(HDRSCAN) ;\n", -"HDRRULE on $(s) = $(HDRRULE) ;\n", -"HDRGRIST on $(s) = $(HDRGRIST) ;\n", -"}\n", -"rule InstallInto\n", -"{\n", -"local i t ;\n", -"t = $(>:G=$(INSTALLGRIST)) ;\n", -"Depends install : $(t) ;\n", -"Clean uninstall : $(t) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"MakeLocate $(t) : $(<) ;\n", -"for i in $(>)\n", -"{\n", -"local tt = $(i:G=$(INSTALLGRIST)) ;\n", -"Depends $(tt) : $(i) ;\n", -"Install $(tt) : $(i) ;\n", -"Chmod $(tt) ;\n", -"if $(OWNER) && $(CHOWN)\n", -"{\n", -"Chown $(tt) ;\n", -"OWNER on $(tt) = $(OWNER) ;\n", -"}\n", -"if $(GROUP) && $(CHGRP)\n", -"{\n", -"Chgrp $(tt) ;\n", -"GROUP on $(tt) = $(GROUP) ;\n", -"}\n", -"}\n", -"}\n", -"rule InstallBin\n", -"{\n", -"local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;\n", -"InstallInto $(<) : $(_t) ;\n", -"MODE on $(_t:G=installed) = $(EXEMODE) ;\n", -"}\n", -"rule InstallFile\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=installed) = $(FILEMODE) ;\n", -"}\n", -"rule InstallLib\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=installed) = $(FILEMODE) ;\n", -"}\n", -"rule InstallMan\n", -"{\n", -"local i s d ;\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", -"d = man$(s) ;\n", -"InstallInto $(d:R=$(<)) : $(i) ;\n", -"}\n", -"MODE on $(>:G=installed) = $(FILEMODE) ;\n", -"}\n", -"rule InstallShell\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=installed) = $(SHELLMODE) ;\n", -"}\n", -"rule Lex\n", -"{\n", -"LexMv $(<) : $(>) ;\n", -"DEPENDS $(<) : $(>) ;\n", -"MakeLocate $(<) : $(LOCATE_SOURCE) ;\n", -"Clean clean : $(<) ;\n", -"}\n", -"rule Library\n", -"{\n", -"LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", -"Objects $(>) ;\n", -"}\n", -"rule LibraryFromObjects\n", -"{\n", -"local _i _l _s ;\n", -"_s = [ FGristFiles $(>) ] ;\n", -"_l = $(<:S=$(SUFLIB)) ;\n", -"if $(KEEPOBJS)\n", -"{\n", -"DEPENDS obj : $(_s) ;\n", -"}\n", -"else\n", -"{\n", -"DEPENDS lib : $(_l) ;\n", -"}\n", -"if ! $(_l:D)\n", -"{\n", -"MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;\n", -"}\n", -"if $(NOARSCAN)\n", -"{\n", -"DEPENDS $(_l) : $(_s) ;\n", -"}\n", -"else\n", -"{\n", -"DEPENDS $(_l) : $(_l)($(_s:BS)) ;\n", -"for _i in $(_s)\n", -"{\n", -"DEPENDS $(_l)($(_i:BS)) : $(_i) ;\n", -"}\n", -"}\n", -"Clean clean : $(_l) ;\n", -"if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }\n", -"Archive $(_l) : $(_s) ;\n", -"if $(RANLIB) { Ranlib $(_l) ; }\n", -"if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(_l) : $(_s) ; }\n", -"}\n", -"rule Link\n", -"{\n", -"MODE on $(<) = $(EXEMODE) ;\n", -"Chmod $(<) ;\n", -"}\n", -"rule LinkLibraries\n", -"{\n", -"local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", -"DEPENDS $(_t) : $(>:S=$(SUFLIB)) ;\n", -"NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;\n", -"}\n", -"rule Main\n", -"{\n", -"MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", -"Objects $(>) ;\n", -"}\n", -"rule MainFromObjects\n", -"{\n", -"local _s _t ;\n", -"_s = [ FGristFiles $(>) ] ;\n", -"_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", -"if $(_t) != $(<)\n", -"{\n", -"DEPENDS $(<) : $(_t) ;\n", -"NOTFILE $(<) ;\n", -"}\n", -"DEPENDS exe : $(_t) ;\n", -"DEPENDS $(_t) : $(_s) ;\n", -"MakeLocate $(_t) : $(LOCATE_TARGET) ;\n", -"Clean clean : $(_t) ;\n", -"Link $(_t) : $(_s) ;\n", -"}\n", -"rule MakeLocate\n", -"{\n", -"if $(>)\n", -"{\n", -"LOCATE on $(<) = $(>) ;\n", -"Depends $(<) : $(>[1]) ;\n", -"MkDir $(>[1]) ;\n", -"}\n", -"}\n", -"rule MkDir\n", -"{\n", -"NOUPDATE $(<) ;\n", -"if $(<) != $(DOT) && ! $($(<)-mkdir)\n", -"{\n", -"local s ;\n", -"$(<)-mkdir = true ;\n", -"MkDir1 $(<) ;\n", -"Depends dirs : $(<) ;\n", -"s = $(<:P) ;\n", -"if $(NT)\n", -"{\n", -"switch $(s)\n", -"{\n", -"case *: : s = ;\n", -"case *:\\\\ : s = ;\n", -"}\n", -"}\n", -"if $(s) && $(s) != $(<)\n", -"{\n", -"Depends $(<) : $(s) ;\n", -"MkDir $(s) ;\n", -"}\n", -"else if $(s)\n", -"{\n", -"NOTFILE $(s) ;\n", -"}\n", -"}\n", -"}\n", -"rule Object\n", -"{\n", -"local h ;\n", -"Clean clean : $(<) ;\n", -"MakeLocate $(<) : $(LOCATE_TARGET) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"HDRS on $(<) = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n", -"if $(SEARCH_SOURCE)\n", -"{\n", -"h = $(SEARCH_SOURCE) ;\n", -"}\n", -"else\n", -"{\n", -"h = \"\" ;\n", -"}\n", -"HDRRULE on $(>) = HdrRule ;\n", -"HDRSCAN on $(>) = $(HDRPATTERN) ;\n", -"HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ;\n", -"HDRGRIST on $(>) = $(HDRGRIST) ;\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 .f : Fortran $(<) : $(>) ;\n", -"case .l : Cc $(<) : $(<:S=.c) ;\n", -"Lex $(<:S=.c) : $(>) ;\n", -"case .s : As $(<) : $(>) ;\n", -"case .y : Cc $(<) : $(<:S=.c) ;\n", -"Yacc $(<:S=.c) : $(>) ;\n", -"case * : UserObject $(<) : $(>) ;\n", -"}\n", -"}\n", -"rule ObjectCcFlags\n", -"{\n", -"CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", -"}\n", -"rule ObjectC++Flags\n", -"{\n", -"C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", -"}\n", -"rule ObjectHdrs\n", -"{\n", -"HDRS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", -"}\n", -"rule Objects\n", -"{\n", -"local _i ;\n", -"for _i in [ FGristFiles $(<) ]\n", -"{\n", -"Object $(_i:S=$(SUFOBJ)) : $(_i) ;\n", -"DEPENDS obj : $(_i:S=$(SUFOBJ)) ;\n", -"}\n", -"}\n", -"rule RmTemps\n", -"{\n", -"TEMPORARY $(>) ;\n", -"}\n", -"rule Setuid\n", -"{\n", -"MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;\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", -"rule SubDir\n", -"{\n", -"local _r _s ;\n", -"if ! $($(<[1]))\n", -"{\n", -"if ! $(<[1])\n", -"{\n", -"EXIT SubDir syntax error ;\n", -"}\n", -"$(<[1]) = [ FSubDir $(<[2-]) ] ;\n", -"}\n", -"if ! $($(<[1])-included)\n", -"{\n", -"$(<[1])-included = TRUE ;\n", -"_r = $($(<[1])RULES) ;\n", -"if ! $(_r)\n", -"{\n", -"_r = $(JAMRULES:R=$($(<[1]))) ;\n", -"}\n", -"include $(_r) ;\n", -"}\n", -"_s = [ FDirName $(<[2-]) ] ;\n", -"SUBDIR = $(_s:R=$($(<[1]))) ;\n", -"SUBDIR_TOKENS = $(<[2-]) ;\n", -"SEARCH_SOURCE = $(SUBDIR) ;\n", -"LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", -"LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", -"SOURCE_GRIST = [ FGrist $(<[2-]) ] ;\n", -"SUBDIRCCFLAGS = ;\n", -"SUBDIRC++FLAGS = ;\n", -"SUBDIRHDRS = ;\n", -"}\n", -"rule SubDirCcFlags\n", -"{\n", -"SUBDIRCCFLAGS += $(<) ;\n", -"}\n", -"rule SubDirC++Flags\n", -"{\n", -"SUBDIRC++FLAGS += $(<) ;\n", -"}\n", -"rule SubDirHdrs\n", -"{\n", -"SUBDIRHDRS += $(<) ;\n", -"}\n", -"rule SubInclude\n", -"{\n", -"local _s ;\n", -"if ! $($(<[1]))\n", -"{\n", -"EXIT Top level of source tree has not been set with $(<[1]) ;\n", -"}\n", -"_s = [ FDirName $(<[2-]) ] ;\n", -"include $(JAMFILE:D=$(_s):R=$($(<[1]))) ;\n", -"}\n", -"rule Undefines\n", -"{\n", -"UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;\n", -"}\n", -"rule UserObject\n", -"{\n", -"EXIT \"Unknown suffix on\" $(>) \"- see UserObject rule in Jamfile(5).\" ;\n", -"}\n", -"rule Yacc\n", -"{\n", -"local _h ;\n", -"_h = $(<:BS=.h) ;\n", -"MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;\n", -"if $(YACC)\n", -"{\n", -"DEPENDS $(<) $(_h) : $(>) ;\n", -"Yacc1 $(<) $(_h) : $(>) ;\n", -"YaccMv $(<) $(_h) : $(>) ;\n", -"Clean clean : $(<) $(_h) ;\n", -"}\n", -"INCLUDES $(<) : $(_h) ;\n", -"}\n", -"rule FGrist\n", -"{\n", -"local _g _i ;\n", -"_g = $(<[1]) ;\n", -"for _i in $(<[2-])\n", -"{\n", -"_g = $(_g)!$(_i) ;\n", -"}\n", -"return $(_g) ;\n", -"}\n", -"rule FGristFiles\n", -"{\n", -"if ! $(SOURCE_GRIST)\n", -"{\n", -"return $(<) ;\n", -"}\n", -"else\n", -"{\n", -"return $(<:G=$(SOURCE_GRIST)) ;\n", -"}\n", -"}\n", -"rule FGristSourceFiles\n", -"{\n", -"if ! $(SOURCE_GRIST)\n", -"{\n", -"return $(<) ;\n", -"}\n", -"else\n", -"{\n", -"local _i _o ;\n", -"for _i in $(<)\n", -"{\n", -"switch $(_i)\n", -"{\n", -"case *.h : _o += $(_i) ;\n", -"case * : _o += $(_i:G=$(SOURCE_GRIST)) ;\n", -"}\n", -"}\n", -"return $(_o) ;\n", -"}\n", -"}\n", -"rule FConcat\n", -"{\n", -"local _t _r ;\n", -"$(_r) = $(<[1]) ;\n", -"for _t in $(<[2-])\n", -"{\n", -"$(_r) = $(_r)$(_t) ;\n", -"}\n", -"return $(_r) ;\n", -"}\n", -"rule FSubDir\n", -"{\n", -"local _i _d ;\n", -"if ! $(<[1])\n", -"{\n", -"_d = $(DOT) ;\n", -"}\n", -"else\n", -"{\n", -"_d = $(DOTDOT) ;\n", -"for _i in $(<[2-])\n", -"{\n", -"_d = $(_d:R=$(DOTDOT)) ;\n", -"}\n", -"}\n", -"return $(_d) ;\n", -"}\n", -"rule FDirName\n", -"{\n", -"local _s _i ;\n", -"if ! $(<)\n", -"{\n", -"_s = $(DOT) ;\n", -"}\n", -"else if $(VMS)\n", -"{\n", -"switch $(<[1])\n", -"{\n", -"case *:* : _s = $(<[1]) ;\n", -"case \\\\[*\\\\] : _s = $(<[1]) ;\n", -"case * : _s = [.$(<[1])] ;\n", -"}\n", -"for _i in [.$(<[2-])]\n", -"{\n", -"_s = $(_i:R=$(_s)) ;\n", -"}\n", -"}\n", -"else if $(MAC)\n", -"{\n", -"_s = $(DOT) ;\n", -"for _i in $(<)\n", -"{\n", -"_s = $(_i:R=$(_s)) ;\n", -"}\n", -"}\n", -"else\n", -"{\n", -"_s = $(<[1]) ;\n", -"for _i in $(<[2-])\n", -"{\n", -"_s = $(_i:R=$(_s)) ;\n", -"}\n", -"}\n", -"return $(_s) ;\n", -"}\n", -"rule _makeCommon\n", -"{\n", -"if $($(<)[1]) && $($(<)[1]) = $($(>)[1])\n", -"{\n", -"$(<) = $($(<)[2-]) ;\n", -"$(>) = $($(>)[2-]) ;\n", -"_makeCommon $(<) : $(>) ;\n", -"}\n", -"}\n", -"rule FRelPath\n", -"{\n", -"local _l _r ;\n", -"_l = $(<) ;\n", -"_r = $(>) ;\n", -"_makeCommon _l : _r ;\n", -"_l = [ FSubDir $(_l) ] ;\n", -"_r = [ FDirName $(_r) ] ;\n", -"if $(_r) = $(DOT) {\n", -"return $(_l) ;\n", -"} else {\n", -"return $(_r:R=$(_l)) ;\n", -"}\n", -"}\n", -"rule FAppendSuffix\n", -"{\n", -"if $(>)\n", -"{\n", -"local _i _o ;\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", -"rule unmakeDir\n", -"{\n", -"if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\\\\\\n", -"{\n", -"unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;\n", -"}\n", -"else\n", -"{\n", -"$(<) = $(>) ;\n", -"}\n", -"}\n", -"rule FConvertToSlashes\n", -"{\n", -"local _d, _s, _i ;\n", -"unmakeDir _d : $(<) ;\n", -"_s = $(_d[1]) ;\n", -"for _i in $(_d[2-])\n", -"{\n", -"_s = $(_s)/$(_i) ;\n", -"}\n", -"return $(_s) ;\n", -"}\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) $(>)\n", -"}\n", -"actions As\n", -"{\n", -"$(AS) $(ASFLAGS) -I$(HDRS) -o $(<) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)\n", -"}\n", -"actions Chgrp\n", -"{\n", -"$(CHGRP) $(GROUP) $(<)\n", -"}\n", -"actions Chmod1\n", -"{\n", -"$(CHMOD) $(MODE) $(<)\n", -"}\n", -"actions Chown\n", -"{\n", -"$(CHOWN) $(OWNER) $(<)\n", -"}\n", -"actions piecemeal together existing Clean\n", -"{\n", -"$(RM) $(>)\n", -"}\n", -"actions File\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"actions GenFile1\n", -"{\n", -"$(>[1]) $(<) $(>[2-])\n", -"}\n", -"actions Fortran\n", -"{\n", -"$(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)\n", -"}\n", -"actions HardLink\n", -"{\n", -"$(RM) $(<) && $(LN) $(>) $(<)\n", -"}\n", -"actions Install\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"actions Lex\n", -"{\n", -"$(LEX) $(>)\n", -"}\n", -"actions LexMv\n", -"{\n", -"$(MV) lex.yy.c $(<)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions MkDir1\n", -"{\n", -"$(MKDIR) $(<)\n", -"}\n", -"actions together Ranlib\n", -"{\n", -"$(RANLIB) $(<)\n", -"}\n", -"actions quietly updated piecemeal together RmTemps\n", -"{\n", -"$(RM) $(>)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(AWK) '\n", -"NR == 1 { print \"$(SHELLHEADER)\" }\n", -"NR == 1 && /^[#:]/ { next }\n", -"/^##/ { next }\n", -"{ print }\n", -"' < $(>) > $(<)\n", -"}\n", -"actions Yacc1\n", -"{\n", -"$(YACC) $(YACCFLAGS) $(>)\n", -"}\n", -"actions YaccMv\n", -"{\n", -"$(MV) $(YACCFILES).c $(<[1])\n", -"$(MV) $(YACCFILES).h $(<[2])\n", -"}\n", -"if $(RELOCATE)\n", -"{\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) $(>)\n", -"}\n", -"actions ignore CcMv\n", -"{\n", -"[ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)\n", -"}\n", -"}\n", -"if $(NOARUPDATE)\n", -"{\n", -"actions Archive\n", -"{\n", -"$(AR) $(<) $(>)\n", -"}\n", -"}\n", -"if $(NT)\n", -"{\n", -"if $(TOOLSET) = VISUALC || $(TOOLSET) = VC7 || $(TOOLSET) = INTELC\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"if exist $(<) set _$(<:B)_=$(<)\n", -"$(AR) /out:$(<) %_$(<:B)_% $(>)\n", -"}\n", -"actions As\n", -"{\n", -"$(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) /Tp$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = VISUALC16\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) -+$(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /Tp$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = BORLANDC\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) -+$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = MINGW\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) $(>:T)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = WATCOM\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) +-$(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = LCC\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) /out:$(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) $(CCFLAGS) $(OPTIM) -Fo$(<) -I$(HDRS) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"}\n", -"else if $(OS2)\n", -"{\n", -"if $(TOOLSET) = WATCOM\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) +-$(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = EMX\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) $(>:T)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"}\n", -"}\n", -"else if $(VMS)\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"lib/replace $(<) $(>[1]) ,$(>[2-])\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>)\n", -"}\n", -"actions piecemeal together existing Clean\n", -"{\n", -"$(RM) $(>[1]);* ,$(>[2-]);*\n", -"}\n", -"actions together quietly CreLib\n", -"{\n", -"if f$search(\"$(<)\") .eqs. \"\" then lib/create $(<)\n", -"}\n", -"actions GenFile1\n", -"{\n", -"mcr $(>[1]) $(<) $(>[2-])\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK)/exe=$(<) $(LINKFLAGS) $(>[1]) ,$(>[2-]) ,$(NEEDLIBS)/lib ,$(LINKLIBS)\n", -"}\n", -"actions quietly updated piecemeal together RmTemps\n", -"{\n", -"$(RM) $(>[1]);* ,$(>[2-]);*\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"else if $(MAC)\n", -"{\n", -"actions together Archive\n", -"{\n", -"$(LINK) -library -o $(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"set -e MWCincludes $(MACINC)\n", -"$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"set -e MWCincludes $(MACINC)\n", -"$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) \"$(LINKLIBS)\"\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", -"rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }\n", -"rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }\n", -"rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }\n", -"rule addDirName { $(<) += [ FDirName $(>) ] ; }\n", -"rule makeDirName { $(<) = [ FDirName $(>) ] ; }\n", -"rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }\n", -"rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }\n", -"rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }\n", -"{\n", -"if $(JAMFILE) { include $(JAMFILE) ; }\n", -"}\n", -"}\n", -0 }; diff --git a/jam-files/engine/jambase.h b/jam-files/engine/jambase.h deleted file mode 100644 index c05ec792..00000000 --- a/jam-files/engine/jambase.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * 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[]; diff --git a/jam-files/engine/jamgram.c b/jam-files/engine/jamgram.c deleted file mode 100644 index b1fa0835..00000000 --- a/jam-files/engine/jamgram.c +++ /dev/null @@ -1,1830 +0,0 @@ -/* A Bison parser, made by GNU Bison 1.875. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program 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, 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, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Written by Richard Stallman by simplifying the original so called - ``semantic'' parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - _BANG_t = 258, - _BANG_EQUALS_t = 259, - _AMPER_t = 260, - _AMPERAMPER_t = 261, - _LPAREN_t = 262, - _RPAREN_t = 263, - _PLUS_EQUALS_t = 264, - _COLON_t = 265, - _SEMIC_t = 266, - _LANGLE_t = 267, - _LANGLE_EQUALS_t = 268, - _EQUALS_t = 269, - _RANGLE_t = 270, - _RANGLE_EQUALS_t = 271, - _QUESTION_EQUALS_t = 272, - _LBRACKET_t = 273, - _RBRACKET_t = 274, - ACTIONS_t = 275, - BIND_t = 276, - CASE_t = 277, - CLASS_t = 278, - DEFAULT_t = 279, - ELSE_t = 280, - EXISTING_t = 281, - FOR_t = 282, - IF_t = 283, - IGNORE_t = 284, - IN_t = 285, - INCLUDE_t = 286, - LOCAL_t = 287, - MODULE_t = 288, - ON_t = 289, - PIECEMEAL_t = 290, - QUIETLY_t = 291, - RETURN_t = 292, - RULE_t = 293, - SWITCH_t = 294, - TOGETHER_t = 295, - UPDATED_t = 296, - WHILE_t = 297, - _LBRACE_t = 298, - _BAR_t = 299, - _BARBAR_t = 300, - _RBRACE_t = 301, - ARG = 302, - STRING = 303 - }; -#endif -#define _BANG_t 258 -#define _BANG_EQUALS_t 259 -#define _AMPER_t 260 -#define _AMPERAMPER_t 261 -#define _LPAREN_t 262 -#define _RPAREN_t 263 -#define _PLUS_EQUALS_t 264 -#define _COLON_t 265 -#define _SEMIC_t 266 -#define _LANGLE_t 267 -#define _LANGLE_EQUALS_t 268 -#define _EQUALS_t 269 -#define _RANGLE_t 270 -#define _RANGLE_EQUALS_t 271 -#define _QUESTION_EQUALS_t 272 -#define _LBRACKET_t 273 -#define _RBRACKET_t 274 -#define ACTIONS_t 275 -#define BIND_t 276 -#define CASE_t 277 -#define CLASS_t 278 -#define DEFAULT_t 279 -#define ELSE_t 280 -#define EXISTING_t 281 -#define FOR_t 282 -#define IF_t 283 -#define IGNORE_t 284 -#define IN_t 285 -#define INCLUDE_t 286 -#define LOCAL_t 287 -#define MODULE_t 288 -#define ON_t 289 -#define PIECEMEAL_t 290 -#define QUIETLY_t 291 -#define RETURN_t 292 -#define RULE_t 293 -#define SWITCH_t 294 -#define TOGETHER_t 295 -#define UPDATED_t 296 -#define WHILE_t 297 -#define _LBRACE_t 298 -#define _BAR_t 299 -#define _BARBAR_t 300 -#define _RBRACE_t 301 -#define ARG 302 -#define STRING 303 - - - - -/* Copy the first part of user declarations. */ -#line 96 "jamgram.y" - -#include "jam.h" - -#include "lists.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 *, FRAME *))0 -# define P0 (PARSE *)0 -# define S0 (char *)0 - -# define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) -# define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) -# define pfor( s,l,r,x ) parse_make( compile_foreach,l,r,P0,s,S0,x ) -# 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 pmodule( l,r ) parse_make( compile_module,l,r,P0,S0,S0,0 ) -# define pclass( l,r ) parse_make( compile_class,l,r,P0,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( s,p ) parse_make( compile_rule,p,P0,P0,s,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,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) -# 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 ) - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -typedef int YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 214 of yacc.c. */ -#line 223 "y.tab.c" - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short yysigned_char; -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 43 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 261 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 49 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 24 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 75 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 159 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 303 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned char yyprhs[] = -{ - 0, 0, 3, 4, 6, 8, 10, 12, 15, 21, - 22, 25, 27, 31, 32, 34, 35, 39, 43, 47, - 52, 59, 63, 72, 78, 84, 90, 96, 102, 110, - 116, 120, 121, 122, 132, 134, 136, 138, 141, 143, - 147, 151, 155, 159, 163, 167, 171, 175, 179, 183, - 187, 190, 194, 195, 198, 203, 205, 209, 211, 212, - 215, 217, 218, 223, 226, 231, 236, 237, 240, 242, - 244, 246, 248, 250, 252, 253 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yysigned_char yyrhs[] = -{ - 50, 0, -1, -1, 52, -1, 53, -1, 52, -1, - 57, -1, 57, 52, -1, 32, 65, 54, 11, 51, - -1, -1, 14, 65, -1, 53, -1, 7, 64, 8, - -1, -1, 32, -1, -1, 43, 51, 46, -1, 31, - 65, 11, -1, 47, 64, 11, -1, 67, 60, 65, - 11, -1, 67, 34, 65, 60, 65, 11, -1, 37, - 65, 11, -1, 27, 56, 47, 30, 65, 43, 51, - 46, -1, 39, 65, 43, 62, 46, -1, 28, 61, - 43, 51, 46, -1, 33, 65, 43, 51, 46, -1, - 23, 64, 43, 51, 46, -1, 42, 61, 43, 51, - 46, -1, 28, 61, 43, 51, 46, 25, 57, -1, - 56, 38, 47, 55, 57, -1, 34, 67, 57, -1, - -1, -1, 20, 70, 47, 72, 43, 58, 48, 59, - 46, -1, 14, -1, 9, -1, 17, -1, 24, 14, - -1, 67, -1, 61, 14, 61, -1, 61, 4, 61, - -1, 61, 12, 61, -1, 61, 13, 61, -1, 61, - 15, 61, -1, 61, 16, 61, -1, 61, 5, 61, - -1, 61, 6, 61, -1, 61, 44, 61, -1, 61, - 45, 61, -1, 67, 30, 65, -1, 3, 61, -1, - 7, 61, 8, -1, -1, 63, 62, -1, 22, 47, - 10, 51, -1, 65, -1, 65, 10, 64, -1, 66, - -1, -1, 66, 67, -1, 47, -1, -1, 18, 68, - 69, 19, -1, 67, 64, -1, 34, 67, 67, 64, - -1, 34, 67, 37, 65, -1, -1, 70, 71, -1, - 41, -1, 40, -1, 29, -1, 36, -1, 35, -1, - 26, -1, -1, 21, 65, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short yyrline[] = -{ - 0, 139, 139, 141, 152, 154, 158, 160, 162, 167, - 170, 172, 176, 179, 182, 185, 188, 190, 192, 194, - 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, - 216, 219, 221, 218, 230, 232, 234, 236, 243, 245, - 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, - 267, 269, 281, 282, 286, 295, 297, 307, 312, 313, - 317, 319, 319, 328, 330, 332, 343, 344, 348, 350, - 352, 354, 356, 358, 368, 369 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "_BANG_t", "_BANG_EQUALS_t", "_AMPER_t", - "_AMPERAMPER_t", "_LPAREN_t", "_RPAREN_t", "_PLUS_EQUALS_t", "_COLON_t", - "_SEMIC_t", "_LANGLE_t", "_LANGLE_EQUALS_t", "_EQUALS_t", "_RANGLE_t", - "_RANGLE_EQUALS_t", "_QUESTION_EQUALS_t", "_LBRACKET_t", "_RBRACKET_t", - "ACTIONS_t", "BIND_t", "CASE_t", "CLASS_t", "DEFAULT_t", "ELSE_t", - "EXISTING_t", "FOR_t", "IF_t", "IGNORE_t", "IN_t", "INCLUDE_t", - "LOCAL_t", "MODULE_t", "ON_t", "PIECEMEAL_t", "QUIETLY_t", "RETURN_t", - "RULE_t", "SWITCH_t", "TOGETHER_t", "UPDATED_t", "WHILE_t", "_LBRACE_t", - "_BAR_t", "_BARBAR_t", "_RBRACE_t", "ARG", "STRING", "$accept", "run", - "block", "rules", "null", "assign_list_opt", "arglist_opt", "local_opt", - "rule", "@1", "@2", "assign", "expr", "cases", "case", "lol", "list", - "listp", "arg", "@3", "func", "eflags", "eflag", "bindlist", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 49, 50, 50, 51, 51, 52, 52, 52, 53, - 54, 54, 55, 55, 56, 56, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 58, 59, 57, 60, 60, 60, 60, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 62, 62, 63, 64, 64, 65, 66, 66, - 67, 68, 67, 69, 69, 69, 70, 70, 71, 71, - 71, 71, 71, 71, 72, 72 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 0, 1, 1, 1, 1, 2, 5, 0, - 2, 1, 3, 0, 1, 0, 3, 3, 3, 4, - 6, 3, 8, 5, 5, 5, 5, 5, 7, 5, - 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, 1, 3, 1, 0, 2, - 1, 0, 4, 2, 4, 4, 0, 2, 1, 1, - 1, 1, 1, 1, 0, 2 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned char yydefact[] = -{ - 2, 61, 66, 58, 15, 0, 58, 58, 58, 0, - 58, 58, 0, 9, 60, 0, 3, 0, 6, 0, - 0, 0, 0, 55, 57, 14, 0, 0, 0, 60, - 0, 38, 0, 9, 0, 15, 0, 0, 0, 0, - 5, 4, 0, 1, 0, 7, 35, 34, 36, 0, - 58, 58, 0, 58, 0, 73, 70, 72, 71, 69, - 68, 74, 67, 9, 58, 59, 0, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, - 58, 17, 58, 11, 0, 9, 30, 21, 52, 9, - 16, 18, 13, 37, 0, 0, 0, 63, 62, 58, - 0, 0, 56, 58, 51, 40, 45, 46, 41, 42, - 39, 43, 44, 0, 47, 48, 49, 10, 9, 0, - 0, 0, 52, 0, 58, 15, 58, 19, 58, 58, - 75, 31, 26, 0, 24, 8, 25, 0, 23, 53, - 27, 0, 29, 0, 65, 64, 0, 9, 15, 9, - 12, 20, 32, 0, 28, 54, 0, 22, 33 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const short yydefgoto[] = -{ - -1, 15, 39, 40, 41, 84, 125, 17, 18, 146, - 156, 51, 30, 121, 122, 22, 23, 24, 31, 20, - 54, 21, 62, 100 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -48 -static const short yypact[] = -{ - 179, -48, -48, -48, -15, 7, -48, -16, -48, 3, - -48, -48, 7, 179, 1, 27, -48, -9, 179, 19, - -3, 33, -11, 24, 3, -48, -10, 7, 7, -48, - 138, 9, 30, 35, 13, 205, 53, 22, 151, 20, - -48, -48, 56, -48, 23, -48, -48, -48, -48, 61, - -48, -48, 3, -48, 62, -48, -48, -48, -48, -48, - -48, 58, -48, 179, -48, -48, 52, -48, 164, 7, - 7, 7, 7, 7, 7, 7, 7, 179, 7, 7, - -48, -48, -48, -48, 72, 179, -48, -48, 68, 179, - -48, -48, 85, -48, 77, 73, 8, -48, -48, -48, - 50, 57, -48, -48, -48, 45, 93, 93, -48, -48, - 45, -48, -48, 64, 245, 245, -48, -48, 179, 66, - 67, 69, 68, 71, -48, 205, -48, -48, -48, -48, - -48, -48, -48, 70, 79, -48, -48, 109, -48, -48, - -48, 112, -48, 115, -48, -48, 75, 179, 205, 179, - -48, -48, -48, 81, -48, -48, 82, -48, -48 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const short yypgoto[] = -{ - -48, -48, -47, 5, 104, -48, -48, 136, -27, -48, - -48, 47, 60, 36, -48, -13, -4, -48, 0, -48, - -48, -48, -48, -48 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -59 -static const short yytable[] = -{ - 19, 42, 32, 33, 34, 16, 36, 37, 86, 35, - 27, -58, -58, 19, 28, 1, 101, 25, 19, -58, - 53, 1, -14, 45, 65, 1, 1, 43, 46, 44, - 113, 52, 63, 47, 64, 19, 48, 66, 119, 80, - 97, 81, 123, 49, 29, 128, 94, 95, -58, 82, - 29, 102, 96, 50, 29, 29, 85, 72, 73, 55, - 75, 76, 56, 19, 87, 88, 90, 91, 57, 58, - 92, 135, 38, 59, 60, 93, 116, 19, 117, 99, - 61, 98, 103, 118, 127, 19, 46, 67, 68, 19, - 120, 47, 124, 131, 48, 130, 129, 69, 142, 133, - 153, 49, 155, 132, 148, 72, 73, 74, 75, 76, - 134, 141, 136, 147, 137, 138, 145, 140, 19, 149, - 150, 154, 143, 152, 144, 19, 151, 157, 158, 105, - 106, 107, 108, 109, 110, 111, 112, 83, 114, 115, - 26, 126, 69, 70, 71, 0, 0, 19, 19, 19, - 72, 73, 74, 75, 76, 69, 70, 71, 139, 0, - 0, 0, 0, 72, 73, 74, 75, 76, 69, 70, - 71, 0, 104, 0, 0, 0, 72, 73, 74, 75, - 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 89, 78, 79, 1, 0, 2, - 0, 0, 3, 0, 0, 0, 4, 5, 78, 79, - 6, 7, 8, 9, 0, 0, 10, -15, 11, 0, - 0, 12, 13, 1, 0, 2, 14, 0, 3, 0, - 0, 0, 4, 5, 0, 0, 6, 25, 8, 9, - 0, 0, 10, 0, 11, 0, 0, 12, 13, 69, - 70, 71, 14, 0, 0, 0, 0, 72, 73, 74, - 75, 76 -}; - -static const short yycheck[] = -{ - 0, 14, 6, 7, 8, 0, 10, 11, 35, 9, - 3, 10, 11, 13, 7, 18, 63, 32, 18, 18, - 20, 18, 38, 18, 24, 18, 18, 0, 9, 38, - 77, 34, 43, 14, 10, 35, 17, 47, 85, 30, - 53, 11, 89, 24, 47, 37, 50, 51, 47, 14, - 47, 64, 52, 34, 47, 47, 43, 12, 13, 26, - 15, 16, 29, 63, 11, 43, 46, 11, 35, 36, - 47, 118, 12, 40, 41, 14, 80, 77, 82, 21, - 47, 19, 30, 11, 11, 85, 9, 27, 28, 89, - 22, 14, 7, 43, 17, 99, 96, 4, 125, 103, - 147, 24, 149, 46, 25, 12, 13, 14, 15, 16, - 46, 124, 46, 43, 47, 46, 129, 46, 118, 10, - 8, 148, 126, 48, 128, 125, 11, 46, 46, 69, - 70, 71, 72, 73, 74, 75, 76, 33, 78, 79, - 4, 94, 4, 5, 6, -1, -1, 147, 148, 149, - 12, 13, 14, 15, 16, 4, 5, 6, 122, -1, - -1, -1, -1, 12, 13, 14, 15, 16, 4, 5, - 6, -1, 8, -1, -1, -1, 12, 13, 14, 15, - 16, 43, 44, 45, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 43, 44, 45, 18, -1, 20, - -1, -1, 23, -1, -1, -1, 27, 28, 44, 45, - 31, 32, 33, 34, -1, -1, 37, 38, 39, -1, - -1, 42, 43, 18, -1, 20, 47, -1, 23, -1, - -1, -1, 27, 28, -1, -1, 31, 32, 33, 34, - -1, -1, 37, -1, 39, -1, -1, 42, 43, 4, - 5, 6, 47, -1, -1, -1, -1, 12, 13, 14, - 15, 16 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 18, 20, 23, 27, 28, 31, 32, 33, 34, - 37, 39, 42, 43, 47, 50, 52, 56, 57, 67, - 68, 70, 64, 65, 66, 32, 56, 3, 7, 47, - 61, 67, 65, 65, 65, 67, 65, 65, 61, 51, - 52, 53, 64, 0, 38, 52, 9, 14, 17, 24, - 34, 60, 34, 67, 69, 26, 29, 35, 36, 40, - 41, 47, 71, 43, 10, 67, 47, 61, 61, 4, - 5, 6, 12, 13, 14, 15, 16, 43, 44, 45, - 30, 11, 14, 53, 54, 43, 57, 11, 43, 43, - 46, 11, 47, 14, 65, 65, 67, 64, 19, 21, - 72, 51, 64, 30, 8, 61, 61, 61, 61, 61, - 61, 61, 61, 51, 61, 61, 65, 65, 11, 51, - 22, 62, 63, 51, 7, 55, 60, 11, 37, 67, - 65, 43, 46, 65, 46, 51, 46, 47, 46, 62, - 46, 64, 57, 65, 65, 64, 58, 43, 25, 10, - 8, 11, 48, 51, 57, 51, 59, 46, 46 -}; - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.first_line = Rhs[1].first_line; \ - Current.first_column = Rhs[1].first_column; \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; -#endif - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ -} while (0) - -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (cinluded). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short *bottom, short *top) -#else -static void -yy_stack_print (bottom, top) - short *bottom; - short *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; -#endif -{ - int yyi; - unsigned int yylineno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylineno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YYDSYMPRINT(Args) -# define YYDSYMPRINTF(Title, Token, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#if YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -#endif /* !YYERROR_VERBOSE */ - - - -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else -static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (yytype < YYNTOKENS) - { - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -# ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - } - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); -} - -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yytype, yyvaluep) - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - register int yystate; - register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; - register short *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; - - - -#define YYPOPSTACK (yyvsp--, yyssp--) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; - - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 3: -#line 142 "jamgram.y" - { parse_save( yyvsp[0].parse ); } - break; - - case 4: -#line 153 "jamgram.y" - { yyval.parse = yyvsp[0].parse; } - break; - - case 5: -#line 155 "jamgram.y" - { yyval.parse = yyvsp[0].parse; } - break; - - case 6: -#line 159 "jamgram.y" - { yyval.parse = yyvsp[0].parse; } - break; - - case 7: -#line 161 "jamgram.y" - { yyval.parse = prules( yyvsp[-1].parse, yyvsp[0].parse ); } - break; - - case 8: -#line 163 "jamgram.y" - { yyval.parse = plocal( yyvsp[-3].parse, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 9: -#line 167 "jamgram.y" - { yyval.parse = pnull(); } - break; - - case 10: -#line 171 "jamgram.y" - { yyval.parse = yyvsp[0].parse; yyval.number = ASSIGN_SET; } - break; - - case 11: -#line 173 "jamgram.y" - { yyval.parse = yyvsp[0].parse; yyval.number = ASSIGN_APPEND; } - break; - - case 12: -#line 177 "jamgram.y" - { yyval.parse = yyvsp[-1].parse; } - break; - - case 13: -#line 179 "jamgram.y" - { yyval.parse = P0; } - break; - - case 14: -#line 183 "jamgram.y" - { yyval.number = 1; } - break; - - case 15: -#line 185 "jamgram.y" - { yyval.number = 0; } - break; - - case 16: -#line 189 "jamgram.y" - { yyval.parse = yyvsp[-1].parse; } - break; - - case 17: -#line 191 "jamgram.y" - { yyval.parse = pincl( yyvsp[-1].parse ); } - break; - - case 18: -#line 193 "jamgram.y" - { yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); } - break; - - case 19: -#line 195 "jamgram.y" - { yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); } - break; - - case 20: -#line 197 "jamgram.y" - { yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); } - break; - - case 21: -#line 199 "jamgram.y" - { yyval.parse = yyvsp[-1].parse; } - break; - - case 22: -#line 201 "jamgram.y" - { yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-6].number ); } - break; - - case 23: -#line 203 "jamgram.y" - { yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); } - break; - - case 24: -#line 205 "jamgram.y" - { yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); } - break; - - case 25: -#line 207 "jamgram.y" - { yyval.parse = pmodule( yyvsp[-3].parse, yyvsp[-1].parse ); } - break; - - case 26: -#line 209 "jamgram.y" - { yyval.parse = pclass( yyvsp[-3].parse, yyvsp[-1].parse ); } - break; - - case 27: -#line 211 "jamgram.y" - { yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); } - break; - - case 28: -#line 213 "jamgram.y" - { yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); } - break; - - case 29: -#line 215 "jamgram.y" - { yyval.parse = psetc( yyvsp[-2].string, yyvsp[0].parse, yyvsp[-1].parse, yyvsp[-4].number ); } - break; - - case 30: -#line 217 "jamgram.y" - { yyval.parse = pon( yyvsp[-1].parse, yyvsp[0].parse ); } - break; - - case 31: -#line 219 "jamgram.y" - { yymode( SCAN_STRING ); } - break; - - case 32: -#line 221 "jamgram.y" - { yymode( SCAN_NORMAL ); } - break; - - case 33: -#line 223 "jamgram.y" - { yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); } - break; - - case 34: -#line 231 "jamgram.y" - { yyval.number = ASSIGN_SET; } - break; - - case 35: -#line 233 "jamgram.y" - { yyval.number = ASSIGN_APPEND; } - break; - - case 36: -#line 235 "jamgram.y" - { yyval.number = ASSIGN_DEFAULT; } - break; - - case 37: -#line 237 "jamgram.y" - { yyval.number = ASSIGN_DEFAULT; } - break; - - case 38: -#line 244 "jamgram.y" - { yyval.parse = peval( EXPR_EXISTS, yyvsp[0].parse, pnull() ); } - break; - - case 39: -#line 246 "jamgram.y" - { yyval.parse = peval( EXPR_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 40: -#line 248 "jamgram.y" - { yyval.parse = peval( EXPR_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 41: -#line 250 "jamgram.y" - { yyval.parse = peval( EXPR_LESS, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 42: -#line 252 "jamgram.y" - { yyval.parse = peval( EXPR_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 43: -#line 254 "jamgram.y" - { yyval.parse = peval( EXPR_MORE, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 44: -#line 256 "jamgram.y" - { yyval.parse = peval( EXPR_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 45: -#line 258 "jamgram.y" - { yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 46: -#line 260 "jamgram.y" - { yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 47: -#line 262 "jamgram.y" - { yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 48: -#line 264 "jamgram.y" - { yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 49: -#line 266 "jamgram.y" - { yyval.parse = peval( EXPR_IN, yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 50: -#line 268 "jamgram.y" - { yyval.parse = peval( EXPR_NOT, yyvsp[0].parse, pnull() ); } - break; - - case 51: -#line 270 "jamgram.y" - { yyval.parse = yyvsp[-1].parse; } - break; - - case 52: -#line 281 "jamgram.y" - { yyval.parse = P0; } - break; - - case 53: -#line 283 "jamgram.y" - { yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); } - break; - - case 54: -#line 287 "jamgram.y" - { yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); } - break; - - case 55: -#line 296 "jamgram.y" - { yyval.parse = pnode( P0, yyvsp[0].parse ); } - break; - - case 56: -#line 298 "jamgram.y" - { yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); } - break; - - case 57: -#line 308 "jamgram.y" - { yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); } - break; - - case 58: -#line 312 "jamgram.y" - { yyval.parse = pnull(); yymode( SCAN_PUNCT ); } - break; - - case 59: -#line 314 "jamgram.y" - { yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); } - break; - - case 60: -#line 318 "jamgram.y" - { yyval.parse = plist( yyvsp[0].string ); } - break; - - case 61: -#line 319 "jamgram.y" - { yymode( SCAN_NORMAL ); } - break; - - case 62: -#line 320 "jamgram.y" - { yyval.parse = yyvsp[-1].parse; } - break; - - case 63: -#line 329 "jamgram.y" - { yyval.parse = prule( yyvsp[-1].string, yyvsp[0].parse ); } - break; - - case 64: -#line 331 "jamgram.y" - { yyval.parse = pon( yyvsp[-2].parse, prule( yyvsp[-1].string, yyvsp[0].parse ) ); } - break; - - case 65: -#line 333 "jamgram.y" - { yyval.parse = pon( yyvsp[-2].parse, yyvsp[0].parse ); } - break; - - case 66: -#line 343 "jamgram.y" - { yyval.number = 0; } - break; - - case 67: -#line 345 "jamgram.y" - { yyval.number = yyvsp[-1].number | yyvsp[0].number; } - break; - - case 68: -#line 349 "jamgram.y" - { yyval.number = EXEC_UPDATED; } - break; - - case 69: -#line 351 "jamgram.y" - { yyval.number = EXEC_TOGETHER; } - break; - - case 70: -#line 353 "jamgram.y" - { yyval.number = EXEC_IGNORE; } - break; - - case 71: -#line 355 "jamgram.y" - { yyval.number = EXEC_QUIETLY; } - break; - - case 72: -#line 357 "jamgram.y" - { yyval.number = EXEC_PIECEMEAL; } - break; - - case 73: -#line 359 "jamgram.y" - { yyval.number = EXEC_EXISTING; } - break; - - case 74: -#line 368 "jamgram.y" - { yyval.parse = pnull(); } - break; - - case 75: -#line 370 "jamgram.y" - { yyval.parse = yyvsp[0].parse; } - break; - - - } - -/* Line 991 of yacc.c. */ -#line 1621 "y.tab.c" - - yyvsp -= yylen; - yyssp -= yylen; - - - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - /* Return failure if at end of input. */ - if (yychar == YYEOF) - { - /* Pop the error token. */ - YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; - } - - YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); - yydestruct (yytoken, &yylval); - yychar = YYEMPTY; - - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab2; - - -/*----------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action. | -`----------------------------------------------------*/ -yyerrlab1: - - /* Suppress GCC warning that yyerrlab1 is unused when no action - invokes YYERROR. */ -#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) - __attribute__ ((__unused__)) -#endif - - - goto yyerrlab2; - - -/*---------------------------------------------------------------. -| yyerrlab2 -- pop states until the error token can be shifted. | -`---------------------------------------------------------------*/ -yyerrlab2: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[yystate], yyvsp); - yyvsp--; - yystate = *--yyssp; - - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - YYDPRINTF ((stderr, "Shifting error token, ")); - - *++yyvsp = yylval; - - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} - - - diff --git a/jam-files/engine/jamgram.h b/jam-files/engine/jamgram.h deleted file mode 100644 index 3cb76564..00000000 --- a/jam-files/engine/jamgram.h +++ /dev/null @@ -1,140 +0,0 @@ -/* A Bison parser, made by GNU Bison 1.875. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program 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, 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, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - _BANG_t = 258, - _BANG_EQUALS_t = 259, - _AMPER_t = 260, - _AMPERAMPER_t = 261, - _LPAREN_t = 262, - _RPAREN_t = 263, - _PLUS_EQUALS_t = 264, - _COLON_t = 265, - _SEMIC_t = 266, - _LANGLE_t = 267, - _LANGLE_EQUALS_t = 268, - _EQUALS_t = 269, - _RANGLE_t = 270, - _RANGLE_EQUALS_t = 271, - _QUESTION_EQUALS_t = 272, - _LBRACKET_t = 273, - _RBRACKET_t = 274, - ACTIONS_t = 275, - BIND_t = 276, - CASE_t = 277, - CLASS_t = 278, - DEFAULT_t = 279, - ELSE_t = 280, - EXISTING_t = 281, - FOR_t = 282, - IF_t = 283, - IGNORE_t = 284, - IN_t = 285, - INCLUDE_t = 286, - LOCAL_t = 287, - MODULE_t = 288, - ON_t = 289, - PIECEMEAL_t = 290, - QUIETLY_t = 291, - RETURN_t = 292, - RULE_t = 293, - SWITCH_t = 294, - TOGETHER_t = 295, - UPDATED_t = 296, - WHILE_t = 297, - _LBRACE_t = 298, - _BAR_t = 299, - _BARBAR_t = 300, - _RBRACE_t = 301, - ARG = 302, - STRING = 303 - }; -#endif -#define _BANG_t 258 -#define _BANG_EQUALS_t 259 -#define _AMPER_t 260 -#define _AMPERAMPER_t 261 -#define _LPAREN_t 262 -#define _RPAREN_t 263 -#define _PLUS_EQUALS_t 264 -#define _COLON_t 265 -#define _SEMIC_t 266 -#define _LANGLE_t 267 -#define _LANGLE_EQUALS_t 268 -#define _EQUALS_t 269 -#define _RANGLE_t 270 -#define _RANGLE_EQUALS_t 271 -#define _QUESTION_EQUALS_t 272 -#define _LBRACKET_t 273 -#define _RBRACKET_t 274 -#define ACTIONS_t 275 -#define BIND_t 276 -#define CASE_t 277 -#define CLASS_t 278 -#define DEFAULT_t 279 -#define ELSE_t 280 -#define EXISTING_t 281 -#define FOR_t 282 -#define IF_t 283 -#define IGNORE_t 284 -#define IN_t 285 -#define INCLUDE_t 286 -#define LOCAL_t 287 -#define MODULE_t 288 -#define ON_t 289 -#define PIECEMEAL_t 290 -#define QUIETLY_t 291 -#define RETURN_t 292 -#define RULE_t 293 -#define SWITCH_t 294 -#define TOGETHER_t 295 -#define UPDATED_t 296 -#define WHILE_t 297 -#define _LBRACE_t 298 -#define _BAR_t 299 -#define _BARBAR_t 300 -#define _RBRACE_t 301 -#define ARG 302 -#define STRING 303 - - - - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -typedef int YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE yylval; - - - diff --git a/jam-files/engine/jamgram.y b/jam-files/engine/jamgram.y deleted file mode 100644 index c26b1e1b..00000000 --- a/jam-files/engine/jamgram.y +++ /dev/null @@ -1,371 +0,0 @@ -%token _BANG_t -%token _BANG_EQUALS_t -%token _AMPER_t -%token _AMPERAMPER_t -%token _LPAREN_t -%token _RPAREN_t -%token _PLUS_EQUALS_t -%token _COLON_t -%token _SEMIC_t -%token _LANGLE_t -%token _LANGLE_EQUALS_t -%token _EQUALS_t -%token _RANGLE_t -%token _RANGLE_EQUALS_t -%token _QUESTION_EQUALS_t -%token _LBRACKET_t -%token _RBRACKET_t -%token ACTIONS_t -%token BIND_t -%token CASE_t -%token CLASS_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 MODULE_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 -%token _LBRACE_t -%token _BAR_t -%token _BARBAR_t -%token _RBRACE_t -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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 now return lists (LIST *), rather than void. - * - * New "[ rule ]" syntax evals rule into a LIST. - * - * Lists are now generated by compile_list() and - * compile_append(), and any other rule that indirectly - * makes a list, rather than being built directly here, - * so that lists values can contain rule evaluations. - * - * New 'return' rule sets the return value, though - * other statements also may have return values. - * - * 'run' production split from 'block' production so - * that empty blocks can be handled separately. - */ - -%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 "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 *, FRAME *))0 -# define P0 (PARSE *)0 -# define S0 (char *)0 - -# define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) -# define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) -# define pfor( s,l,r,x ) parse_make( compile_foreach,l,r,P0,s,S0,x ) -# 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 pmodule( l,r ) parse_make( compile_module,l,r,P0,S0,S0,0 ) -# define pclass( l,r ) parse_make( compile_class,l,r,P0,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( s,p ) parse_make( compile_rule,p,P0,P0,s,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,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) -# 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 : null - { $$.parse = $1.parse; } - | rules - { $$.parse = $1.parse; } - ; - -rules : rule - { $$.parse = $1.parse; } - | rule rules - { $$.parse = prules( $1.parse, $2.parse ); } - | LOCAL_t list assign_list_opt _SEMIC_t block - { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } - ; - -null : /* empty */ - { $$.parse = pnull(); } - ; - -assign_list_opt : _EQUALS_t list - { $$.parse = $2.parse; $$.number = ASSIGN_SET; } - | null - { $$.parse = $1.parse; $$.number = ASSIGN_APPEND; } - ; - -arglist_opt : _LPAREN_t lol _RPAREN_t - { $$.parse = $2.parse; } - | - { $$.parse = P0; } - ; - -local_opt : LOCAL_t - { $$.number = 1; } - | /* empty */ - { $$.number = 0; } - ; - -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.string, $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 ); } - | RETURN_t list _SEMIC_t - { $$.parse = $2.parse; } - | FOR_t local_opt ARG IN_t list _LBRACE_t block _RBRACE_t - { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } - | 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() ); } - | MODULE_t list _LBRACE_t block _RBRACE_t - { $$.parse = pmodule( $2.parse, $4.parse ); } - | CLASS_t lol _LBRACE_t block _RBRACE_t - { $$.parse = pclass( $2.parse, $4.parse ); } - | WHILE_t expr _LBRACE_t block _RBRACE_t - { $$.parse = pwhile( $2.parse, $4.parse ); } - | IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule - { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | local_opt RULE_t ARG arglist_opt rule - { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } - | 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 = ASSIGN_SET; } - | _PLUS_EQUALS_t - { $$.number = ASSIGN_APPEND; } - | _QUESTION_EQUALS_t - { $$.number = ASSIGN_DEFAULT; } - | DEFAULT_t _EQUALS_t - { $$.number = ASSIGN_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 ); } - ; - -/* - * 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.string, $2.parse ); } - | ON_t arg arg lol - { $$.parse = pon( $2.parse, prule( $3.string, $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 = EXEC_UPDATED; } - | TOGETHER_t - { $$.number = EXEC_TOGETHER; } - | IGNORE_t - { $$.number = EXEC_IGNORE; } - | QUIETLY_t - { $$.number = EXEC_QUIETLY; } - | PIECEMEAL_t - { $$.number = EXEC_PIECEMEAL; } - | EXISTING_t - { $$.number = EXEC_EXISTING; } - ; - - -/* - * bindlist - list of variable to bind for an action - */ - -bindlist : /* empty */ - { $$.parse = pnull(); } - | BIND_t list - { $$.parse = $2.parse; } - ; diff --git a/jam-files/engine/jamgram.yy b/jam-files/engine/jamgram.yy deleted file mode 100644 index 15243487..00000000 --- a/jam-files/engine/jamgram.yy +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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 now return lists (LIST *), rather than void. - * - * New "[ rule ]" syntax evals rule into a LIST. - * - * Lists are now generated by compile_list() and - * compile_append(), and any other rule that indirectly - * makes a list, rather than being built directly here, - * so that lists values can contain rule evaluations. - * - * New 'return' rule sets the return value, though - * other statements also may have return values. - * - * 'run' production split from 'block' production so - * that empty blocks can be handled separately. - */ - -%token ARG STRING - -%left `||` `|` -%left `&&` `&` -%left `=` `!=` `in` -%left `<` `<=` `>` `>=` -%left `!` - -%{ -#include "jam.h" - -#include "lists.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 *, FRAME *))0 -# define P0 (PARSE *)0 -# define S0 (char *)0 - -# define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) -# define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) -# define pfor( s,l,r,x ) parse_make( compile_foreach,l,r,P0,s,S0,x ) -# 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 pmodule( l,r ) parse_make( compile_module,l,r,P0,S0,S0,0 ) -# define pclass( l,r ) parse_make( compile_class,l,r,P0,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( s,p ) parse_make( compile_rule,p,P0,P0,s,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,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) -# 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 : null - { $$.parse = $1.parse; } - | rules - { $$.parse = $1.parse; } - ; - -rules : rule - { $$.parse = $1.parse; } - | rule rules - { $$.parse = prules( $1.parse, $2.parse ); } - | `local` list assign_list_opt `;` block - { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } - ; - -null : /* empty */ - { $$.parse = pnull(); } - ; - -assign_list_opt : `=` list - { $$.parse = $2.parse; $$.number = ASSIGN_SET; } - | null - { $$.parse = $1.parse; $$.number = ASSIGN_APPEND; } - ; - -arglist_opt : `(` lol `)` - { $$.parse = $2.parse; } - | - { $$.parse = P0; } - ; - -local_opt : `local` - { $$.number = 1; } - | /* empty */ - { $$.number = 0; } - ; - -rule : `{` block `}` - { $$.parse = $2.parse; } - | `include` list `;` - { $$.parse = pincl( $2.parse ); } - | ARG lol `;` - { $$.parse = prule( $1.string, $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 ); } - | `return` list `;` - { $$.parse = $2.parse; } - | `for` local_opt ARG `in` list `{` block `}` - { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } - | `switch` list `{` cases `}` - { $$.parse = pswitch( $2.parse, $4.parse ); } - | `if` expr `{` block `}` - { $$.parse = pif( $2.parse, $4.parse, pnull() ); } - | `module` list `{` block `}` - { $$.parse = pmodule( $2.parse, $4.parse ); } - | `class` lol `{` block `}` - { $$.parse = pclass( $2.parse, $4.parse ); } - | `while` expr `{` block `}` - { $$.parse = pwhile( $2.parse, $4.parse ); } - | `if` expr `{` block `}` `else` rule - { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | local_opt `rule` ARG arglist_opt rule - { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } - | `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 = ASSIGN_SET; } - | `+=` - { $$.number = ASSIGN_APPEND; } - | `?=` - { $$.number = ASSIGN_DEFAULT; } - | `default` `=` - { $$.number = ASSIGN_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 ); } - ; - -/* - * 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.string, $2.parse ); } - | `on` arg arg lol - { $$.parse = pon( $2.parse, prule( $3.string, $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 = EXEC_UPDATED; } - | `together` - { $$.number = EXEC_TOGETHER; } - | `ignore` - { $$.number = EXEC_IGNORE; } - | `quietly` - { $$.number = EXEC_QUIETLY; } - | `piecemeal` - { $$.number = EXEC_PIECEMEAL; } - | `existing` - { $$.number = EXEC_EXISTING; } - ; - - -/* - * bindlist - list of variable to bind for an action - */ - -bindlist : /* empty */ - { $$.parse = pnull(); } - | `bind` list - { $$.parse = $2.parse; } - ; - - diff --git a/jam-files/engine/jamgramtab.h b/jam-files/engine/jamgramtab.h deleted file mode 100644 index a0fd43f6..00000000 --- a/jam-files/engine/jamgramtab.h +++ /dev/null @@ -1,44 +0,0 @@ - { "!", _BANG_t }, - { "!=", _BANG_EQUALS_t }, - { "&", _AMPER_t }, - { "&&", _AMPERAMPER_t }, - { "(", _LPAREN_t }, - { ")", _RPAREN_t }, - { "+=", _PLUS_EQUALS_t }, - { ":", _COLON_t }, - { ";", _SEMIC_t }, - { "<", _LANGLE_t }, - { "<=", _LANGLE_EQUALS_t }, - { "=", _EQUALS_t }, - { ">", _RANGLE_t }, - { ">=", _RANGLE_EQUALS_t }, - { "?=", _QUESTION_EQUALS_t }, - { "[", _LBRACKET_t }, - { "]", _RBRACKET_t }, - { "actions", ACTIONS_t }, - { "bind", BIND_t }, - { "case", CASE_t }, - { "class", CLASS_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 }, - { "module", MODULE_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 }, - { "{", _LBRACE_t }, - { "|", _BAR_t }, - { "||", _BARBAR_t }, - { "}", _RBRACE_t }, diff --git a/jam-files/engine/lists.c b/jam-files/engine/lists.c deleted file mode 100644 index ebabb63e..00000000 --- a/jam-files/engine/lists.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -# include "jam.h" -# include "newstr.h" -# include "lists.h" - -/* - * 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 - */ - -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, char * string ) -{ - LIST * l; - - if ( DEBUG_LISTS ) - printf( "list > %s <\n", 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 *)BJAM_MALLOC( sizeof( LIST ) ); - } - - /* 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, copystr( nl->string ) ); - 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, copystr( l->string ) ); - return nl; -} - - -static int str_ptr_compare( void const * va, void const * vb ) -{ - char * a = *( (char * *)va ); - char * b = *( (char * *)vb ); - return strcmp(a, b); -} - - -LIST * list_sort( LIST * l ) -{ - int len; - int ii; - char * * strings; - LIST * listp; - LIST * result = 0; - - if ( !l ) - return L0; - - len = list_length( l ); - strings = (char * *)BJAM_MALLOC( len * sizeof(char*) ); - - listp = l; - for ( ii = 0; ii < len; ++ii ) - { - strings[ ii ] = listp->string; - listp = listp->next; - } - - qsort( strings, len, sizeof( char * ), str_ptr_compare ); - - for ( ii = 0; ii < len; ++ii ) - result = list_append( result, list_new( 0, strings[ ii ] ) ); - - BJAM_FREE( strings ); - - return result; -} - - -/* - * 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_pop_front() - remove the front element from a list of strings - */ - -LIST * list_pop_front( LIST * l ) -{ - LIST * result = l->next; - if ( result ) - { - result->tail = l->tail; - l->next = L0; - l->tail = l; - } - list_free( l ); - return result; -} - - -/* - * list_print() - print a list of strings to stdout - */ - -void list_print( LIST * l ) -{ - LIST * p = 0; - for ( ; l; p = l, l = list_next( l ) ) - if ( p ) - printf( "%s ", p->string ); - if ( p ) - printf( "%s", p->string ); -} - - -/* - * 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; -} - - -int list_in( LIST * l, char * value ) -{ - for ( ; l; l = l->next ) - if ( strcmp( l->string, value ) == 0 ) - return 1; - return 0; -} - - -LIST * list_unique( LIST * sorted_list ) -{ - LIST * result = 0; - LIST * last_added = 0; - - for ( ; sorted_list; sorted_list = sorted_list->next ) - { - if ( !last_added || strcmp( sorted_list->string, last_added->string ) != 0 ) - { - result = list_new( result, sorted_list->string ); - last_added = sorted_list; - } - } - return result; -} - - -/* - * 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 ] ); - } -} - -#ifdef HAVE_PYTHON - -PyObject *list_to_python(LIST *l) -{ - PyObject *result = PyList_New(0); - - for (; l; l = l->next) - { - PyObject* s = PyString_FromString(l->string); - PyList_Append(result, s); - Py_DECREF(s); - } - - return result; -} - -LIST *list_from_python(PyObject *l) -{ - LIST * result = 0; - - Py_ssize_t i, n; - n = PySequence_Size(l); - for (i = 0; i < n; ++i) - { - PyObject *v = PySequence_GetItem(l, i); - result = list_new (result, newstr (PyString_AsString(v))); - Py_DECREF(v); - } - - return result; -} - -#endif diff --git a/jam-files/engine/lists.h b/jam-files/engine/lists.h deleted file mode 100644 index 1dc59827..00000000 --- a/jam-files/engine/lists.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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_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() - */ - -#ifndef LISTS_DWA20011022_H -# define LISTS_DWA20011022_H - -#ifdef HAVE_PYTHON -#include <Python.h> -#endif - -/* - * LIST - list of strings - */ - -typedef struct _list LIST; - -struct _list { - LIST *next; - LIST *tail; /* only valid in head node */ - char *string; /* private copy */ -}; - -/* - * LOL - list of LISTs - */ - -typedef struct _lol LOL; - -# define LOL_MAX 19 - -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, char *string ); -void list_print( LIST *l ); -int list_length( LIST *l ); -LIST * list_sublist( LIST *l, int start, int count ); -LIST * list_pop_front( LIST *l ); -LIST * list_sort( LIST *l); -LIST * list_unique( LIST *sorted_list); -int list_in(LIST* l, char* value); - -# 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 ); -void lol_build( LOL* lol, char** elements ); - -#ifdef HAVE_PYTHON - -PyObject *list_to_python(LIST *l); -LIST *list_from_python(PyObject *l); - -#endif - -#endif - diff --git a/jam-files/engine/make.c b/jam-files/engine/make.c deleted file mode 100644 index c871f0be..00000000 --- a/jam-files/engine/make.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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 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 are not seen as being dependent 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). - */ - -#include "jam.h" - -#include "lists.h" -#include "parse.h" -#include "variable.h" -#include "rules.h" - -#ifdef OPT_HEADER_CACHE_EXT - #include "hcache.h" -#endif - -#include "search.h" -#include "newstr.h" -#include "make.h" -#include "headers.h" -#include "command.h" -#include <assert.h> - -#ifndef max - #define max( a,b ) ((a)>(b)?(a):(b)) -#endif - -static TARGETS * make0sort( TARGETS * c ); - -#ifdef OPT_GRAPH_DEBUG_EXT - static void dependGraphOutput( TARGET * t, int depth ); -#endif - -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 */ - "rebuild", /* T_FATE_REBUILD */ - "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) ( " " + ( x > 20 ? 0 : 20-x ) ) - - -/* - * make() - make a target, given its name. - */ - -int make( int n_targets, char const * * targets, int anyhow ) -{ - int i; - COUNTS counts[ 1 ]; - int status = 0; /* 1 if anything fails */ - -#ifdef OPT_HEADER_CACHE_EXT - hcache_init(); -#endif - - memset( (char *)counts, 0, sizeof( *counts ) ); - - /* First bind all targets with LOCATE_TARGET setting. This is needed to - * correctly handle dependencies to generated headers. - */ - bind_explicitly_located_targets(); - - { - PROFILE_ENTER( MAKE_MAKE0 ); - for ( i = 0; i < n_targets; ++i ) - make0( bindtarget( targets[ i ] ), 0, 0, counts, anyhow ); - PROFILE_EXIT( MAKE_MAKE0 ); - } - -#ifdef OPT_GRAPH_DEBUG_EXT - if ( DEBUG_GRAPH ) - for ( i = 0; i < n_targets; ++i ) - dependGraphOutput( bindtarget( targets[ i ] ), 0 ); -#endif - - if ( DEBUG_MAKE ) - { - if ( counts->targets ) - printf( "...found %d target%s...\n", counts->targets, - counts->targets > 1 ? "s" : "" ); - if ( counts->temp ) - printf( "...using %d temp target%s...\n", counts->temp, - counts->temp > 1 ? "s" : "" ); - if ( counts->updating ) - printf( "...updating %d target%s...\n", counts->updating, - counts->updating > 1 ? "s" : "" ); - if ( counts->cantfind ) - printf( "...can't find %d target%s...\n", counts->cantfind, - counts->cantfind > 1 ? "s" : "" ); - if ( counts->cantmake ) - printf( "...can't make %d target%s...\n", counts->cantmake, - counts->cantmake > 1 ? "s" : "" ); - } - -#ifdef OPT_HEADER_CACHE_EXT - hcache_done(); -#endif - - status = counts->cantfind || counts->cantmake; - - { - PROFILE_ENTER( MAKE_MAKE1 ); - for ( i = 0; i < n_targets; ++i ) - status |= make1( bindtarget( targets[ i ] ) ); - PROFILE_EXIT( MAKE_MAKE1 ); - } - - return status; -} - - -/* Force any dependants of t that have already at least begun being visited by - * make0() to be updated. - */ - -static void update_dependants( TARGET * t ) -{ - TARGETS * q; - - for ( q = t->dependants; q; q = q->next ) - { - TARGET * p = q->target; - char fate0 = p->fate; - - /* If we have already at least begun visiting it and we are not already - * rebuilding it for other reasons. - */ - if ( ( fate0 != T_FATE_INIT ) && ( fate0 < T_FATE_BUILD ) ) - { - p->fate = T_FATE_UPDATE; - - if ( DEBUG_FATE ) - { - printf( "fate change %s from %s to %s (as dependant of %s)\n", - p->name, target_fate[ (int) fate0 ], target_fate[ (int) p->fate ], t->name ); - } - - /* If we are done visiting it, go back and make sure its dependants - * get rebuilt. - */ - if ( fate0 > T_FATE_MAKING ) - update_dependants( p ); - } - } -} - - -/* - * Make sure that all of t's rebuilds get rebuilt. - */ - -static void force_rebuilds( TARGET * t ) -{ - TARGETS * d; - for ( d = t->rebuilds; d; d = d->next ) - { - TARGET * r = d->target; - - /* If it is not already being rebuilt for other reasons. */ - if ( r->fate < T_FATE_BUILD ) - { - if ( DEBUG_FATE ) - printf( "fate change %s from %s to %s (by rebuild)\n", - r->name, target_fate[ (int) r->fate ], target_fate[ T_FATE_REBUILD ] ); - - /* Force rebuild it. */ - r->fate = T_FATE_REBUILD; - - /* And make sure its dependants are updated too. */ - update_dependants( r ); - } - } -} - - -/* - * make0() - bind and scan everything to make a TARGET. - * - * Recursively binds a target, searches for #included headers, calls itself on - * those headers and any dependencies. - */ - -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; - TARGET * ptime = t; - time_t last; - time_t leaf; - time_t hlast; - int fate; - char const * flag = ""; - SETTINGS * s; - -#ifdef OPT_GRAPH_DEBUG_EXT - int savedFate, oldTimeStamp; -#endif - - if ( DEBUG_MAKEPROG ) - printf( "make\t--\t%s%s\n", spaces( depth ), t->name ); - - /* - * 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 is a file). */ - if ( ( t->binding == T_BIND_UNBOUND ) && !( t->flags & T_FLAG_NOTFILE ) ) - { - char * another_target; - t->boundname = search( t->name, &t->time, &another_target, - t->flags & T_FLAG_ISFILE ); - /* If it was detected that this target refers to an already existing and - * bound one, we add an include dependency, so that every target - * depending on us will depend on that other target as well. - */ - if ( another_target ) - target_include( t, bindtarget( another_target ) ); - - 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 does not 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; - } - -#ifdef OPT_SEMAPHORE - { - LIST * var = var_get( "JAM_SEMAPHORE" ); - if ( var ) - { - TARGET * semaphore = bindtarget( var->string ); - semaphore->progress = T_MAKE_SEMAPHORE; - t->semaphore = semaphore; - } - } -#endif - - /* 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_BIND ) - { - 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[ (int) 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() dependencies & headers. - */ - - /* Step 3a: recursively make0() dependencies. */ - for ( c = t->depends; c; c = c->next ) - { - int internal = t->flags & T_FLAG_INTERNAL; - - /* 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 dependencies' includes to our direct dependencies. */ - { - TARGETS * incs = 0; - for ( c = t->depends; c; c = c->next ) - if ( c->target->includes ) - incs = targetentry( incs, c->target->includes ); - t->depends = targetchain( t->depends, incs ); - } - - /* - * Step 4: compute time & fate - */ - - /* Step 4a: pick up dependencies' 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 ); - -#ifdef OPT_GRAPH_DEBUG_EXT - if ( DEBUG_FATE ) - if ( fate < c->target->fate ) - printf( "fate change %s from %s to %s by dependency %s\n", - t->name, target_fate[(int) fate], target_fate[(int) c->target->fate], - c->target->name ); -#endif - } - - /* 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, mark it as having eternally old dependencies. - * Do not inherit our fate from our dependencies. Decide fate based only on - * other flags and our binding (done later). - */ - if ( t->flags & T_FLAG_NOUPDATE ) - { -#ifdef OPT_GRAPH_DEBUG_EXT - if ( DEBUG_FATE ) - if ( fate != T_FATE_STABLE ) - printf( "fate change %s back to stable, NOUPDATE.\n", t->name - ); -#endif - - last = 0; - t->time = 0; - - /* Do not inherit our fate from our dependencies. Decide fate based only - * upon other flags and our binding (done later). - */ - fate = T_FATE_STABLE; - } - - /* Step 4d: determine fate: rebuild target or what? */ - - /* - In English: - If can not find or make child, can not 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. - */ - -#ifdef OPT_GRAPH_DEBUG_EXT - savedFate = fate; - oldTimeStamp = 0; -#endif - - 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 ) ) - { -#ifdef OPT_GRAPH_DEBUG_EXT - oldTimeStamp = 1; -#endif - fate = T_FATE_OUTDATED; - } - else if ( ( t->binding == T_BIND_PARENTS ) && ( last > p->time ) ) - { -#ifdef OPT_GRAPH_DEBUG_EXT - oldTimeStamp = 1; -#endif - 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 ) ) - { -#ifdef OPT_GRAPH_DEBUG_EXT - oldTimeStamp = 1; -#endif - fate = T_FATE_NEWER; - } - else - { - fate = T_FATE_STABLE; - } -#ifdef OPT_GRAPH_DEBUG_EXT - if ( DEBUG_FATE && ( fate != savedFate ) ) - { - if ( savedFate == T_FATE_STABLE ) - printf( "fate change %s set to %s%s\n", t->name, - target_fate[ fate ], oldTimeStamp ? " (by timestamp)" : "" ); - else - printf( "fate change %s from %s to %s%s\n", t->name, - target_fate[ savedFate ], target_fate[ fate ], - oldTimeStamp ? " (by timestamp)" : "" ); - } -#endif - - /* Step 4e: handle missing files */ - /* If it is missing and there are no actions to create it, boom. */ - /* If we can not make a target we do not care about it, okay. */ - /* We could insist that there are updating actions for all missing */ - /* files, but if they have dependencies we just pretend it is a NOTFILE. */ - - if ( ( fate == T_FATE_MISSING ) && !t->actions && !t->depends ) - { - if ( t->flags & T_FLAG_NOCARE ) - { -#ifdef OPT_GRAPH_DEBUG_EXT - if ( DEBUG_FATE ) - printf( "fate change %s to STABLE from %s, " - "no actions, no dependencies and do not care\n", - t->name, target_fate[ fate ] ); -#endif - fate = T_FATE_STABLE; - } - else - { - printf( "don't know how to make %s\n", t->name ); - fate = T_FATE_CANTFIND; - } - } - - /* Step 4f: propagate dependencies' 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 ; - /* This target's fate may have been updated by virtue of following some - * target's rebuilds list, so only allow it to be increased to the fate we - * have calculated. Otherwise, grab its new fate. - */ - if ( fate > t->fate ) - t->fate = fate; - else - fate = t->fate; - - /* Step 4g: if this target needs to be built, force rebuild everything in - * this target's rebuilds list. - */ - if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) ) - force_rebuilds( t ); - - /* - * Step 5: sort dependencies by their update time. - */ - - if ( globs.newestfirst ) - t->depends = make0sort( t->depends ); - - /* - * Step 6: a little harmless tabulating for tracing purposes - */ - - /* Do not count or report interal includes nodes. */ - if ( t->flags & T_FLAG_INTERNAL ) - return; - - if ( counts ) - { -#ifdef OPT_IMPROVED_PATIENCE_EXT - ++counts->targets; -#else - if ( !( ++counts->targets % 1000 ) && DEBUG_MAKE ) - printf( "...patience...\n" ); -#endif - - 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[ (int) t->fate ], - spaces( depth ), t->name ); -} - - -#ifdef OPT_GRAPH_DEBUG_EXT - -static const char * target_name( TARGET * t ) -{ - static char buf[ 1000 ]; - if ( t->flags & T_FLAG_INTERNAL ) - { - sprintf( buf, "%s (internal node)", t->name ); - return buf; - } - return t->name; -} - - -/* - * dependGraphOutput() - output the DG after make0 has run. - */ - -static void dependGraphOutput( TARGET * t, int depth ) -{ - TARGETS * c; - - if ( ( t->flags & T_FLAG_VISITED ) || !t->name || !t->boundname ) - return; - - t->flags |= T_FLAG_VISITED; - - switch ( t->fate ) - { - case T_FATE_TOUCHED: - case T_FATE_MISSING: - case T_FATE_OUTDATED: - case T_FATE_UPDATE: - printf( "->%s%2d Name: %s\n", spaces( depth ), depth, target_name( t ) ); - break; - default: - printf( " %s%2d Name: %s\n", spaces( depth ), depth, target_name( t ) ); - break; - } - - if ( strcmp( t->name, t->boundname ) ) - printf( " %s Loc: %s\n", spaces( depth ), t->boundname ); - - switch ( t->fate ) - { - case T_FATE_STABLE: - printf( " %s : Stable\n", spaces( depth ) ); - break; - case T_FATE_NEWER: - printf( " %s : Newer\n", spaces( depth ) ); - break; - case T_FATE_ISTMP: - printf( " %s : Up to date temp file\n", spaces( depth ) ); - break; - case T_FATE_NEEDTMP: - printf( " %s : Temporary file, to be updated\n", spaces( depth ) ); - break; - case T_FATE_TOUCHED: - printf( " %s : Been touched, updating it\n", spaces( depth ) ); - break; - case T_FATE_MISSING: - printf( " %s : Missing, creating it\n", spaces( depth ) ); - break; - case T_FATE_OUTDATED: - printf( " %s : Outdated, updating it\n", spaces( depth ) ); - break; - case T_FATE_REBUILD: - printf( " %s : Rebuild, updating it\n", spaces( depth ) ); - break; - case T_FATE_UPDATE: - printf( " %s : Updating it\n", spaces( depth ) ); - break; - case T_FATE_CANTFIND: - printf( " %s : Can not find it\n", spaces( depth ) ); - break; - case T_FATE_CANTMAKE: - printf( " %s : Can make it\n", spaces( depth ) ); - break; - } - - if ( t->flags & ~T_FLAG_VISITED ) - { - printf( " %s : ", spaces( depth ) ); - if ( t->flags & T_FLAG_TEMP ) printf( "TEMPORARY " ); - if ( t->flags & T_FLAG_NOCARE ) printf( "NOCARE " ); - if ( t->flags & T_FLAG_NOTFILE ) printf( "NOTFILE " ); - if ( t->flags & T_FLAG_TOUCHED ) printf( "TOUCHED " ); - if ( t->flags & T_FLAG_LEAVES ) printf( "LEAVES " ); - if ( t->flags & T_FLAG_NOUPDATE ) printf( "NOUPDATE " ); - printf( "\n" ); - } - - for ( c = t->depends; c; c = c->next ) - { - printf( " %s : Depends on %s (%s)", spaces( depth ), - target_name( c->target ), target_fate[ (int) c->target->fate ] ); - if ( c->target->time == t->time ) - printf( " (max time)"); - printf( "\n" ); - } - - for ( c = t->depends; c; c = c->next ) - dependGraphOutput( c->target, depth + 1 ); -} -#endif - - -/* - * make0sort() - reorder TARGETS chain by their time (newest to oldest). - * - * We walk chain, taking each item and inserting it on the sorted result, with - * newest items at the front. This involves updating each of the 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. - */ - -static TARGETS * make0sort( TARGETS * chain ) -{ - PROFILE_ENTER( MAKE_MAKE0SORT ); - - TARGETS * result = 0; - - /* Walk the 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). Do not 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 */ - } - - PROFILE_EXIT( MAKE_MAKE0SORT ); - return result; -} - - -static LIST * targets_to_update_ = 0; - - -void mark_target_for_updating( char * target ) -{ - targets_to_update_ = list_new( targets_to_update_, target ); -} - - -LIST * targets_to_update() -{ - return targets_to_update_; -} - - -void clear_targets_to_update() -{ - list_free( targets_to_update_ ); - targets_to_update_ = 0; -} diff --git a/jam-files/engine/make.h b/jam-files/engine/make.h deleted file mode 100644 index b372263e..00000000 --- a/jam-files/engine/make.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 - */ - -#include "lists.h" - -int make( int n_targets, const char **targets, int anyhow ); -int make1( TARGET *t ); - -typedef struct { - int temp; - int updating; - int cantfind; - int cantmake; - int targets; - int made; -} COUNTS ; - - -void make0( TARGET *t, TARGET *p, int depth, - COUNTS *counts, int anyhow ); - - -/* - * Specifies that the target should be updated. - */ -void mark_target_for_updating(char *target); -/* - * Returns the list of all the target previously passed to 'mark_target_for_updating'. - */ -LIST *targets_to_update(); -/* - * Cleasr/unmarks all targets that are currently marked for update. - */ -void clear_targets_to_update(); diff --git a/jam-files/engine/make1.c b/jam-files/engine/make1.c deleted file mode 100644 index 8001f333..00000000 --- a/jam-files/engine/make1.c +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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 of its dependencies. - * - * Internal routines, the recursive/asynchronous command executors: - * - * make1a() - recursively traverse dependency target tree, calling make1b(). - * make1atail() - started processing all dependencies so go on to make1b(). - * make1b() - when dependencies are up to date, build target with make1c(). - * make1c() - launch target's next command, call parents' make1b() if none. - * 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 values, 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 exec_cmd(). - * 02/28/95 (seiwald) - Handle empty "existing" actions. - * 03/10/95 (seiwald) - Fancy counts. - */ - -#include "jam.h" - -#include "lists.h" -#include "parse.h" -#include "assert.h" -#include "variable.h" -#include "rules.h" -#include "headers.h" - -#include "search.h" -#include "newstr.h" -#include "make.h" -#include "command.h" -#include "execcmd.h" -#include "compile.h" -#include "output.h" - -#include <stdlib.h> - -#if ! defined(NT) || defined(__GNUC__) - #include <unistd.h> /* for unlink */ -#endif - -static CMD * make1cmds ( TARGET * ); -static LIST * make1list ( LIST *, TARGETS *, int flags ); -static SETTINGS * make1settings( LIST * vars ); -static void make1bind ( TARGET * ); - -/* Ugly static - it is too hard to carry it through the callbacks. */ - -static struct -{ - int failed; - int skipped; - int total; - int made; -} counts[ 1 ] ; - -/* Target state - remove recursive calls by just keeping track of state target - * is in. - */ -typedef struct _state -{ - struct _state * prev; /* previous state on stack */ - TARGET * t; /* current target */ - TARGET * parent; /* parent argument necessary for make1a() */ -#define T_STATE_MAKE1A 0 /* make1a() should be called */ -#define T_STATE_MAKE1ATAIL 1 /* make1atail() should be called */ -#define T_STATE_MAKE1B 2 /* make1b() should be called */ -#define T_STATE_MAKE1C 3 /* make1c() should be called */ -#define T_STATE_MAKE1D 4 /* make1d() should be called */ - int curstate; /* current state */ - int status; -} state; - -static void make1a ( state * ); -static void make1atail ( state * ); -static void make1b ( state * ); -static void make1c ( state * ); -static void make1d ( state * ); -static void make_closure( void * closure, int status, timing_info *, char *, char * ); - -typedef struct _stack -{ - state * stack; -} stack; - -static stack state_stack = { NULL }; - -static state * state_freelist = NULL; - - -static state * alloc_state() -{ - if ( state_freelist != NULL ) - { - state * pState = state_freelist; - state_freelist = pState->prev; - memset( pState, 0, sizeof( state ) ); - return pState; - } - - return (state *)BJAM_MALLOC( sizeof( state ) ); -} - - -static void free_state( state * pState ) -{ - pState->prev = state_freelist; - state_freelist = pState; -} - - -static void clear_state_freelist() -{ - while ( state_freelist != NULL ) - { - state * pState = state_freelist; - state_freelist = state_freelist->prev; - BJAM_FREE( pState ); - } -} - - -static state * current_state( stack * pStack ) -{ - return pStack->stack; -} - - -static void pop_state( stack * pStack ) -{ - if ( pStack->stack != NULL ) - { - state * pState = pStack->stack->prev; - free_state( pStack->stack ); - pStack->stack = pState; - } -} - - -static state * push_state( stack * pStack, TARGET * t, TARGET * parent, int curstate ) -{ - state * pState = alloc_state(); - - pState->t = t; - pState->parent = parent; - pState->prev = pStack->stack; - pState->curstate = curstate; - - pStack->stack = pState; - - return pStack->stack; -} - - -/* - * Pushes a stack onto another stack, effectively reversing the order. - */ - -static void push_stack_on_stack( stack * pDest, stack * pSrc ) -{ - while ( pSrc->stack != NULL ) - { - state * pState = pSrc->stack; - pSrc->stack = pSrc->stack->prev; - pState->prev = pDest->stack; - pDest->stack = pState; - } -} - - -/* - * make1() - execute commands to update a TARGET and all of its dependencies. - */ - -static int intr = 0; - -int make1( TARGET * t ) -{ - state * pState; - - memset( (char *)counts, 0, sizeof( *counts ) ); - - /* Recursively make the target and its dependencies. */ - push_state( &state_stack, t, NULL, T_STATE_MAKE1A ); - - do - { - while ( ( pState = current_state( &state_stack ) ) != NULL ) - { - if ( intr ) - pop_state( &state_stack ); - - switch ( pState->curstate ) - { - case T_STATE_MAKE1A : make1a ( pState ); break; - case T_STATE_MAKE1ATAIL: make1atail( pState ); break; - case T_STATE_MAKE1B : make1b ( pState ); break; - case T_STATE_MAKE1C : make1c ( pState ); break; - case T_STATE_MAKE1D : make1d ( pState ); break; - } - } - } - /* Wait for any outstanding commands to finish running. */ - while ( exec_wait() ); - - clear_state_freelist(); - - /* Talk about it. */ - if ( counts->failed ) - printf( "...failed updating %d target%s...\n", counts->failed, - counts->failed > 1 ? "s" : "" ); - if ( DEBUG_MAKE && counts->skipped ) - printf( "...skipped %d target%s...\n", counts->skipped, - counts->skipped > 1 ? "s" : "" ); - if ( DEBUG_MAKE && counts->made ) - printf( "...updated %d target%s...\n", counts->made, - counts->made > 1 ? "s" : "" ); - - return counts->total != counts->made; -} - - -/* - * make1a() - recursively traverse target tree, calling make1b(). - * - * Called to start processing a specified target. Does nothing if the target is - * already being processed or otherwise starts processing all of its - * dependencies. Once all of its dependencies have started being processed goes - * on and calls make1b() (actually does that indirectly via a helper - * make1atail() state). - */ - -static void make1a( state * pState ) -{ - TARGET * t = pState->t; - 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 ( pState->parent ) - switch ( pState->t->progress ) - { - case T_MAKE_INIT: - case T_MAKE_ACTIVE: - case T_MAKE_RUNNING: - pState->t->parents = targetentry( pState->t->parents, - pState->parent ); - ++pState->parent->asynccnt; - } - - /* If this target is already being processed then do nothing. There is no - * need to start processing the same target all over again. - */ - if ( pState->t->progress != T_MAKE_INIT ) - { - pop_state( &state_stack ); - return; - } - - /* Asynccnt counts the dependencies 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 notify all dependencies that - * they are needed. This 1 is accounted for when we call make1b() ourselves, - * below. Without this if a a dependency gets built before we finish - * processing all of our other dependencies our build might be triggerred - * prematurely. - */ - pState->t->asynccnt = 1; - - /* Add header nodes created during the building process. */ - { - TARGETS * inc = 0; - for ( c = t->depends; c; c = c->next ) - if ( c->target->rescanned && c->target->includes ) - inc = targetentry( inc, c->target->includes ); - t->depends = targetchain( t->depends, inc ); - } - - /* Guard against circular dependencies. */ - pState->t->progress = T_MAKE_ONSTACK; - - { - stack temp_stack = { NULL }; - for ( c = t->depends; c && !intr; c = c->next ) - push_state( &temp_stack, c->target, pState->t, T_STATE_MAKE1A ); - - /* Using stacks reverses the order of execution. Reverse it back. */ - push_stack_on_stack( &state_stack, &temp_stack ); - } - - pState->curstate = T_STATE_MAKE1ATAIL; -} - - -/* - * make1atail() - started processing all dependencies so go on to make1b(). - */ - -static void make1atail( state * pState ) -{ - pState->t->progress = T_MAKE_ACTIVE; - /* Now that all of our dependencies have bumped up our asynccnt we can - * remove our own internal bump added to prevent this target from being - * built before all of its dependencies start getting processed. - */ - pState->curstate = T_STATE_MAKE1B; -} - - -/* - * make1b() - when dependencies are up to date, build target with make1c(). - * - * Called after all dependencies have started being processed and after each of - * them finishes its processing. The target actually goes on to getting built in - * make1c() only after all of its dependencies have finished their processing. - */ - -static void make1b( state * pState ) -{ - TARGET * t = pState->t; - TARGETS * c; - TARGET * failed = 0; - char * failed_name = "dependencies"; - - /* If any dependencies are still outstanding, wait until they call make1b() - * to signal their completion. - */ - if ( --pState->t->asynccnt ) - { - pop_state( &state_stack ); - return; - } - - /* Try to aquire a semaphore. If it is locked, wait until the target that - * locked it is built and signal completition. - */ -#ifdef OPT_SEMAPHORE - if ( t->semaphore && t->semaphore->asynccnt ) - { - /* Append 't' to the list of targets waiting on semaphore. */ - t->semaphore->parents = targetentry( t->semaphore->parents, t ); - t->asynccnt++; - - if ( DEBUG_EXECCMD ) - printf( "SEM: %s is busy, delaying launch of %s\n", - t->semaphore->name, t->name ); - pop_state( &state_stack ); - return; - } -#endif - - /* Now ready to build target 't', if dependencies built OK. */ - - /* Collect status from dependencies. */ - for ( c = t->depends; c; c = c->next ) - if ( c->target->status > t->status && !( c->target->flags & T_FLAG_NOCARE ) ) - { - failed = c->target; - pState->t->status = c->target->status; - } - /* If an internal header node failed to build, we want to output the target - * that it failed on. - */ - if ( failed ) - { - failed_name = failed->flags & T_FLAG_INTERNAL - ? failed->failed - : failed->name; - } - t->failed = failed_name; - - /* If actions for building any of the dependencies have failed, bail. - * Otherwise, execute all actions to make the current target. - */ - if ( ( pState->t->status == EXEC_CMD_FAIL ) && pState->t->actions ) - { - ++counts->skipped; - if ( ( pState->t->flags & ( T_FLAG_RMOLD | T_FLAG_NOTFILE ) ) == T_FLAG_RMOLD ) - { - if ( !unlink( pState->t->boundname ) ) - printf( "...removing outdated %s\n", pState->t->boundname ); - } - else - printf( "...skipped %s for lack of %s...\n", pState->t->name, failed_name ); - } - - if ( pState->t->status == EXEC_CMD_OK ) - switch ( pState->t->fate ) - { - /* These are handled by the default case below now - case T_FATE_INIT: - case T_FATE_MAKING: - */ - - case T_FATE_STABLE: - case T_FATE_NEWER: - break; - - case T_FATE_CANTFIND: - case T_FATE_CANTMAKE: - pState->t->status = EXEC_CMD_FAIL; - break; - - case T_FATE_ISTMP: - if ( DEBUG_MAKE ) - printf( "...using %s...\n", pState->t->name ); - break; - - case T_FATE_TOUCHED: - case T_FATE_MISSING: - case T_FATE_NEEDTMP: - case T_FATE_OUTDATED: - case T_FATE_UPDATE: - case T_FATE_REBUILD: - /* Prepare commands for executing actions scheduled for this target - * and then schedule transfer to make1c() state to proceed with - * executing the prepared commands. Commands have their embedded - * variables automatically expanded, including making use of any "on - * target" variables. - */ - if ( pState->t->actions ) - { - ++counts->total; - if ( DEBUG_MAKE && !( counts->total % 100 ) ) - printf( "...on %dth target...\n", counts->total ); - - pState->t->cmds = (char *)make1cmds( pState->t ); - /* Set the target's "progress" so that make1c() counts it among - * its successes/failures. - */ - pState->t->progress = T_MAKE_RUNNING; - } - break; - - /* All possible fates should have been accounted for by now. */ - default: - printf( "ERROR: %s has bad fate %d", pState->t->name, - pState->t->fate ); - abort(); - } - - /* Call make1c() to begin the execution of the chain of commands needed to - * build the target. If we are not going to build the target (due of - * dependency failures or no commands needing to be run) the chain will be - * empty and make1c() will directly signal the target's completion. - */ - -#ifdef OPT_SEMAPHORE - /* If there is a semaphore, indicate that it is in use. */ - if ( pState->t->semaphore ) - { - ++pState->t->semaphore->asynccnt; - if ( DEBUG_EXECCMD ) - printf( "SEM: %s now used by %s\n", pState->t->semaphore->name, - pState->t->name ); - } -#endif - - pState->curstate = T_STATE_MAKE1C; -} - - -/* - * make1c() - launch target's next command, call parents' make1b() if none. - * - * If there are (more) commands to run to build this target (and we have not hit - * an error running earlier comands) we launch the command using exec_cmd(). If - * there are no more commands to run, we collect the status from all the actions - * and report our completion to all the parents. - */ - -static void make1c( state * pState ) -{ - CMD * cmd = (CMD *)pState->t->cmds; - - if ( cmd && ( pState->t->status == EXEC_CMD_OK ) ) - { - char * rule_name = 0; - char * target = 0; - - if ( DEBUG_MAKEQ || - ( !( cmd->rule->actions->flags & RULE_QUIETLY ) && DEBUG_MAKE ) ) - { - rule_name = cmd->rule->name; - target = lol_get( &cmd->args, 0 )->string; - if ( globs.noexec ) - out_action( rule_name, target, cmd->buf, "", "", EXIT_OK ); - } - - if ( globs.noexec ) - { - pState->curstate = T_STATE_MAKE1D; - pState->status = EXEC_CMD_OK; - } - else - { - /* Pop state first because exec_cmd() could push state. */ - pop_state( &state_stack ); - exec_cmd( cmd->buf, make_closure, pState->t, cmd->shell, rule_name, - target ); - } - } - else - { - TARGETS * c; - ACTIONS * actions; - - /* Collect status from actions, and distribute it as well. */ - for ( actions = pState->t->actions; actions; actions = actions->next ) - if ( actions->action->status > pState->t->status ) - pState->t->status = actions->action->status; - for ( actions = pState->t->actions; actions; actions = actions->next ) - if ( pState->t->status > actions->action->status ) - actions->action->status = pState->t->status; - - /* Tally success/failure for those we tried to update. */ - if ( pState->t->progress == T_MAKE_RUNNING ) - switch ( pState->t->status ) - { - case EXEC_CMD_OK : ++counts->made ; break; - case EXEC_CMD_FAIL: ++counts->failed; break; - } - - /* Tell parents their dependency has been built. */ - { - stack temp_stack = { NULL }; - TARGET * t = pState->t; - TARGET * additional_includes = NULL; - - t->progress = T_MAKE_DONE; - - /* Target has been updated so rescan it for dependencies. */ - if ( ( t->fate >= T_FATE_MISSING ) && - ( t->status == EXEC_CMD_OK ) && - !t->rescanned ) - { - TARGET * target_to_rescan = t; - SETTINGS * s; - - target_to_rescan->rescanned = 1; - - if ( target_to_rescan->flags & T_FLAG_INTERNAL ) - target_to_rescan = t->original_target; - - /* Clean current includes. */ - target_to_rescan->includes = 0; - - s = copysettings( target_to_rescan->settings ); - pushsettings( s ); - headers( target_to_rescan ); - popsettings( s ); - freesettings( s ); - - if ( target_to_rescan->includes ) - { - target_to_rescan->includes->rescanned = 1; - /* Tricky. The parents have already been processed, but they - * have not seen the internal node, because it was just - * created. We need to make the calls to make1a() that would - * have been made by the parents here, and also make sure - * all unprocessed parents will pick up the includes. We - * must make sure processing of the additional make1a() - * invocations is done before make1b() which means this - * target is built, otherwise the parent would be considered - * built before this make1a() processing has even started. - */ - make0( target_to_rescan->includes, target_to_rescan->parents->target, 0, 0, 0 ); - for ( c = target_to_rescan->parents; c; c = c->next ) - c->target->depends = targetentry( c->target->depends, - target_to_rescan->includes ); - /* Will be processed below. */ - additional_includes = target_to_rescan->includes; - } - } - - if ( additional_includes ) - for ( c = t->parents; c; c = c->next ) - push_state( &temp_stack, additional_includes, c->target, T_STATE_MAKE1A ); - - for ( c = t->parents; c; c = c->next ) - push_state( &temp_stack, c->target, NULL, T_STATE_MAKE1B ); - -#ifdef OPT_SEMAPHORE - /* If there is a semaphore, it is now free. */ - if ( t->semaphore ) - { - assert( t->semaphore->asynccnt == 1 ); - --t->semaphore->asynccnt; - - if ( DEBUG_EXECCMD ) - printf( "SEM: %s is now free\n", t->semaphore->name ); - - /* If anything is waiting, notify the next target. There is no - * point in notifying waiting targets, since they will be - * notified again. - */ - if ( t->semaphore->parents ) - { - TARGETS * first = t->semaphore->parents; - if ( first->next ) - first->next->tail = first->tail; - t->semaphore->parents = first->next; - - if ( DEBUG_EXECCMD ) - printf( "SEM: placing %s on stack\n", first->target->name ); - push_state( &temp_stack, first->target, NULL, T_STATE_MAKE1B ); - BJAM_FREE( first ); - } - } -#endif - - /* Must pop state before pushing any more. */ - pop_state( &state_stack ); - - /* Using stacks reverses the order of execution. Reverse it back. */ - push_stack_on_stack( &state_stack, &temp_stack ); - } - } -} - - -/* - * call_timing_rule() - Look up the __TIMING_RULE__ variable on the given - * target, and if non-empty, invoke the rule it names, passing the given - * timing_info. - */ - -static void call_timing_rule( TARGET * target, timing_info * time ) -{ - LIST * timing_rule; - - pushsettings( target->settings ); - timing_rule = var_get( "__TIMING_RULE__" ); - popsettings( target->settings ); - - if ( timing_rule ) - { - /* rule timing-rule ( args * : target : start end user system ) */ - - /* Prepare the argument list. */ - FRAME frame[ 1 ]; - frame_init( frame ); - - /* args * :: $(__TIMING_RULE__[2-]) */ - lol_add( frame->args, list_copy( L0, timing_rule->next ) ); - - /* target :: the name of the target */ - lol_add( frame->args, list_new( L0, target->name ) ); - - /* start end user system :: info about the action command */ - lol_add( frame->args, list_new( list_new( list_new( list_new( L0, - outf_time ( time->start ) ), - outf_time ( time->end ) ), - outf_double( time->user ) ), - outf_double( time->system ) ) ); - - /* Call the rule. */ - evaluate_rule( timing_rule->string, frame ); - - /* Clean up. */ - frame_free( frame ); - } -} - - -/* - * call_action_rule() - Look up the __ACTION_RULE__ variable on the given - * target, and if non-empty, invoke the rule it names, passing the given info, - * timing_info, executed command and command output. - */ - -static void call_action_rule -( - TARGET * target, - int status, - timing_info * time, - char * executed_command, - char * command_output -) -{ - LIST * action_rule; - - pushsettings( target->settings ); - action_rule = var_get( "__ACTION_RULE__" ); - popsettings( target->settings ); - - if ( action_rule ) - { - /* rule action-rule ( - args * : - target : - command status start end user system : - output ? ) */ - - /* Prepare the argument list. */ - FRAME frame[ 1 ]; - frame_init( frame ); - - /* args * :: $(__ACTION_RULE__[2-]) */ - lol_add( frame->args, list_copy( L0, action_rule->next ) ); - - /* target :: the name of the target */ - lol_add( frame->args, list_new( L0, target->name ) ); - - /* command status start end user system :: info about the action command */ - lol_add( frame->args, - list_new( list_new( list_new( list_new( list_new( list_new( L0, - newstr( executed_command ) ), - outf_int( status ) ), - outf_time( time->start ) ), - outf_time( time->end ) ), - outf_double( time->user ) ), - outf_double( time->system ) ) ); - - /* output ? :: the output of the action command */ - if ( command_output ) - lol_add( frame->args, list_new( L0, newstr( command_output ) ) ); - else - lol_add( frame->args, L0 ); - - /* Call the rule. */ - evaluate_rule( action_rule->string, frame ); - - /* Clean up. */ - frame_free( frame ); - } -} - - -/* - * make_closure() - internal function passed as a notification callback for when - * commands finish getting executed by the OS. - */ - -static void make_closure -( - void * closure, - int status, - timing_info * time, - char * executed_command, - char * command_output -) -{ - TARGET * built = (TARGET *)closure; - - call_timing_rule( built, time ); - if ( DEBUG_EXECCMD ) - printf( "%f sec system; %f sec user\n", time->system, time->user ); - - call_action_rule( built, status, time, executed_command, command_output ); - - push_state( &state_stack, built, NULL, T_STATE_MAKE1D )->status = status; -} - - -/* - * make1d() - handle command execution completion and call back make1c(). - * - * exec_cmd() has completed and now all we need to do is fiddle with the status - * and call back to make1c() so it can run the next command scheduled for - * building this target or close up the target's build process in case there are - * no more commands scheduled for it. On interrupts, we bail heavily. - */ - -static void make1d( state * pState ) -{ - TARGET * t = pState->t; - CMD * cmd = (CMD *)t->cmds; - int status = pState->status; - - if ( t->flags & T_FLAG_FAIL_EXPECTED ) - { - /* Invert execution result when FAIL_EXPECTED has been applied. */ - switch ( status ) - { - case EXEC_CMD_FAIL: status = EXEC_CMD_OK ; break; - case EXEC_CMD_OK: status = EXEC_CMD_FAIL; break; - } - } - - if ( ( status == EXEC_CMD_FAIL ) && - ( cmd->rule->actions->flags & RULE_IGNORE ) ) - status = EXEC_CMD_OK; - - /* On interrupt, set intr so _everything_ fails. */ - if ( status == EXEC_CMD_INTR ) - ++intr; - - /* Print command text on failure. */ - if ( ( status == EXEC_CMD_FAIL ) && DEBUG_MAKE ) - { - if ( !DEBUG_EXEC ) - printf( "%s\n", cmd->buf ); - - printf( "...failed %s ", cmd->rule->name ); - list_print( lol_get( &cmd->args, 0 ) ); - printf( "...\n" ); - } - - /* Treat failed commands as interrupts in case we were asked to stop the - * build in case of any errors. - */ - if ( ( status == EXEC_CMD_FAIL ) && globs.quitquick ) - ++intr; - - /* If the command was interrupted or failed and the target is not - * "precious", remove the targets. - */ - if (status != EXEC_CMD_OK) - { - LIST * targets = lol_get( &cmd->args, 0 ); - for ( ; targets; targets = list_next( targets ) ) - { - int need_unlink = 1; - TARGET* t = bindtarget ( targets->string ); - if (t->flags & T_FLAG_PRECIOUS) - { - need_unlink = 0; - } - if (need_unlink && !unlink( targets->string ) ) - printf( "...removing %s\n", targets->string ); - } - } - - /* Free this command and call make1c() to move onto the next one scheduled - * for building this same target. - */ - t->status = status; - t->cmds = (char *)cmd_next( cmd ); - cmd_free( cmd ); - pState->curstate = T_STATE_MAKE1C; -} - - -/* - * swap_settings() - replace the settings from the current module and target - * with those from the new module and target - */ - -static void swap_settings -( - module_t * * current_module, - TARGET * * current_target, - module_t * new_module, - TARGET * new_target -) -{ - if ( new_module == root_module() ) - new_module = 0; - - if ( ( new_target == *current_target ) && ( new_module == *current_module ) ) - return; - - if ( *current_target ) - popsettings( (*current_target)->settings ); - - if ( new_module != *current_module ) - { - if ( *current_module ) - exit_module( *current_module ); - - *current_module = new_module; - - if ( new_module ) - enter_module( new_module ); - } - - *current_target = new_target; - if ( new_target ) - pushsettings( new_target->settings ); -} - - -/* - * 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_NEWSRCS actions. The result is a chain of CMDs which can be expanded by - * var_string() and executed using exec_cmd(). - */ - -static CMD * make1cmds( TARGET * t ) -{ - CMD * cmds = 0; - LIST * shell = 0; - module_t * settings_module = 0; - TARGET * settings_target = 0; - ACTIONS * a0; - - /* Step through actions. Actions may be shared with other targets or grouped - * using RULE_TOGETHER, so actions already seen are skipped. - */ - for ( a0 = t->actions ; a0; a0 = a0->next ) - { - RULE * rule = a0->action->rule; - rule_actions * actions = rule->actions; - SETTINGS * boundvars; - LIST * nt; - LIST * ns; - ACTIONS * a1; - int start; - int chunk; - int length; - - /* Only do rules with commands to execute. If this action has already - * been executed, use saved status. - */ - if ( !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, actions->flags ); - if ( actions->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, actions->flags ); - a1->action->running = 1; - } - - /* If doing only updated (or existing) sources, but none have been - * updated (or exist), skip this action. - */ - if ( !ns && ( actions->flags & ( RULE_NEWSRCS | RULE_EXISTING ) ) ) - { - list_free( nt ); - continue; - } - - swap_settings( &settings_module, &settings_target, rule->module, t ); - if ( !shell ) - shell = var_get( "JAMSHELL" ); /* shell is per-target */ - - /* If we had 'actions xxx bind vars' we bind the vars now. */ - boundvars = make1settings( actions->bindlist ); - pushsettings( boundvars ); - - /* - * Build command, starting with all source args. - * - * If cmd_new returns 0, it is because the resulting command length is - * > MAXLINE. In this case, we will 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 is worth it to get as close to MAXLINE as possible, because - * launching the commands we are executing is likely to be much more - * compute intensive. - * - * Note we loop through at least once, for sourceless actions. - */ - - start = 0; - chunk = length = list_length( ns ); - - 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 ) ); - - if ( cmd ) - { - /* It fit: chain it up. */ - if ( !cmds ) cmds = cmd; - else cmds->tail->next = cmd; - cmds->tail = cmd; - start += chunk; - } - else if ( ( actions->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 - ); - - /* Tell the user what didn't fit. */ - cmd = cmd_new( rule, list_copy( L0, nt ), - list_sublist( ns, start, chunk ), - list_new( L0, newstr( "%" ) ) ); - fputs( cmd->buf, stdout ); - 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 ); - } - - swap_settings( &settings_module, &settings_target, 0, 0 ); - 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; - - if ( t->binding == T_BIND_UNBOUND ) - make1bind( t ); - - if ( ( flags & RULE_EXISTING ) && ( flags & RULE_NEWSRCS ) ) - { - if ( ( t->binding != T_BIND_EXISTS ) && ( t->fate <= T_FATE_STABLE ) ) - continue; - } - else - { - if ( ( flags & RULE_EXISTING ) && ( t->binding != T_BIND_EXISTS ) ) - continue; - - if ( ( flags & RULE_NEWSRCS ) && ( 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, copystr( t->boundname ) ); - } - - 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. */ - if ( t->binding == T_BIND_UNBOUND ) - make1bind( t ); - - /* Build a new list. */ - nl = list_new( nl, copystr( t->boundname ) ); - } - - /* Add to settings chain. */ - settings = addsettings( settings, VAR_SET, vars->string, nl ); - } - - return settings; -} - - -/* - * make1bind() - bind targets that were not bound during dependency analysis - * - * Spot the kludge! If a target is not in the dependency tree, it did not get - * bound by make0(), so we have to do it here. Ugly. - */ - -static void make1bind( TARGET * t ) -{ - if ( t->flags & T_FLAG_NOTFILE ) - return; - - pushsettings( t->settings ); - t->boundname = search( t->name, &t->time, 0, ( t->flags & T_FLAG_ISFILE ) ); - t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING; - popsettings( t->settings ); -} diff --git a/jam-files/engine/md5.c b/jam-files/engine/md5.c deleted file mode 100644 index c35d96c5..00000000 --- a/jam-files/engine/md5.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include <string.h> - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include <stdio.h> in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5.h" -#include <string.h> - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -#else -# define BYTE_ORDER 0 -#endif - -#define T_MASK ((md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - - -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) -{ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } -#endif - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init(md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -{ - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -{ - static const md5_byte_t pad[64] = { - 0x80, 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 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} diff --git a/jam-files/engine/md5.h b/jam-files/engine/md5.h deleted file mode 100644 index 698c995d..00000000 --- a/jam-files/engine/md5.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.h is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke <purschke@bnl.gov>. - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); - -/* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* md5_INCLUDED */ diff --git a/jam-files/engine/mem.c b/jam-files/engine/mem.c deleted file mode 100644 index 6a11fb38..00000000 --- a/jam-files/engine/mem.c +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright Rene Rivera 2006. -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE_1_0.txt or copy at -http://www.boost.org/LICENSE_1_0.txt) -*/ - -#include "jam.h" - -#ifdef OPT_BOEHM_GC - - /* Compile the Boehm GC as one big chunk of code. It's much easier - this way, than trying to make radical changes to the bjam build - scripts. */ - - #define ATOMIC_UNCOLLECTABLE - #define NO_EXECUTE_PERMISSION - #define ALL_INTERIOR_POINTERS - - #define LARGE_CONFIG - /* - #define NO_SIGNALS - #define SILENT - */ - #ifndef GC_DEBUG - #define NO_DEBUGGING - #endif - - #ifdef __GLIBC__ - #define __USE_GNU - #endif - - #include "boehm_gc/reclaim.c" - #include "boehm_gc/allchblk.c" - #include "boehm_gc/misc.c" - #include "boehm_gc/alloc.c" - #include "boehm_gc/mach_dep.c" - #include "boehm_gc/os_dep.c" - #include "boehm_gc/mark_rts.c" - #include "boehm_gc/headers.c" - #include "boehm_gc/mark.c" - #include "boehm_gc/obj_map.c" - #include "boehm_gc/pcr_interface.c" - #include "boehm_gc/blacklst.c" - #include "boehm_gc/new_hblk.c" - #include "boehm_gc/real_malloc.c" - #include "boehm_gc/dyn_load.c" - #include "boehm_gc/dbg_mlc.c" - #include "boehm_gc/malloc.c" - #include "boehm_gc/stubborn.c" - #include "boehm_gc/checksums.c" - #include "boehm_gc/pthread_support.c" - #include "boehm_gc/pthread_stop_world.c" - #include "boehm_gc/darwin_stop_world.c" - #include "boehm_gc/typd_mlc.c" - #include "boehm_gc/ptr_chck.c" - #include "boehm_gc/mallocx.c" - #include "boehm_gc/gcj_mlc.c" - #include "boehm_gc/specific.c" - #include "boehm_gc/gc_dlopen.c" - #include "boehm_gc/backgraph.c" - #include "boehm_gc/win32_threads.c" - - /* Needs to be last. */ - #include "boehm_gc/finalize.c" - -#elif defined(OPT_DUMA) - - #ifdef OS_NT - #define WIN32 - #endif - #include "duma/duma.c" - #include "duma/print.c" - -#endif diff --git a/jam-files/engine/mem.h b/jam-files/engine/mem.h deleted file mode 100644 index 71b2fb4b..00000000 --- a/jam-files/engine/mem.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright Rene Rivera 2006. -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE_1_0.txt or copy at -http://www.boost.org/LICENSE_1_0.txt) -*/ - -#ifndef BJAM_MEM_H -#define BJAM_MEM_H - - -#ifdef OPT_BOEHM_GC - - /* Use Boehm GC memory allocator. */ - #include <gc.h> - #define bjam_malloc_x(s) memset(GC_malloc(s),0,s) - #define bjam_malloc_atomic_x(s) memset(GC_malloc_atomic(s),0,s) - #define bjam_calloc_x(n,s) memset(GC_malloc((n)*(s)),0,(n)*(s)) - #define bjam_calloc_atomic_x(n,s) memset(GC_malloc_atomic((n)*(s)),0,(n)*(s)) - #define bjam_realloc_x(p,s) GC_realloc(p,s) - #define bjam_free_x(p) GC_free(p) - #define bjam_mem_init_x() GC_init(); GC_enable_incremental() - - #define bjam_malloc_raw_x(s) malloc(s) - #define bjam_calloc_raw_x(n,s) calloc(n,s) - #define bjam_realloc_raw_x(p,s) realloc(p,s) - #define bjam_free_raw_x(p) free(p) - - #ifndef BJAM_NEWSTR_NO_ALLOCATE - #define BJAM_NEWSTR_NO_ALLOCATE - #endif - -#elif defined(OPT_DUMA) - - /* Use Duma memory debugging library. */ - #include <stdlib.h> - #define _DUMA_CONFIG_H_ - #define DUMA_NO_GLOBAL_MALLOC_FREE - #define DUMA_EXPLICIT_INIT - #define DUMA_NO_THREAD_SAFETY - #define DUMA_NO_CPP_SUPPORT - /* #define DUMA_NO_LEAKDETECTION */ - /* #define DUMA_USE_FRAMENO */ - /* #define DUMA_PREFER_ATEXIT */ - /* #define DUMA_OLD_DEL_MACRO */ - /* #define DUMA_NO_HANG_MSG */ - #define DUMA_PAGE_SIZE 4096 - #define DUMA_MIN_ALIGNMENT 1 - /* #define DUMA_GNU_INIT_ATTR 0 */ - typedef unsigned int DUMA_ADDR; - typedef unsigned int DUMA_SIZE; - #include <duma.h> - #define bjam_malloc_x(s) malloc(s) - #define bjam_calloc_x(n,s) calloc(n,s) - #define bjam_realloc_x(p,s) realloc(p,s) - #define bjam_free_x(p) free(p) - - #ifndef BJAM_NEWSTR_NO_ALLOCATE - #define BJAM_NEWSTR_NO_ALLOCATE - #endif - -#else - - /* Standard C memory allocation. */ - #define bjam_malloc_x(s) malloc(s) - #define bjam_calloc_x(n,s) calloc(n,s) - #define bjam_realloc_x(p,s) realloc(p,s) - #define bjam_free_x(p) free(p) - -#endif - -#ifndef bjam_malloc_atomic_x - #define bjam_malloc_atomic_x(s) bjam_malloc_x(s) -#endif -#ifndef bjam_calloc_atomic_x - #define bjam_calloc_atomic_x(n,s) bjam_calloc_x(n,s) -#endif -#ifndef bjam_mem_init_x - #define bjam_mem_init_x() -#endif -#ifndef bjam_mem_close_x - #define bjam_mem_close_x() -#endif -#ifndef bjam_malloc_raw_x - #define bjam_malloc_raw_x(s) bjam_malloc_x(s) -#endif -#ifndef bjam_calloc_raw_x - #define bjam_calloc_raw_x(n,s) bjam_calloc_x(n,s) -#endif -#ifndef bjam_realloc_raw_x - #define bjam_realloc_raw_x(p,s) bjam_realloc_x(p,s) -#endif -#ifndef bjam_free_raw_x - #define bjam_free_raw_x(p) bjam_free_x(p) -#endif - -#ifdef OPT_DEBUG_PROFILE - - /* Profile tracing of memory allocations. */ - #define BJAM_MALLOC(s) (profile_memory(s), bjam_malloc_x(s)) - #define BJAM_MALLOC_ATOMIC(s) (profile_memory(s), bjam_malloc_atomic_x(s)) - #define BJAM_CALLOC(n,s) (profile_memory(n*s), bjam_calloc_x(n,s)) - #define BJAM_CALLOC_ATOMIC(n,s) (profile_memory(n*s), bjam_calloc_atomic_x(n,s)) - #define BJAM_REALLOC(p,s) (profile_memory(s), bjam_realloc_x(p,s)) - #define BJAM_FREE(p) bjam_free_x(p) - #define BJAM_MEM_INIT() bjam_mem_init_x() - #define BJAM_MEM_CLOSE() bjam_mem_close_x() - - #define BJAM_MALLOC_RAW(s) (profile_memory(s), bjam_malloc_raw_x(s)) - #define BJAM_CALLOC_RAW(n,s) (profile_memory(n*s), bjam_calloc_raw_x(n,s)) - #define BJAM_REALLOC_RAW(p,s) (profile_memory(s), bjam_realloc_raw_x(p,s)) - #define BJAM_FREE_RAW(p) bjam_free_raw_x(p) - -#else - - /* No mem tracing. */ - #define BJAM_MALLOC(s) bjam_malloc_x(s) - #define BJAM_MALLOC_ATOMIC(s) bjam_malloc_atomic_x(s) - #define BJAM_CALLOC(n,s) bjam_calloc_x(n,s) - #define BJAM_CALLOC_ATOMIC(n,s) bjam_calloc_atomic_x(n,s) - #define BJAM_REALLOC(p,s) bjam_realloc_x(p,s) - #define BJAM_FREE(p) bjam_free_x(p) - #define BJAM_MEM_INIT() bjam_mem_init_x() - #define BJAM_MEM_CLOSE() bjam_mem_close_x() - - #define BJAM_MALLOC_RAW(s) bjam_malloc_raw_x(s) - #define BJAM_CALLOC_RAW(n,s) bjam_calloc_raw_x(n,s) - #define BJAM_REALLOC_RAW(p,s) bjam_realloc_raw_x(p,s) - #define BJAM_FREE_RAW(p) bjam_free_raw_x(p) - -#endif - - -#endif diff --git a/jam-files/engine/mkjambase.c b/jam-files/engine/mkjambase.c deleted file mode 100644 index cdf59982..00000000 --- a/jam-files/engine/mkjambase.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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. - * - */ - -#include <stdio.h> -#include <string.h> - - -int 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, "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 ) - switch ( *p ) - { - case '\\': putc( '\\', fout ); putc( '\\', fout ); break; - case '"' : putc( '\\', fout ); putc( '"' , fout ); break; - case '\r': 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; -} diff --git a/jam-files/engine/modules.c b/jam-files/engine/modules.c deleted file mode 100644 index 72952594..00000000 --- a/jam-files/engine/modules.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ -#include "jam.h" - -#include "modules.h" -#include "string.h" -#include "hash.h" -#include "newstr.h" -#include "lists.h" -#include "parse.h" -#include "rules.h" -#include "variable.h" -#include "strings.h" -#include <assert.h> - -static struct hash * module_hash = 0; - - -static char * new_module_str( module_t * m, char * suffix ) -{ - char * result; - string s; - string_copy( &s, m->name ); - string_append( &s, suffix ); - result = newstr( s.value ); - string_free( &s ); - return result; -} - - -module_t * bindmodule( char * name ) -{ - PROFILE_ENTER( BINDMODULE ); - - string s; - module_t m_; - module_t * m = &m_; - - if ( !module_hash ) - module_hash = hashinit( sizeof( module_t ), "modules" ); - - string_new( &s ); - if ( name ) - { - string_append( &s, name ); - string_push_back( &s, '.' ); - } - - m->name = s.value; - - if ( hashenter( module_hash, (HASHDATA * *)&m ) ) - { - m->name = newstr( m->name ); - m->variables = 0; - m->rules = 0; - m->imported_modules = 0; - m->class_module = 0; - m->native_rules = 0; - m->user_module = 0; - } - string_free( &s ); - - PROFILE_EXIT( BINDMODULE ); - - return m; -} - -/* - * demand_rules() - Get the module's "rules" hash on demand. - */ -struct hash * demand_rules( module_t * m ) -{ - if ( !m->rules ) - m->rules = hashinit( sizeof( RULE ), new_module_str( m, "rules" ) ); - return m->rules; -} - - -/* - * delete_module() - wipe out the module's rules and variables. - */ - -static void delete_rule_( void * xrule, void * data ) -{ - rule_free( (RULE *)xrule ); -} - - -void delete_module( module_t * m ) -{ - /* Clear out all the rules. */ - if ( m->rules ) - { - hashenumerate( m->rules, delete_rule_, (void *)0 ); - hashdone( m->rules ); - m->rules = 0; - } - - if ( m->variables ) - { - var_hash_swap( &m->variables ); - var_done(); - var_hash_swap( &m->variables ); - m->variables = 0; - } -} - - -module_t * root_module() -{ - static module_t * root = 0; - if ( !root ) - root = bindmodule( 0 ); - return root; -} - -void enter_module( module_t * m ) -{ - var_hash_swap( &m->variables ); -} - - -void exit_module( module_t * m ) -{ - var_hash_swap( &m->variables ); -} - - -void import_module( LIST * module_names, module_t * target_module ) -{ - PROFILE_ENTER( IMPORT_MODULE ); - - struct hash * h; - - if ( !target_module->imported_modules ) - target_module->imported_modules = hashinit( sizeof( char * ), "imported" ); - h = target_module->imported_modules; - - for ( ; module_names; module_names = module_names->next ) - { - char * s = module_names->string; - char * * ss = &s; - hashenter( h, (HASHDATA * *)&ss ); - } - - PROFILE_EXIT( IMPORT_MODULE ); -} - - -static void add_module_name( void * r_, void * result_ ) -{ - char * * r = (char * *)r_; - LIST * * result = (LIST * *)result_; - - *result = list_new( *result, copystr( *r ) ); -} - - -LIST * imported_modules( module_t * module ) -{ - LIST * result = L0; - if ( module->imported_modules ) - hashenumerate( module->imported_modules, add_module_name, &result ); - return result; -} diff --git a/jam-files/engine/modules.h b/jam-files/engine/modules.h deleted file mode 100644 index 60053a23..00000000 --- a/jam-files/engine/modules.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef MODULES_DWA10182001_H -# define MODULES_DWA10182001_H - -#include "lists.h" - -struct module_t -{ - char* name; - struct hash* rules; - struct hash* variables; - struct hash* imported_modules; - struct module_t* class_module; - struct hash* native_rules; - int user_module; -}; - -typedef struct module_t module_t ; /* MSVC debugger gets confused unless this is provided */ - -module_t* bindmodule( char* name ); -module_t* root_module(); -void enter_module( module_t* ); -void exit_module( module_t* ); -void delete_module( module_t* ); - -void import_module(LIST* module_names, module_t* target_module); -LIST* imported_modules(module_t* module); - -struct hash* demand_rules( module_t* ); - - -#endif - diff --git a/jam-files/engine/modules/order.c b/jam-files/engine/modules/order.c deleted file mode 100644 index d77943a7..00000000 --- a/jam-files/engine/modules/order.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright Vladimir Prus 2004. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "../native.h" -#include "../lists.h" -#include "../strings.h" -#include "../newstr.h" -#include "../variable.h" - - -/* Use quite klugy approach: when we add order dependency from 'a' to 'b', - just append 'b' to of value of variable 'a'. -*/ -LIST *add_pair( PARSE *parse, FRAME *frame ) -{ - LIST* arg = lol_get( frame->args, 0 ); - - var_set(arg->string, list_copy(0, arg->next), VAR_APPEND); - - return L0; -} - -/** Given a list and a value, returns position of that value in - the list, or -1 if not found. -*/ -int list_index(LIST* list, const char* value) -{ - int result = 0; - for(; list; list = list->next, ++result) { - if (strcmp(list->string, value) == 0) - return result; - } - return -1; -} - -enum colors { white, gray, black }; - -/* Main routite of topological sort. Calls itself recursively on all - adjacent vertices which were not yet visited. After that, 'current_vertex' - is added to '*result_ptr'. -*/ -void do_ts(int** graph, int current_vertex, int* colors, int** result_ptr) -{ - int i; - - colors[current_vertex] = gray; - for(i = 0; graph[current_vertex][i] != -1; ++i) { - int adjacent_vertex = graph[current_vertex][i]; - - if (colors[adjacent_vertex] == white) - do_ts(graph, adjacent_vertex, colors, result_ptr); - /* The vertex is either black, in which case we don't have to do - anything, a gray, in which case we have a loop. If we have a loop, - it's not clear what useful diagnostic we can emit, so we emit - nothing. */ - } - colors[current_vertex] = black; - **result_ptr = current_vertex; - (*result_ptr)++; -} - -void topological_sort(int** graph, int num_vertices, int* result) -{ - int i; - int* colors = (int*)BJAM_CALLOC(num_vertices, sizeof(int)); - for (i = 0; i < num_vertices; ++i) - colors[i] = white; - - for(i = 0; i < num_vertices; ++i) - if (colors[i] == white) - do_ts(graph, i, colors, &result); - - BJAM_FREE(colors); -} - -LIST *order( PARSE *parse, FRAME *frame ) -{ - LIST* arg = lol_get( frame->args, 0 ); - LIST* tmp; - LIST* result = 0; - int src; - - /* We need to create a graph of order dependencies between - the passed objects. We assume that there are no duplicates - passed to 'add_pair'. - */ - int length = list_length(arg); - int** graph = (int**)BJAM_CALLOC(length, sizeof(int*)); - int* order = (int*)BJAM_MALLOC((length+1)*sizeof(int)); - - for(tmp = arg, src = 0; tmp; tmp = tmp->next, ++src) { - /* For all object this one depend upon, add elements - to 'graph' */ - LIST* dependencies = var_get(tmp->string); - int index = 0; - - graph[src] = (int*)BJAM_CALLOC(list_length(dependencies)+1, sizeof(int)); - for(; dependencies; dependencies = dependencies->next) { - int dst = list_index(arg, dependencies->string); - if (dst != -1) - graph[src][index++] = dst; - } - graph[src][index] = -1; - } - - topological_sort(graph, length, order); - - { - int index = length-1; - for(; index >= 0; --index) { - int i; - tmp = arg; - for (i = 0; i < order[index]; ++i, tmp = tmp->next); - result = list_new(result, tmp->string); - } - } - - /* Clean up */ - { - int i; - for(i = 0; i < length; ++i) - BJAM_FREE(graph[i]); - BJAM_FREE(graph); - BJAM_FREE(order); - } - - return result; -} - -void init_order() -{ - { - char* args[] = { "first", "second", 0 }; - declare_native_rule("class@order", "add-pair", args, add_pair, 1); - } - - { - char* args[] = { "objects", "*", 0 }; - declare_native_rule("class@order", "order", args, order, 1); - } - - -} diff --git a/jam-files/engine/modules/path.c b/jam-files/engine/modules/path.c deleted file mode 100644 index f5d09622..00000000 --- a/jam-files/engine/modules/path.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "../native.h" -#include "../timestamp.h" -#include "../newstr.h" - -LIST *path_exists( PARSE *parse, FRAME *frame ) -{ - LIST* l = lol_get( frame->args, 0 ); - - time_t time; - timestamp(l->string, &time); - if (time != 0) - { - return list_new(0, newstr("true")); - } - else - { - return L0; - } -} - -void init_path() -{ - { - char* args[] = { "location", 0 }; - declare_native_rule("path", "exists", args, path_exists, 1); - } - -} diff --git a/jam-files/engine/modules/property-set.c b/jam-files/engine/modules/property-set.c deleted file mode 100644 index 2b0fb5d9..00000000 --- a/jam-files/engine/modules/property-set.c +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "../native.h" -#include "../timestamp.h" -#include "../newstr.h" -#include "../strings.h" -#include "../lists.h" -#include "../variable.h" -#include "../compile.h" - -LIST* get_grist(char* f) -{ - char* end = strchr(f, '>'); - string s[1]; - LIST* result; - - string_new(s); - - string_append_range(s, f, end+1); - result = list_new(0, newstr(s->value)); - - string_free(s); - return result; -} - -/* -rule create ( raw-properties * ) -{ - raw-properties = [ sequence.unique - [ sequence.insertion-sort $(raw-properties) ] ] ; - - local key = $(raw-properties:J=-:E=) ; - - if ! $(.ps.$(key)) - { - .ps.$(key) = [ new property-set $(raw-properties) ] ; - } - return $(.ps.$(key)) ; -} -*/ - -LIST *property_set_create( PARSE *parse, FRAME *frame ) -{ - LIST* properties = lol_get( frame->args, 0 ); - LIST* sorted = 0; -#if 0 - LIST* order_sensitive = 0; -#endif - LIST* unique; - LIST* tmp; - LIST* val; - string var[1]; - -#if 0 - /* Sort all properties which are not order sensitive */ - for(tmp = properties; tmp; tmp = tmp->next) { - LIST* g = get_grist(tmp->string); - LIST* att = call_rule("feature.attributes", frame, g, 0); - if (list_in(att, "order-sensitive")) { - order_sensitive = list_new( order_sensitive, tmp->string); - } else { - sorted = list_new( sorted, tmp->string); - } - list_free(att); - } - - sorted = list_sort(sorted); - sorted = list_append(sorted, order_sensitive); - unique = list_unique(sorted); -#endif - sorted = list_sort(properties); - unique = list_unique(sorted); - - string_new(var); - string_append(var, ".ps."); - - for(tmp = unique; tmp; tmp = tmp->next) { - string_append(var, tmp->string); - string_push_back(var, '-'); - } - val = var_get(var->value); - if (val == 0) - { - val = call_rule("new", frame, - list_append(list_new(0, "property-set"), unique), 0); - - var_set(newstr(var->value), list_copy(0, val), VAR_SET); - } - else - { - val = list_copy(0, val); - } - - string_free(var); - /* The 'unique' variable is freed in 'call_rule'. */ - list_free(sorted); - - return val; - -} - -void init_property_set() -{ - { - char* args[] = { "raw-properties", "*", 0 }; - declare_native_rule("property-set", "create", args, property_set_create, 1); - } -} diff --git a/jam-files/engine/modules/readme.txt b/jam-files/engine/modules/readme.txt deleted file mode 100644 index 2edf6e17..00000000 --- a/jam-files/engine/modules/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ - -This directory constains sources which declare native -rules for Boost.Build modules.
\ No newline at end of file diff --git a/jam-files/engine/modules/regex.c b/jam-files/engine/modules/regex.c deleted file mode 100644 index d048ba1d..00000000 --- a/jam-files/engine/modules/regex.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "../native.h" -#include "../timestamp.h" -#include "../newstr.h" -#include "../strings.h" -#include "../regexp.h" -#include "../compile.h" - -/* -rule transform ( list * : pattern : indices * ) -{ - indices ?= 1 ; - local result ; - for local e in $(list) - { - local m = [ MATCH $(pattern) : $(e) ] ; - if $(m) - { - result += $(m[$(indices)]) ; - } - } - return $(result) ; -} -*/ -LIST *regex_transform( PARSE *parse, FRAME *frame ) -{ - LIST* l = lol_get( frame->args, 0 ); - LIST* pattern = lol_get( frame->args, 1 ); - LIST* indices_list = lol_get(frame->args, 2); - int* indices = 0; - int size; - int* p; - LIST* result = 0; - - string buf[1]; - string_new(buf); - - if (indices_list) - { - size = list_length(indices_list); - indices = (int*)BJAM_MALLOC(size*sizeof(int)); - for(p = indices; indices_list; indices_list = indices_list->next) - { - *p++ = atoi(indices_list->string); - } - } - else - { - size = 1; - indices = (int*)BJAM_MALLOC(sizeof(int)); - *indices = 1; - } - - { - /* Result is cached and intentionally never freed */ - regexp *re = regex_compile( pattern->string ); - - for(; l; l = l->next) - { - if( regexec( re, l->string ) ) - { - int i = 0; - for(; i < size; ++i) - { - int index = indices[i]; - /* Skip empty submatches. Not sure it's right in all cases, - but surely is right for the case for which this routine - is optimized -- header scanning. - */ - if (re->startp[index] != re->endp[index]) - { - string_append_range( buf, re->startp[index], re->endp[index] ); - result = list_new( result, newstr( buf->value ) ); - string_truncate( buf, 0 ); - } - } - } - } - string_free( buf ); - } - - BJAM_FREE(indices); - - return result; -} - -void init_regex() -{ - { - char* args[] = { "list", "*", ":", "pattern", ":", "indices", "*", 0 }; - declare_native_rule("regex", "transform", args, regex_transform, 2); - } -} diff --git a/jam-files/engine/modules/sequence.c b/jam-files/engine/modules/sequence.c deleted file mode 100644 index bda80d94..00000000 --- a/jam-files/engine/modules/sequence.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "../native.h" - -# ifndef max -# define max( a,b ) ((a)>(b)?(a):(b)) -# endif - - -LIST *sequence_select_highest_ranked( PARSE *parse, FRAME *frame ) -{ - /* Returns all of 'elements' for which corresponding element in parallel */ - /* list 'rank' is equal to the maximum value in 'rank'. */ - - LIST* elements = lol_get( frame->args, 0 ); - LIST* rank = lol_get( frame->args, 1 ); - - LIST* result = 0; - LIST* tmp; - int highest_rank = -1; - - for (tmp = rank; tmp; tmp = tmp->next) - highest_rank = max(highest_rank, atoi(tmp->string)); - - for (; rank; rank = rank->next, elements = elements->next) - if (atoi(rank->string) == highest_rank) - result = list_new(result, elements->string); - - return result; -} - -void init_sequence() -{ - { - char* args[] = { "elements", "*", ":", "rank", "*", 0 }; - declare_native_rule("sequence", "select-highest-ranked", args, - sequence_select_highest_ranked, 1); - } - -} diff --git a/jam-files/engine/modules/set.c b/jam-files/engine/modules/set.c deleted file mode 100644 index f8219403..00000000 --- a/jam-files/engine/modules/set.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "../native.h" - -/* - local result = ; - local element ; - for element in $(B) - { - if ! ( $(element) in $(A) ) - { - result += $(element) ; - } - } - return $(result) ; -*/ -LIST *set_difference( PARSE *parse, FRAME *frame ) -{ - - LIST* b = lol_get( frame->args, 0 ); - LIST* a = lol_get( frame->args, 1 ); - - LIST* result = 0; - for(; b; b = b->next) - { - if (!list_in(a, b->string)) - result = list_new(result, b->string); - } - return result; -} - -void init_set() -{ - { - char* args[] = { "B", "*", ":", "A", "*", 0 }; - declare_native_rule("set", "difference", args, set_difference, 1); - } - -} diff --git a/jam-files/engine/native.c b/jam-files/engine/native.c deleted file mode 100644 index 4c289959..00000000 --- a/jam-files/engine/native.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "native.h" -#include "hash.h" - -# define P0 (PARSE *)0 -# define C0 (char *)0 - - -void declare_native_rule(char* module, char* rule, char** args, - LIST*(*f)(PARSE*, FRAME*), int version) -{ - module_t* m = bindmodule(module); - if (m->native_rules == 0) { - m->native_rules = hashinit( sizeof( native_rule_t ), "native rules"); - } - - { - native_rule_t n, *np = &n; - n.name = rule; - if (args) - { - n.arguments = args_new(); - lol_build( n.arguments->data, args ); - } - else - { - n.arguments = 0; - } - n.procedure = parse_make( f, P0, P0, P0, C0, C0, 0 ); - n.version = version; - hashenter(m->native_rules, (HASHDATA**)&np); - } -} diff --git a/jam-files/engine/native.h b/jam-files/engine/native.h deleted file mode 100644 index 3fc710b9..00000000 --- a/jam-files/engine/native.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright David Abrahams 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#ifndef NATIVE_H_VP_2003_12_09 -#define NATIVE_H_VP_2003_12_09 - -#include "rules.h" - -struct native_rule_t -{ - char* name; - argument_list* arguments; - PARSE* procedure; - /* Version of the interface that the native rule provides. - It's possible that we want to change the set parameter - for existing native rule. In that case, version number - should be incremented so that Boost.Build can check for - version it relies on. - - Versions are numbered from 1. - */ - int version; -}; - -/* MSVC debugger gets confused unless this is provided */ -typedef struct native_rule_t native_rule_t ; - -void declare_native_rule(char* module, char* rule, char** args, - LIST*(*f)(PARSE*, FRAME*), int version); - - - -#endif diff --git a/jam-files/engine/newstr.c b/jam-files/engine/newstr.c deleted file mode 100644 index 6a229eb2..00000000 --- a/jam-files/engine/newstr.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -# include "jam.h" -# include "newstr.h" -# include "hash.h" -# include "compile.h" -# include <stddef.h> -# include <stdlib.h> - -/* - * newstr.c - string manipulation routines - * - * To minimize string copying, string creation, copying, and freeing - * is done through newstr. - * - * External functions: - * - * newstr() - return a dynamically allocated copy of a string - * copystr() - return a copy of a string previously returned by newstr() - * freestr() - free a string returned by newstr() or copystr() - * str_done() - 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. - */ - -typedef char * STRING; - -static struct hash * strhash = 0; -static int strtotal = 0; -static int strcount_in = 0; -static int strcount_out = 0; - - -/* - * Immortal string allocator implementation speeds string allocation and cuts - * down on internal fragmentation. - */ - -# define STRING_BLOCK 4096 -typedef struct strblock -{ - struct strblock * next; - char data[STRING_BLOCK]; -} strblock; - -static strblock * strblock_chain = 0; - -/* Storage remaining in the current strblock */ -static char * storage_start = 0; -static char * storage_finish = 0; - - -/* - * allocate() - Allocate n bytes of immortal string storage. - */ - -static char * allocate( size_t const n ) -{ -#ifdef BJAM_NEWSTR_NO_ALLOCATE - return (char*)BJAM_MALLOC_ATOMIC(n); -#else - /* See if we can grab storage from an existing block. */ - size_t remaining = storage_finish - storage_start; - if ( remaining >= n ) - { - char * result = storage_start; - storage_start += n; - return result; - } - else /* Must allocate a new block. */ - { - strblock * new_block; - size_t nalloc = n; - if ( nalloc < STRING_BLOCK ) - nalloc = STRING_BLOCK; - - /* Allocate a new block and link into the chain. */ - new_block = (strblock *)BJAM_MALLOC( offsetof( strblock, data[0] ) + nalloc * sizeof( new_block->data[0] ) ); - if ( new_block == 0 ) - return 0; - new_block->next = strblock_chain; - strblock_chain = new_block; - - /* Take future allocations out of the larger remaining space. */ - if ( remaining < nalloc - n ) - { - storage_start = new_block->data + n; - storage_finish = new_block->data + nalloc; - } - return new_block->data; - } -#endif -} - - -/* - * newstr() - return a dynamically allocated copy of a string. - */ - -char * newstr( char * string ) -{ - STRING str; - STRING * s = &str; - - if ( !strhash ) - strhash = hashinit( sizeof( STRING ), "strings" ); - - *s = string; - - if ( hashenter( strhash, (HASHDATA **)&s ) ) - { - int l = strlen( string ); - char * m = (char *)allocate( l + 1 ); - - strtotal += l + 1; - memcpy( m, string, l + 1 ); - *s = m; - } - - strcount_in += 1; - return *s; -} - - -/* - * copystr() - return a copy of a string previously returned by newstr() - */ - -char * copystr( char * s ) -{ - strcount_in += 1; - return s; -} - - -/* - * freestr() - free a string returned by newstr() or copystr() - */ - -void freestr( char * s ) -{ - strcount_out += 1; -} - - -/* - * str_done() - free string tables. - */ - -void str_done() -{ - /* Reclaim string blocks. */ - while ( strblock_chain != 0 ) - { - strblock * n = strblock_chain->next; - BJAM_FREE(strblock_chain); - strblock_chain = n; - } - - hashdone( strhash ); - - if ( DEBUG_MEM ) - printf( "%dK in strings\n", strtotal / 1024 ); - - /* printf( "--- %d strings of %d dangling\n", strcount_in-strcount_out, strcount_in ); */ -} diff --git a/jam-files/engine/newstr.h b/jam-files/engine/newstr.h deleted file mode 100644 index 84a4d7b6..00000000 --- a/jam-files/engine/newstr.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * newstr.h - string manipulation routines - */ - -char * copystr ( char * ); -void freestr ( char * ); -char * newstr ( char * ); -void str_done(); diff --git a/jam-files/engine/option.c b/jam-files/engine/option.c deleted file mode 100644 index d25e5e8a..00000000 --- a/jam-files/engine/option.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -# include "jam.h" -# include "option.h" - -/* - * option.c - command line option processing - * - * {o >o - * \<>) "Process command line options as defined in <option.h>. - * 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." - */ - -int getoptions( int argc, char * * argv, char * opts, bjam_option * optv ) -{ - int i; - int optc = N_OPTS; - - memset( (char *)optv, '\0', sizeof( *optv ) * N_OPTS ); - - for ( i = 0; i < argc; ++i ) - { - char *arg; - - if ( ( argv[ i ][ 0 ] != '-' ) || - ( ( argv[ i ][ 1 ] != '-' ) && !isalpha( argv[ i ][ 1 ] ) ) ) - continue; - - if ( !optc-- ) - { - printf( "too many options (%d max)\n", N_OPTS ); - return -1; - } - - for ( arg = &argv[ i ][ 1 ]; *arg; ++arg ) - { - 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; - } - } - } - - return i; -} - - -/* - * Name: getoptval() - find an option given its character. - */ - -char * getoptval( bjam_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; -} diff --git a/jam-files/engine/option.h b/jam-files/engine/option.h deleted file mode 100644 index 99ef620d..00000000 --- a/jam-files/engine/option.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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." - */ - -typedef struct bjam_option -{ - char flag; /* filled in by getoption() */ - char *val; /* set to random address if true */ -} bjam_option; - -# define N_OPTS 256 - -int getoptions( int argc, char **argv, char *opts, bjam_option *optv ); -char * getoptval( bjam_option *optv, char opt, int subopt ); diff --git a/jam-files/engine/output.c b/jam-files/engine/output.c deleted file mode 100644 index 483c6ca9..00000000 --- a/jam-files/engine/output.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright 2007 Rene Rivera - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -*/ - -#include "jam.h" -#include "output.h" -#include "newstr.h" -#include <stdio.h> - -#define bjam_out (stdout) -#define bjam_err (stderr) - -static void out_ -( - char const * data, - FILE * io -) -{ - while ( *data ) - { - size_t len = strcspn(data,"\r"); - data += fwrite(data,1,len,io); - if ( *data == '\r' ) ++data; - } -} - - -void out_action -( - char const * action, - char const * target, - char const * command, - char const * out_data, - char const * err_data, - int exit_reason -) -{ - /* Print out the action+target line, if the action is quite the action - * should be null. - */ - if ( action ) - { - fprintf( bjam_out, "%s %s\n", action, target ); - } - - /* Print out the command executed if given -d+2. */ - if ( DEBUG_EXEC ) - { - fputs( command, bjam_out ); - fputc( '\n', bjam_out ); - } - - /* Print out the command executed to the command stream. */ - if ( globs.cmdout ) - { - fputs( command, globs.cmdout ); - } - - switch ( exit_reason ) - { - case EXIT_OK: - break; - case EXIT_FAIL: - break; - case EXIT_TIMEOUT: - { - /* Process expired, make user aware with explicit message. */ - if ( action ) - { - /* But only output for non-quietly actions. */ - fprintf( bjam_out, "%ld second time limit exceeded\n", globs.timeout ); - } - break; - } - default: - break; - } - - /* Print out the command output, if requested, or if the program failed. */ - if ( action || exit_reason != EXIT_OK) - { - /* But only output for non-quietly actions. */ - if ( ( 0 != out_data ) && - ( ( globs.pipe_action & 1 /* STDOUT_FILENO */ ) || - ( globs.pipe_action == 0 ) ) ) - { - out_( out_data, bjam_out ); - } - if ( ( 0 != err_data ) && - ( globs.pipe_action & 2 /* STDERR_FILENO */ ) ) - { - out_( err_data, bjam_err ); - } - } - - fflush( bjam_out ); - fflush( bjam_err ); - fflush( globs.cmdout ); -} - - -char * outf_int( int value ) -{ - char buffer[50]; - sprintf( buffer, "%i", value ); - return newstr( buffer ); -} - - -char * outf_double( double value ) -{ - char buffer[50]; - sprintf( buffer, "%f", value ); - return newstr( buffer ); -} - - -char * outf_time( time_t value ) -{ - char buffer[50]; - strftime( buffer, 49, "%Y-%m-%d %H:%M:%SZ", gmtime( &value ) ); - return newstr( buffer ); -} diff --git a/jam-files/engine/output.h b/jam-files/engine/output.h deleted file mode 100644 index 9e9876cf..00000000 --- a/jam-files/engine/output.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright 2007 Rene Rivera - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -*/ - -#ifndef BJAM_OUTPUT_H -#define BJAM_OUTPUT_H - -#include <time.h> - -#define EXIT_OK 0 -#define EXIT_FAIL 1 -#define EXIT_TIMEOUT 2 - -void out_action( - const char * action, - const char * target, - const char * command, - const char * out_data, - const char * err_data, - int exit_reason - ); - -char * outf_int( int value ); -char * outf_double( double value ); -char * outf_time( time_t value ); - -#endif diff --git a/jam-files/engine/parse.c b/jam-files/engine/parse.c deleted file mode 100644 index 9114fa05..00000000 --- a/jam-files/engine/parse.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -#include "jam.h" -#include "lists.h" -#include "parse.h" -#include "scan.h" -#include "newstr.h" -#include "modules.h" -#include "frames.h" - -/* - * 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 *. - */ - -static PARSE * yypsave; - -void parse_file( char * f, FRAME * frame ) -{ - /* 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 ( ; ; ) - { - PARSE * p; - - /* 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. */ - parse_evaluate( p, frame ); - parse_free( p ); - } -} - - -void parse_save( PARSE * p ) -{ - yypsave = p; -} - - -PARSE * parse_make( - LIST * (* func)( PARSE *, FRAME * ), - PARSE * left, - PARSE * right, - PARSE * third, - char * string, - char * string1, - int num ) -{ - PARSE * p = (PARSE *)BJAM_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; - p->rulename = 0; - - if ( left ) - { - p->file = left->file; - p->line = left->line; - } - else - { - yyinput_stream( &p->file, &p->line ); - } - - 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 ); - if ( p->rulename ) - freestr( p->rulename ); - - BJAM_FREE( (char *)p ); -} - - -LIST * parse_evaluate( PARSE * p, FRAME * frame ) -{ - frame->procedure = p; - return (*p->func)( p, frame ); -} diff --git a/jam-files/engine/parse.h b/jam-files/engine/parse.h deleted file mode 100644 index e324972f..00000000 --- a/jam-files/engine/parse.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -#ifndef PARSE_DWA20011020_H -#define PARSE_DWA20011020_H - -#include "frames.h" -#include "modules.h" -#include "lists.h" - -/* - * parse.h - make and destroy parse trees as driven by the parser. - */ - -/* - * Parse tree node. - */ - -struct _PARSE { - LIST * (* func)( PARSE *, FRAME * ); - PARSE * left; - PARSE * right; - PARSE * third; - char * string; - char * string1; - int num; - int refs; -/* module * module; */ - char * rulename; - char * file; - int line; -}; - -void parse_file( char *, FRAME * ); -void parse_save( PARSE * ); - -PARSE * parse_make( - LIST * (* func)( PARSE *, FRAME * ), - PARSE * left, - PARSE * right, - PARSE * third, - char * string, - char * string1, - int num ); - -void parse_refer ( PARSE * ); -void parse_free ( PARSE * ); -LIST * parse_evaluate( PARSE *, FRAME * ); - -#endif diff --git a/jam-files/engine/patchlevel.h b/jam-files/engine/patchlevel.h deleted file mode 100644 index 699efd84..00000000 --- a/jam-files/engine/patchlevel.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* Keep JAMVERSYM in sync with VERSION. */ -/* It can be accessed as $(JAMVERSION) in the Jamfile. */ - -#define VERSION_MAJOR 2011 -#define VERSION_MINOR 04 -#define VERSION_PATCH 0 -#define VERSION_MAJOR_SYM "2011" -#define VERSION_MINOR_SYM "04" -#define VERSION_PATCH_SYM "00" -#define VERSION "2011.4" -#define JAMVERSYM "JAMVERSION=2011.4" diff --git a/jam-files/engine/pathmac.c b/jam-files/engine/pathmac.c deleted file mode 100644 index e2c250e3..00000000 --- a/jam-files/engine/pathmac.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" -# include "pathsys.h" - -# ifdef OS_MAC - -# define DELIM ':' - -/* - * 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. - */ - -/* - * path_parse() - split a file name into dir/base/suffix/member - */ - -void -path_parse( - char *file, - PATHNAME *f ) -{ - char *p, *q; - char *end; - - memset( (char *)f, 0, sizeof( *f ) ); - - /* Look for <grist> */ - - 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( 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, string * file, int binding ) -{ - int dflag; - int rflag; - int act; - - file_build1( f, 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 */ - string_push_back( file, DELIM ); - } - /* fall through */ - - case G_DIR: - /* take dir */ - string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len ); - break; - - case G_ROOT: - /* take root */ - string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len ); - break; - - case G_CAT: - /* prepend root to dir */ - string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len ); - if ( file->value[ file->size - 1 ] == DELIM ) - string_pop_back( file ); - string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len ); - break; - - case G_DDDD: - /* make it ::: (../..) */ - string_append( file, ":::" ); - break; - } - - /* Put : between dir and file (if none already). */ - - if ( ( act != G_MT ) && - ( file->value[ file->size - 1 ] != DELIM ) && - ( f->f_base.len || f->f_suffix.len ) ) - { - string_push_back( file, DELIM ); - } - - if ( f->f_base.len ) - string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len ); - - if ( f->f_suffix.len ) - string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len ); - - if ( f->f_member.len ) - { - string_push_back( file, '(' ); - string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len ); - string_push_back( file, ')' ); - } - - if ( DEBUG_SEARCH ) - printf( " -> '%s'\n", file->value ); -} - - -/* - * 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 */ diff --git a/jam-files/engine/pathsys.h b/jam-files/engine/pathsys.h deleted file mode 100644 index 73775810..00000000 --- a/jam-files/engine/pathsys.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 - */ - -/* - * PATHNAME - a name of a file, broken into <grist>dir/base/suffix(member) - * - * <grist> 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. - */ - -#ifndef PATHSYS_VP_20020211_H -# define PATHSYS_VP_20020211_H - -#include "strings.h" - -typedef struct _pathname PATHNAME; -typedef struct _pathpart PATHPART; - -struct _pathpart -{ - 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, string * file, int binding ); -void path_build1( PATHNAME * f, string * file ); - -void path_parse( char * file, PATHNAME * f ); -void path_parent( PATHNAME * f ); - -#ifdef NT - -/** Returns newstr-allocated string with long equivivalent of 'short_name'. - If none exists -- i.e. 'short_path' is already long path, it's returned - unaltered. */ -char * short_path_to_long_path( char * short_path ); - -#endif - -#ifdef USE_PATHUNIX -/** Returns a static pointer to the system dependent path to the temporary - directory. NOTE: *without* a trailing path separator. -*/ -const char * path_tmpdir( void ); - -/** Returns a new temporary name. -*/ -const char * path_tmpnam( void ); - -/** Returns a new temporary path. -*/ -const char * path_tmpfile( void ); -#endif - -/** Give the first argument to 'main', return a full path to - our executable. Returns null in the unlikely case it - cannot be determined. Caller is responsible for freeing - the string. - - Implemented in jam.c -*/ -char * executable_path (char *argv0); - -#endif diff --git a/jam-files/engine/pathunix.c b/jam-files/engine/pathunix.c deleted file mode 100644 index 2daad14b..00000000 --- a/jam-files/engine/pathunix.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Copyright 2005 Rene Rivera. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" -# include "pathsys.h" -# include "strings.h" -# include "newstr.h" -# include "filesys.h" -# include <time.h> -# include <stdlib.h> -# ifndef OS_NT -# include <unistd.h> -# endif - -# ifdef USE_PATHUNIX - -/* - * 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 on \ handling on UNIX, on by accident - */ - -/* - * path_parse() - split a file name into dir/base/suffix/member - */ - -void path_parse( char * file, PATHNAME * f ) -{ - char * p; - char * q; - char * end; - - memset( (char *)f, 0, sizeof( *f ) ); - - /* Look for <grist> */ - - 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_delims - the string of legal path delimiters - */ -static char path_delims[] = { - PATH_DELIM, -# if PATH_DELIM == '\\' - '/', -# endif - 0 -}; - -/* - * is_path_delim() - true iff c is a path delimiter - */ -static int is_path_delim( char c ) -{ - char* p = strchr( path_delims, c ); - return p && *p; -} - -/* - * as_path_delim() - convert c to a path delimiter if it isn't one - * already - */ -static char as_path_delim( char c ) -{ - return is_path_delim( c ) ? c : PATH_DELIM; -} - -/* - * path_build() - build a filename given dir/base/suffix/member - * - * To avoid changing slash direction on NT when reconstituting paths, - * instead of unconditionally appending PATH_DELIM we check the - * past-the-end character of the previous path element. If it is in - * path_delims, we append that, and only append PATH_DELIM as a last - * resort. This heuristic is based on the fact that PATHNAME objects - * are usually the result of calling path_parse, which leaves the - * original slashes in the past-the-end position. Correctness depends - * on the assumption that all strings are zero terminated, so a - * past-the-end character will always be available. - * - * As an attendant patch, we had to ensure that backslashes are used - * explicitly in timestamp.c - */ - -void -path_build( - PATHNAME *f, - string *file, - int binding ) -{ - file_build1( f, 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 */ - - { - string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len ); - /* If 'root' already ends with path delimeter, - don't add yet another one. */ - if ( ! is_path_delim( f->f_root.ptr[f->f_root.len-1] ) ) - string_push_back( file, as_path_delim( f->f_root.ptr[f->f_root.len] ) ); - } - - if ( f->f_dir.len ) - string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + 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 && is_path_delim( f->f_dir.ptr[0] ) ) ) - string_push_back( file, as_path_delim( f->f_dir.ptr[f->f_dir.len] ) ); - } - - if ( f->f_base.len ) - { - string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len ); - } - - if ( f->f_suffix.len ) - { - string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len ); - } - - if ( f->f_member.len ) - { - string_push_back( file, '(' ); - string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len ); - string_push_back( file, ')' ); - } -} - -/* - * 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; -} - -#ifdef NT -#include <windows.h> -#include <tchar.h> - -/* The definition of this in winnt.h is not ANSI-C compatible. */ -#undef INVALID_FILE_ATTRIBUTES -#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) - - -DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD - cchBuffer) -{ - LONG i=0; - TCHAR path[_MAX_PATH]={0}; - TCHAR ret[_MAX_PATH]={0}; - LONG pos=0, prev_pos=0; - LONG len=_tcslen(lpszShortPath); - - /* Is the string valid? */ - if (!lpszShortPath) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - /* Is the path valid? */ - if (GetFileAttributes(lpszShortPath)==INVALID_FILE_ATTRIBUTES) - return 0; - - /* Convert "/" to "\" */ - for (i=0;i<len;++i) { - if (lpszShortPath[i]==_T('/')) - path[i]=_T('\\'); - else - path[i]=lpszShortPath[i]; - } - - /* UNC path? */ - if (path[0]==_T('\\') && path[1]==_T('\\')) { - pos=2; - for (i=0;i<2;++i) { - while (path[pos]!=_T('\\') && path[pos]!=_T('\0')) - ++pos; - ++pos; - } - _tcsncpy(ret,path,pos-1); - } /* Drive letter? */ - else if (path[1]==_T(':')) { - if (path[2]==_T('\\')) - pos=3; - if (len==3) { - if (cchBuffer>3) - _tcscpy(lpszLongPath,lpszShortPath); - return len; - } - _tcsncpy(ret,path,2); - } - - /* Expand the path for each subpath, and strip trailing backslashes */ - for (prev_pos = pos-1;pos<=len;++pos) { - if (path[pos]==_T('\\') || (path[pos]==_T('\0') && - path[pos-1]!=_T('\\'))) { - WIN32_FIND_DATA fd; - HANDLE hf=0; - TCHAR c=path[pos]; - char* new_element; - path[pos]=_T('\0'); - - /* the path[prev_pos+1]... path[pos] range is the part of - path we're handling right now. We need to find long - name for that element and add it. */ - new_element = path + prev_pos + 1; - - /* First add separator, but only if there's something in result already. */ - if (ret[0] != _T('\0')) - { - _tcscat(ret,_T("\\")); - } - - /* If it's ".." element, we need to append it, not - the name in parent that FindFirstFile will return. - Same goes for "." */ - - if (new_element[0] == _T('.') && new_element[1] == _T('\0') || - new_element[0] == _T('.') && new_element[1] == _T('.') - && new_element[2] == _T('\0')) - { - _tcscat(ret, new_element); - } - else - { - hf=FindFirstFile(path, &fd); - if (hf==INVALID_HANDLE_VALUE) - return 0; - - _tcscat(ret,fd.cFileName); - FindClose(hf); - } - - path[pos]=c; - - prev_pos = pos; - } - } - - len=_tcslen(ret)+1; - if (cchBuffer>=len) - _tcscpy(lpszLongPath,ret); - - return len; -} - -char* short_path_to_long_path(char* short_path) -{ - char buffer2[_MAX_PATH]; - int ret = ShortPathToLongPath(short_path, buffer2, _MAX_PATH); - - if (ret) - return newstr(buffer2); - else - return newstr(short_path); -} - -#endif - -static string path_tmpdir_buffer[1]; -static const char * path_tmpdir_result = 0; - -const char * path_tmpdir() -{ - if (!path_tmpdir_result) - { - # ifdef OS_NT - DWORD pathLength = 0; - pathLength = GetTempPath(pathLength,NULL); - string_new(path_tmpdir_buffer); - string_reserve(path_tmpdir_buffer,pathLength); - pathLength = GetTempPathA(pathLength,path_tmpdir_buffer[0].value); - path_tmpdir_buffer[0].value[pathLength-1] = '\0'; - path_tmpdir_buffer[0].size = pathLength-1; - # else - const char * t = getenv("TMPDIR"); - if (!t) - { - t = "/tmp"; - } - string_new(path_tmpdir_buffer); - string_append(path_tmpdir_buffer,t); - # endif - path_tmpdir_result = path_tmpdir_buffer[0].value; - } - return path_tmpdir_result; -} - -const char * path_tmpnam(void) -{ - char name_buffer[64]; - # ifdef OS_NT - unsigned long c0 = GetCurrentProcessId(); - # else - unsigned long c0 = getpid(); - # endif - static unsigned long c1 = 0; - if (0 == c1) c1 = time(0)&0xffff; - c1 += 1; - sprintf(name_buffer,"jam%lx%lx.000",c0,c1); - return newstr(name_buffer); -} - -const char * path_tmpfile(void) -{ - const char * result = 0; - - string file_path; - string_copy(&file_path,path_tmpdir()); - string_push_back(&file_path,PATH_DELIM); - string_append(&file_path,path_tmpnam()); - result = newstr(file_path.value); - string_free(&file_path); - - return result; -} - - -# endif /* unix, NT, OS/2, AmigaOS */ diff --git a/jam-files/engine/pathvms.c b/jam-files/engine/pathvms.c deleted file mode 100644 index 975fe5a5..00000000 --- a/jam-files/engine/pathvms.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" -# include "pathsys.h" - -# ifdef OS_VMS - -# define DEBUG - -/* - * 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 - */ - -/* - * path_parse() - split a file name into dir/base/suffix/member. - */ - -void path_parse( char * file, PATHNAME * f ) -{ - char * p; - char * q; - char * end; - - memset( (char *)f, 0, sizeof( *f ) ); - - /* Look for <grist> */ - - 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( char * buf, int len, struct dirinf * i ) -{ - 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( buf, ':', len ) ) - { - i->dev.ptr = buf; - i->dev.len = p + 1 - buf; - i->dir.ptr = 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 = buf; - i->dev.len = 0; - i->dir.ptr = 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, string * file, int binding ) -{ - struct dirinf root; - struct dirinf dir; - int g; - - file_build1( f, 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 */ - string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len ); - break; - - case G_ROOT: - /* take root */ - string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len ); - break; - - case G_VAD: - /* root's dev + abs directory */ - string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len ); - string_append_range( file, dir.dir.ptr, dir.dir.ptr + dir.dir.len ); - break; - - case G_DRD: - case G_DDD: - /* root's dev:[dir] + rel directory */ - string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len ); - - /* sanity checks: root ends with ] */ - - if ( file->value[file->size - 1] == ']' ) - string_pop_back( file ); - - /* Add . if separating two -'s */ - - if ( g == G_DDD ) - string_push_back( file, '.' ); - - /* skip [ of dir */ - string_append_range( file, dir.dir.ptr + 1, dir.dir.ptr + 1 + dir.dir.len - 1 ); - break; - - case G_VRD: - /* root's dev + rel directory made abs */ - string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len ); - string_push_back( file, '[' ); - /* skip [. of rel dir */ - string_append_range( file, dir.dir.ptr + 2, dir.dir.ptr + 2 + dir.dir.len - 2 ); - break; - } - -# ifdef DEBUG - if ( DEBUG_SEARCH && ( root.flags || dir.flags ) ) - printf( "%d x %d = %d (%s)\n", root.flags, dir.flags, - grid[ root.flags ][ dir.flags ], file->value ); -# endif - - /* - * Now do the special :P modifier when no file was present. - * (none) (none) - * [dir1.dir2] [dir1] - * [dir] [000000] - * [.dir] (none) - * [] [] - */ - - if ( ( file->value[ file->size - 1 ] == ']' ) && f->parent ) - { - char * p = file->value + file->size; - while ( p-- > file->value ) - { - if ( *p == '.' ) - { - /* If we've truncated everything and left with '[', - return empty string. */ - if ( p == file->value + 1 ) - string_truncate( file, 0 ); - else - { - string_truncate( file, p - file->value ); - string_push_back( file, ']' ); - } - break; - } - - if ( *p == '-' ) - { - /* handle .- or - */ - if ( ( p > file->value ) && ( p[ -1 ] == '.' ) ) - --p; - - *p++ = ']'; - break; - } - - if ( *p == '[' ) - { - if ( p[ 1 ] == ']' ) - { - /* CONSIDER: I don't see any use of this code. We immediately - break, and 'p' is a local variable. */ - p += 2; - } - else - { - string_truncate( file, p - file->value ); - string_append( file, "[000000]" ); - } - break; - } - } - } - - /* Now copy the file pieces. */ - if ( f->f_base.len ) - { - string_append_range( file, f->f_base.ptr, f->f_base.ptr + 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 ) - string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len ); - else if ( binding && f->f_base.len ) - string_push_back( file, '.' ); - - if ( f->f_member.len ) - { - string_push_back( file, '(' ); - string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len ); - string_push_back( file, ')' ); - } - -# 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, - file->value ); -# 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 */ diff --git a/jam-files/engine/pwd.c b/jam-files/engine/pwd.c deleted file mode 100644 index 90c8eb17..00000000 --- a/jam-files/engine/pwd.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright Vladimir Prus 2002, Rene Rivera 2005. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "jam.h" -#include "lists.h" -#include "newstr.h" -#include "pathsys.h" -#include "mem.h" - -#include <limits.h> -#include <errno.h> - -/* MinGW on windows declares PATH_MAX in limits.h */ -#if defined(NT) && ! defined(__GNUC__) -#include <direct.h> -#define PATH_MAX _MAX_PATH -#else -#include <unistd.h> -#if defined(__COMO__) - #include <linux/limits.h> -#endif -#endif - -#ifndef PATH_MAX - #define PATH_MAX 1024 -#endif - -/* The current directory can't change in bjam, so optimize this to cache -** the result. -*/ -static char * pwd_result = NULL; - - -LIST* -pwd(void) -{ - if (!pwd_result) - { - int buffer_size = PATH_MAX; - char * result_buffer = 0; - do - { - char * buffer = BJAM_MALLOC_RAW(buffer_size); - result_buffer = getcwd(buffer,buffer_size); - if (result_buffer) - { - #ifdef NT - pwd_result = short_path_to_long_path(result_buffer); - #else - pwd_result = newstr(result_buffer); - #endif - } - buffer_size *= 2; - BJAM_FREE_RAW(buffer); - } - while (!pwd_result && errno == ERANGE); - - if (!pwd_result) - { - perror("can not get current directory"); - return L0; - } - } - return list_new(L0, pwd_result); -} diff --git a/jam-files/engine/pwd.h b/jam-files/engine/pwd.h deleted file mode 100644 index 37cb531e..00000000 --- a/jam-files/engine/pwd.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright Vladimir Prus 2002. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#ifndef PWD_H -#define PWD_H - -LIST* pwd(void); - -#endif diff --git a/jam-files/engine/regexp.c b/jam-files/engine/regexp.c deleted file mode 100644 index 30197a2f..00000000 --- a/jam-files/engine/regexp.c +++ /dev/null @@ -1,1328 +0,0 @@ -/* - * 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. - * - * 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 "jam.h" -#include "regexp.h" -#include <stdio.h> -#include <ctype.h> -#ifndef ultrix - #include <stdlib.h> -#endif -#include <string.h> - - -/* - * 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( 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 *)BJAM_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 = 0; - 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 char *reginput; /* String-input pointer. */ -static char *regbol; /* Beginning of input, for ^ check. */ -static char **regstartp; /* Pointer to startp array. */ -static char **regendp; /* Ditto for endp. */ - -/* - * Forwards. - */ -STATIC int regtry( regexp *prog, 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 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 ) ) - 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 do not -- 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, - char *string ) -{ - register int i; - register char * * sp; - register 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 do not 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 ) -{ - 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 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 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 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 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 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 diff --git a/jam-files/engine/regexp.h b/jam-files/engine/regexp.h deleted file mode 100644 index 9d4604f6..00000000 --- a/jam-files/engine/regexp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Definitions etc. for regexp(3) routines. - * - * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], - * not the System V one. - */ -#ifndef REGEXP_DWA20011023_H -# define REGEXP_DWA20011023_H - -#define NSUBEXP 10 -typedef struct regexp { - char *startp[NSUBEXP]; - 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( char *exp ); -int regexec( regexp *prog, char *string ); -void regerror( 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 - -#endif - diff --git a/jam-files/engine/rules.c b/jam-files/engine/rules.c deleted file mode 100644 index a0be1d34..00000000 --- a/jam-files/engine/rules.c +++ /dev/null @@ -1,810 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "variable.h" -# include "rules.h" -# include "newstr.h" -# include "hash.h" -# include "modules.h" -# include "search.h" -# include "lists.h" -# include "pathsys.h" -# include "timestamp.h" - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * 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. - * touch_target() - 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. - * actionlist() - append to an ACTION chain. - * addsettings() - add a deferred "set" command to a target. - * pushsettings() - set all target specific variables. - * popsettings() - reset target specific variables to their pre-push values. - * freesettings() - delete a settings list. - * rules_done() - 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) - */ - -static void set_rule_actions( RULE *, rule_actions * ); -static void set_rule_body ( RULE *, argument_list *, PARSE * procedure ); - -static struct hash * targethash = 0; - -struct _located_target -{ - char * file_name; - TARGET * target; -}; -typedef struct _located_target LOCATED_TARGET ; - -static struct hash * located_targets = 0; - - -/* - * target_include() - adds the 'included' TARGET to the list of targets included - * by the 'including' TARGET. Such targets are modeled as dependencies of the - * internal include node belonging to the 'including' TARGET. - */ - -void target_include( TARGET * including, TARGET * included ) -{ - TARGET * internal; - if ( !including->includes ) - { - including->includes = copytarget( including ); - including->includes->original_target = including; - } - internal = including->includes; - internal->depends = targetentry( internal->depends, included ); -} - - -/* - * enter_rule() - return pointer to RULE, creating it if necessary in - * target_module. - */ - -static RULE * enter_rule( char * rulename, module_t * target_module ) -{ - RULE rule; - RULE * r = &rule; - - r->name = rulename; - - if ( hashenter( demand_rules( target_module ), (HASHDATA * *)&r ) ) - { - r->name = newstr( rulename ); /* never freed */ - r->procedure = (PARSE *)0; - r->module = 0; - r->actions = 0; - r->arguments = 0; - r->exported = 0; - r->module = target_module; -#ifdef HAVE_PYTHON - r->python_function = 0; -#endif - } - return r; -} - - -/* - * define_rule() - return pointer to RULE, creating it if necessary in - * target_module. Prepare it to accept a body or action originating in - * src_module. - */ - -static RULE * define_rule -( - module_t * src_module, - char * rulename, - module_t * target_module -) -{ - RULE * r = enter_rule( rulename, target_module ); - if ( r->module != src_module ) /* if the rule was imported from elsewhere, clear it now */ - { - set_rule_body( r, 0, 0 ); - set_rule_actions( r, 0 ); - r->module = src_module; /* r will be executed in the source module */ - } - return r; -} - - -void rule_free( RULE * r ) -{ - freestr( r->name ); - r->name = ""; - parse_free( r->procedure ); - r->procedure = 0; - if ( r->arguments ) - args_free( r->arguments ); - r->arguments = 0; - if ( r->actions ) - actions_free( r->actions ); - r->actions = 0; -} - - -/* - * bindtarget() - return pointer to TARGET, creating it if necessary. - */ - -TARGET * bindtarget( char const * target_name ) -{ - TARGET target; - TARGET * t = ⌖ - - if ( !targethash ) - targethash = hashinit( sizeof( TARGET ), "targets" ); - - /* Perforce added const everywhere. No time to merge that change. */ -#ifdef NT - target_name = short_path_to_long_path( (char *)target_name ); -#endif - t->name = (char *)target_name; - - if ( hashenter( targethash, (HASHDATA * *)&t ) ) - { - memset( (char *)t, '\0', sizeof( *t ) ); - t->name = newstr( (char *)target_name ); /* never freed */ - t->boundname = t->name; /* default for T_FLAG_NOTFILE */ - } - - return t; -} - - -static void bind_explicitly_located_target( void * xtarget, void * data ) -{ - TARGET * t = (TARGET *)xtarget; - if ( !( t->flags & T_FLAG_NOTFILE ) ) - { - /* Check if there's a setting for LOCATE */ - SETTINGS * s = t->settings; - for ( ; s ; s = s->next ) - { - if ( strcmp( s->symbol, "LOCATE" ) == 0 ) - { - pushsettings( t->settings ); - /* We are binding a target with explicit LOCATE. So third - * argument is of no use: nothing will be returned through it. - */ - t->boundname = search( t->name, &t->time, 0, 0 ); - popsettings( t->settings ); - break; - } - } - } -} - - -void bind_explicitly_located_targets() -{ - if ( targethash ) - hashenumerate( targethash, bind_explicitly_located_target, (void *)0 ); -} - - -/* TODO: It is probably not a good idea to use functions in other modules like - this. */ -void call_bind_rule( char * target, char * boundname ); - - -TARGET * search_for_target ( char * name, LIST * search_path ) -{ - PATHNAME f[1]; - string buf[1]; - LOCATED_TARGET lt; - LOCATED_TARGET * lta = < - time_t time; - int found = 0; - TARGET * result; - - string_new( buf ); - - path_parse( name, f ); - - f->f_grist.ptr = 0; - f->f_grist.len = 0; - - while ( search_path ) - { - f->f_root.ptr = search_path->string; - f->f_root.len = strlen( search_path->string ); - - string_truncate( buf, 0 ); - path_build( f, buf, 1 ); - - lt.file_name = buf->value ; - - if ( !located_targets ) - located_targets = hashinit( sizeof(LOCATED_TARGET), - "located targets" ); - - if ( hashcheck( located_targets, (HASHDATA * *)<a ) ) - { - return lta->target; - } - - timestamp( buf->value, &time ); - if ( time ) - { - found = 1; - break; - } - - search_path = list_next( search_path ); - } - - if ( !found ) - { - f->f_root.ptr = 0; - f->f_root.len = 0; - - string_truncate( buf, 0 ); - path_build( f, buf, 1 ); - - timestamp( buf->value, &time ); - } - - result = bindtarget( name ); - result->boundname = newstr( buf->value ); - result->time = time; - result->binding = time ? T_BIND_EXISTS : T_BIND_MISSING; - - call_bind_rule( result->name, result->boundname ); - - string_free( buf ); - - return result; -} - - -/* - * 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 = (TARGET *)BJAM_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; -} - - -/* - * touch_target() - mark a target to simulate being new. - */ - -void touch_target( 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 * target_names ) -{ - for ( ; target_names; target_names = list_next( target_names ) ) - chain = targetentry( chain, bindtarget( target_names->string ) ); - return chain; -} - - -/* - * targetentry() - add a TARGET to a chain of TARGETS. - * - * Inputs: - * chain existing TARGETS to append to - * target new target to append - */ - -TARGETS * targetentry( TARGETS * chain, TARGET * target ) -{ - TARGETS * c = (TARGETS *)BJAM_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 ) -{ - if ( !targets ) return chain; - 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 *)BJAM_MALLOC( sizeof( ACTIONS ) ); - - actions->action = action; - - if ( !chain ) chain = actions; - else chain->tail->next = actions; - chain->tail = actions; - actions->next = 0; - - return chain; -} - -static SETTINGS * settings_freelist; - - -/* - * addsettings() - add a deferred "set" command to a target. - * - * Adds a variable setting (varname=list) onto a chain of settings for a - * particular target. 'flag' controls the relationship between new and old - * values in the same way as in var_set() function (see variable.c). Returns - * the head of the settings chain. - */ - -SETTINGS * addsettings( SETTINGS * head, int flag, char * symbol, LIST * value ) -{ - SETTINGS * v; - - /* Look for previous settings. */ - 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_freelist; - - if ( v ) - settings_freelist = v->next; - else - v = (SETTINGS *)BJAM_MALLOC( sizeof( *v ) ); - - v->symbol = newstr( symbol ); - v->value = value; - v->next = head; - v->multiple = 0; - head = v; - } - else if ( flag == VAR_APPEND ) - { - v->value = list_append( v->value, value ); - } - else if ( flag != VAR_DEFAULT ) - { - list_free( v->value ); - v->value = value; - } - else - list_free( value ); - - /* Return (new) head of list. */ - 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 */ -} - - -/* - * copysettings() - duplicate a settings list, returning the new copy. - */ - -SETTINGS * copysettings( SETTINGS * head ) -{ - SETTINGS * copy = 0; - SETTINGS * v; - for ( v = head; v; v = v->next ) - copy = addsettings( copy, VAR_SET, v->symbol, list_copy( 0, v->value ) ); - return copy; -} - - -/* - * freetargets() - delete a targets list. - */ - -void freetargets( TARGETS * chain ) -{ - while ( chain ) - { - TARGETS * n = chain->next; - BJAM_FREE( chain ); - chain = n; - } -} - - -/* - * freeactions() - delete an action list. - */ - -void freeactions( ACTIONS * chain ) -{ - while ( chain ) - { - ACTIONS * n = chain->next; - BJAM_FREE( chain ); - chain = n; - } -} - - -/* - * freesettings() - delete a settings list. - */ - -void freesettings( SETTINGS * v ) -{ - while ( v ) - { - SETTINGS * n = v->next; - freestr( v->symbol ); - list_free( v->value ); - v->next = settings_freelist; - settings_freelist = v; - v = n; - } -} - - -static void freetarget( void * xt, void * data ) -{ - TARGET * t = (TARGET *)xt; - if ( t->settings ) freesettings( t->settings ); - if ( t->depends ) freetargets ( t->depends ); - if ( t->includes ) freetarget ( t->includes, (void *)0 ); - if ( t->actions ) freeactions ( t->actions ); -} - - -/* - * rules_done() - free RULE and TARGET tables. - */ - -void rules_done() -{ - hashenumerate( targethash, freetarget, 0 ); - hashdone( targethash ); - while ( settings_freelist ) - { - SETTINGS * n = settings_freelist->next; - BJAM_FREE( settings_freelist ); - settings_freelist = n; - } -} - - -/* - * args_new() - make a new reference-counted argument list. - */ - -argument_list * args_new() -{ - argument_list * r = (argument_list *)BJAM_MALLOC( sizeof(argument_list) ); - r->reference_count = 0; - lol_init( r->data ); - return r; -} - - -/* - * args_refer() - add a new reference to the given argument list. - */ - -void args_refer( argument_list * a ) -{ - ++a->reference_count; -} - - -/* - * args_free() - release a reference to the given argument list. - */ - -void args_free( argument_list * a ) -{ - if ( --a->reference_count <= 0 ) - { - lol_free( a->data ); - BJAM_FREE( a ); - } -} - - -/* - * actions_refer() - add a new reference to the given actions. - */ - -void actions_refer( rule_actions * a ) -{ - ++a->reference_count; -} - - -/* - * actions_free() - release a reference to the given actions. - */ - -void actions_free( rule_actions * a ) -{ - if ( --a->reference_count <= 0 ) - { - freestr( a->command ); - list_free( a->bindlist ); - BJAM_FREE( a ); - } -} - - -/* - * set_rule_body() - set the argument list and procedure of the given rule. - */ - -static void set_rule_body( RULE * rule, argument_list * args, PARSE * procedure ) -{ - if ( args ) - args_refer( args ); - if ( rule->arguments ) - args_free( rule->arguments ); - rule->arguments = args; - - if ( procedure ) - parse_refer( procedure ); - if ( rule->procedure ) - parse_free( rule->procedure ); - rule->procedure = procedure; -} - - -/* - * global_name() - given a rule, return the name for a corresponding rule in the - * global module. - */ - -static char * global_rule_name( RULE * r ) -{ - if ( r->module == root_module() ) - return r->name; - - { - char name[4096] = ""; - strncat( name, r->module->name, sizeof( name ) - 1 ); - strncat( name, r->name, sizeof( name ) - 1 ); - return newstr( name); - } -} - - -/* - * global_rule() - given a rule, produce the corresponding entry in the global - * module. - */ - -static RULE * global_rule( RULE * r ) -{ - if ( r->module == root_module() ) - return r; - - { - char * name = global_rule_name( r ); - RULE * result = define_rule( r->module, name, root_module() ); - freestr( name ); - return result; - } -} - - -/* - * new_rule_body() - make a new rule named rulename in the given module, with - * the given argument list and procedure. If exported is true, the rule is - * exported to the global module as modulename.rulename. - */ - -RULE * new_rule_body( module_t * m, char * rulename, argument_list * args, PARSE * procedure, int exported ) -{ - RULE * local = define_rule( m, rulename, m ); - local->exported = exported; - set_rule_body( local, args, procedure ); - - /* Mark the procedure with the global rule name, regardless of whether the - * rule is exported. That gives us something reasonably identifiable that we - * can use, e.g. in profiling output. Only do this once, since this could be - * called multiple times with the same procedure. - */ - if ( procedure->rulename == 0 ) - procedure->rulename = global_rule_name( local ); - - return local; -} - - -static void set_rule_actions( RULE * rule, rule_actions * actions ) -{ - if ( actions ) - actions_refer( actions ); - if ( rule->actions ) - actions_free( rule->actions ); - rule->actions = actions; -} - - -static rule_actions * actions_new( char * command, LIST * bindlist, int flags ) -{ - rule_actions * result = (rule_actions *)BJAM_MALLOC( sizeof( rule_actions ) ); - result->command = copystr( command ); - result->bindlist = bindlist; - result->flags = flags; - result->reference_count = 0; - return result; -} - - -RULE * new_rule_actions( module_t * m, char * rulename, char * command, LIST * bindlist, int flags ) -{ - RULE * local = define_rule( m, rulename, m ); - RULE * global = global_rule( local ); - set_rule_actions( local, actions_new( command, bindlist, flags ) ); - set_rule_actions( global, local->actions ); - return local; -} - - -/* - * Looks for a rule in the specified module, and returns it, if found. First - * checks if the rule is present in the module's rule table. Second, if name of - * the rule is in the form name1.name2 and name1 is in the list of imported - * modules, look in module 'name1' for rule 'name2'. - */ - -RULE * lookup_rule( char * rulename, module_t * m, int local_only ) -{ - RULE rule; - RULE * r = &rule; - RULE * result = 0; - module_t * original_module = m; - - r->name = rulename; - - if ( m->class_module ) - m = m->class_module; - - if ( m->rules && hashcheck( m->rules, (HASHDATA * *)&r ) ) - result = r; - else if ( !local_only && m->imported_modules ) - { - /* Try splitting the name into module and rule. */ - char *p = strchr( r->name, '.' ) ; - if ( p ) - { - *p = '\0'; - /* Now, r->name keeps the module name, and p+1 keeps the rule name. - */ - if ( hashcheck( m->imported_modules, (HASHDATA * *)&r ) ) - result = lookup_rule( p + 1, bindmodule( rulename ), 1 ); - *p = '.'; - } - } - - if ( result ) - { - if ( local_only && !result->exported ) - result = 0; - else - { - /* Lookup started in class module. We have found a rule in class - * module, which is marked for execution in that module, or in some - * instances. Mark it for execution in the instance where we started - * the lookup. - */ - int execute_in_class = ( result->module == m ); - int execute_in_some_instance = ( result->module->class_module && - ( result->module->class_module == m ) ); - if ( ( original_module != m ) && - ( execute_in_class || execute_in_some_instance ) ) - result->module = original_module; - } - } - - return result; -} - - -RULE * bindrule( char * rulename, module_t * m ) -{ - RULE * result = lookup_rule( rulename, m, 0 ); - if ( !result ) - result = lookup_rule( rulename, root_module(), 0 ); - /* We have only one caller, 'evaluate_rule', which will complain about - * calling an undefined rule. We could issue the error here, but we do not - * have the necessary information, such as frame. - */ - if ( !result ) - result = enter_rule( rulename, m ); - return result; -} - - -RULE * import_rule( RULE * source, module_t * m, char * name ) -{ - RULE * dest = define_rule( source->module, name, m ); - set_rule_body( dest, source->arguments, source->procedure ); - set_rule_actions( dest, source->actions ); - return dest; -} diff --git a/jam-files/engine/rules.h b/jam-files/engine/rules.h deleted file mode 100644 index 806a1469..00000000 --- a/jam-files/engine/rules.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -#ifndef RULES_DWA_20011020_H -#define RULES_DWA_20011020_H - -#include "modules.h" -#include "jam.h" -#include "parse.h" - - -/* - * 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 - an entity (e.g. a file) 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. - */ - -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. */ - -/* A rule's argument list. */ -struct argument_list -{ - int reference_count; - LOL data[1]; -}; - -/* Build actions corresponding to a rule. */ -struct rule_actions -{ - int reference_count; - char * command; /* command string from ACTIONS */ - LIST * bindlist; - int flags; /* modifiers on ACTIONS */ - -#define RULE_NEWSRCS 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 /* do not mention it unless verbose */ -#define RULE_PIECEMEAL 0x10 /* split exec so each $(>) is small */ -#define RULE_EXISTING 0x20 /* $(>) is pre-exisitng sources only */ -}; - -typedef struct rule_actions rule_actions; -typedef struct argument_list argument_list; - -struct _rule -{ - char * name; - PARSE * procedure; /* parse tree from RULE */ - argument_list * arguments; /* argument checking info, or NULL for unchecked - */ - rule_actions * actions; /* build actions, or NULL for no actions */ - module_t * module; /* module in which this rule is executed */ - int exported; /* nonzero if this rule is supposed to appear in - * the global module and be automatically - * imported into other modules - */ -#ifdef HAVE_PYTHON - PyObject * python_function; -#endif -}; - -/* 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; - char * symbol; /* symbol name for var_set() */ - LIST * value; /* symbol value for var_set() */ - int multiple; -}; - -/* TARGETS - a chain of TARGETs. */ -struct _targets -{ - TARGETS * next; - TARGETS * tail; /* valid only for head */ - TARGET * target; -}; - -/* TARGET - an entity (e.g. a file) that can be built. */ -struct _target -{ - char * name; - char * boundname; /* if search() relocates target */ - ACTIONS * actions; /* rules to execute, if any */ - SETTINGS * settings; /* variables to define */ - - short flags; /* status info */ - -#define T_FLAG_TEMP 0x0001 /* TEMPORARY applied */ -#define T_FLAG_NOCARE 0x0002 /* NOCARE applied */ -#define T_FLAG_NOTFILE 0x0004 /* NOTFILE applied */ -#define T_FLAG_TOUCHED 0x0008 /* ALWAYS applied or -t target */ -#define T_FLAG_LEAVES 0x0010 /* LEAVES applied */ -#define T_FLAG_NOUPDATE 0x0020 /* NOUPDATE applied */ -#define T_FLAG_VISITED 0x0040 /* CWM: Used in debugging */ - -/* This flag has been added to support a new built-in rule named "RMBAD". It is - * used to force removal of outdated targets whose dependencies fail to build. - */ -#define T_FLAG_RMOLD 0x0080 /* RMBAD applied */ - -/* This flag was added to support a new built-in rule named "FAIL_EXPECTED" used - * to indicate that the result of running a given action should be inverted, - * i.e. ok <=> fail. This is useful for launching certain test runs from a - * Jamfile. - */ -#define T_FLAG_FAIL_EXPECTED 0x0100 /* FAIL_EXPECTED applied */ - -#define T_FLAG_INTERNAL 0x0200 /* internal INCLUDES node */ - -/* Indicates that the target must be a file. This prevents matching non-files, - * like directories, when a target is searched. - */ -#define T_FLAG_ISFILE 0x0400 - -#define T_FLAG_PRECIOUS 0x0800 - - char binding; /* how target relates to a real file or - * folder - */ - -#define T_BIND_UNBOUND 0 /* a disembodied name */ -#define T_BIND_MISSING 1 /* could not find real file */ -#define T_BIND_PARENTS 2 /* using parent's timestamp */ -#define T_BIND_EXISTS 3 /* real file, timestamp valid */ - - TARGETS * depends; /* dependencies */ - TARGETS * dependants; /* the inverse of dependencies */ - TARGETS * rebuilds; /* targets that should be force-rebuilt - * whenever this one is - */ - TARGET * includes; /* internal includes node */ - TARGET * original_target; /* original_target->includes = this */ - char rescanned; - - 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 did not 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_REBUILD 6 -#define T_FATE_MISSING 7 /* is missing, needs updating */ -#define T_FATE_NEEDTMP 8 /* missing temp that must be rebuild */ -#define T_FATE_OUTDATED 9 /* is out of date, needs updating */ -#define T_FATE_UPDATE 10 /* deps updated, needs updating */ - -#define T_FATE_BROKEN 11 /* >= BROKEN ruins parents */ -#define T_FATE_CANTFIND 11 /* no rules to make missing target */ -#define T_FATE_CANTMAKE 12 /* can not find dependencies */ - - 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 */ - -#ifdef OPT_SEMAPHORE - #define T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */ -#endif - -#ifdef OPT_SEMAPHORE - TARGET * semaphore; /* used in serialization */ -#endif - - char status; /* exec_cmd() result */ - - int asynccnt; /* child deps outstanding */ - TARGETS * parents; /* used by make1() for completion */ - char * cmds; /* type-punned command list */ - - char * failed; -}; - - -/* Action related functions. */ -ACTIONS * actionlist ( ACTIONS *, ACTION * ); -void freeactions ( ACTIONS * ); -SETTINGS * addsettings ( SETTINGS *, int flag, char * symbol, LIST * value ); -void pushsettings ( SETTINGS * ); -void popsettings ( SETTINGS * ); -SETTINGS * copysettings ( SETTINGS * ); -void freesettings ( SETTINGS * ); -void actions_refer( rule_actions * ); -void actions_free ( rule_actions * ); - -/* Argument list related functions. */ -void args_free ( argument_list * ); -argument_list * args_new (); -void args_refer( argument_list * ); - -/* Rule related functions. */ -RULE * bindrule ( char * rulename, module_t * ); -RULE * import_rule ( RULE * source, module_t *, char * name ); -RULE * new_rule_body ( module_t *, char * rulename, argument_list *, PARSE * procedure, int exprt ); -RULE * new_rule_actions( module_t *, char * rulename, char * command, LIST * bindlist, int flags ); -void rule_free ( RULE * ); - -/* Target related functions. */ -void bind_explicitly_located_targets(); -TARGET * bindtarget ( char const * target_name ); -TARGET * copytarget ( TARGET const * t ); -void freetargets ( TARGETS * ); -TARGET * search_for_target ( char * name, LIST * search_path ); -TARGETS * targetchain ( TARGETS * chain, TARGETS * ); -TARGETS * targetentry ( TARGETS * chain, TARGET * ); -void target_include ( TARGET * including, TARGET * included ); -TARGETS * targetlist ( TARGETS * chain, LIST * target_names ); -void touch_target ( char * t ); - -/* Final module cleanup. */ -void rules_done(); - -#endif diff --git a/jam-files/engine/scan.c b/jam-files/engine/scan.c deleted file mode 100644 index 11c44c0e..00000000 --- a/jam-files/engine/scan.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -#include "jam.h" -#include "lists.h" -#include "parse.h" -#include "scan.h" -#include "jamgram.h" -#include "jambase.h" -#include "newstr.h" - -/* - * 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. - */ - -struct keyword -{ - char * word; - int type; -} keywords[] = -{ -#include "jamgramtab.h" - { 0, 0 } -}; - -struct include -{ - struct include * next; /* next serial include file */ - char * string; /* pointer into current line */ - char * * strings; /* for yyfparse() -- text to parse */ - FILE * file; /* for yyfparse() -- file being read */ - 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 * ); - -#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( char * s ) -{ - /* We use yylval instead of incp to access the error location information as - * the incp pointer will already be reset to 0 in case the error occurred at - * EOF. - * - * The two may differ only if we get an error while reading a lexical token - * spanning muliple lines, e.g. a multi-line string literal or action body, - * in which case yylval location information will hold the information about - * where this token started while incp will hold the information about where - * reading it broke. - * - * TODO: Test the theory about when yylval and incp location information are - * the same and when they differ. - */ - printf( "%s:%d: %s at %s\n", yylval.file, yylval.line, s, symdump( &yylval ) ); - ++anyerrors; -} - - -int yyanyerrors() -{ - return anyerrors != 0; -} - - -void yyfparse( char * s ) -{ - struct include * i = (struct include *)BJAM_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 are reading from an internal string list, go to the next string. */ - if ( i->strings ) - { - if ( *i->strings ) - { - ++i->line; - i->string = *(i->strings++); - return *i->string++; - } - } - else - { - /* 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 is 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++; - } - } - - /* 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 ); - BJAM_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(); - - /* Turn trailing "\r\n" sequences into plain "\n" for Cygwin. */ - if ( ( c == '\n' ) && ( b[ -1 ] == '\r' ) ) - --b; - } - - /* We ate the ending brace -- regurgitate it. */ - if ( c != EOF ) - yyprev(); - - /* Check for 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 ); - yylval.file = incp->fname; - yylval.line = incp->line; - } - 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? */ - if ( c != '#' ) - break; - - /* Swallow up comment line. */ - while ( ( ( c = yychar() ) != EOF ) && ( c != '\n' ) ) ; - } - - /* c now points to the first character of a token. */ - if ( c == EOF ) - goto eof; - - yylval.file = incp->fname; - yylval.line = incp->line; - - /* 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 */ - if (c == 'n') - c = '\n'; - else if (c == 'r') - c = '\r'; - else if (c == 't') - c = '\t'; - *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. Do not scan if it is obviously not a keyword or if - * it is 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: - /* We do not reset yylval.file & yylval.line here so unexpected EOF error - * messages would include correct error location information. - */ - 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; -} - - -/* - * Get information about the current file and line, for those epsilon - * transitions that produce a parse. - */ - -void yyinput_stream( char * * name, int * line ) -{ - if ( incp ) - { - *name = incp->fname; - *line = incp->line; - } - else - { - *name = "(builtin)"; - *line = -1; - } -} diff --git a/jam-files/engine/scan.h b/jam-files/engine/scan.h deleted file mode 100644 index 3fad1c24..00000000 --- a/jam-files/engine/scan.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -/* - * YYSTYPE - value of a lexical token - */ - -#define YYSTYPE YYSYMBOL - -typedef struct _YYSTYPE -{ - int type; - char * string; - PARSE * parse; - LIST * list; - int number; - char * file; - int line; -} YYSTYPE; - -extern YYSTYPE yylval; - -void yymode( int n ); -void yyerror( char * s ); -int yyanyerrors(); -void yyfparse( char * s ); -int yyline(); -int yylex(); -int yyparse(); -void yyinput_stream( char * * name, int * line ); - -# define SCAN_NORMAL 0 /* normal parsing */ -# define SCAN_STRING 1 /* look only for matching } */ -# define SCAN_PUNCT 2 /* only punctuation keywords */ diff --git a/jam-files/engine/search.c b/jam-files/engine/search.c deleted file mode 100644 index 6c23d97a..00000000 --- a/jam-files/engine/search.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -#include "jam.h" -#include "lists.h" -#include "search.h" -#include "timestamp.h" -#include "pathsys.h" -#include "variable.h" -#include "newstr.h" -#include "compile.h" -#include "strings.h" -#include "hash.h" -#include "filesys.h" -#include <string.h> - - -typedef struct _binding -{ - char * binding; - char * target; -} BINDING; - -static struct hash *explicit_bindings = 0; - - -void call_bind_rule -( - char * target_, - char * boundname_ -) -{ - LIST * bind_rule = var_get( "BINDRULE" ); - if ( bind_rule ) - { - /* No guarantee that the target is an allocated string, so be on the - * safe side. - */ - char * target = copystr( target_ ); - - /* Likewise, do not rely on implementation details of newstr.c: allocate - * a copy of boundname. - */ - char * boundname = copystr( boundname_ ); - if ( boundname && target ) - { - /* Prepare the argument list. */ - FRAME frame[1]; - frame_init( frame ); - - /* First argument is the target name. */ - lol_add( frame->args, list_new( L0, target ) ); - - lol_add( frame->args, list_new( L0, boundname ) ); - if ( lol_get( frame->args, 1 ) ) - evaluate_rule( bind_rule->string, frame ); - - /* Clean up */ - frame_free( frame ); - } - else - { - if ( boundname ) - freestr( boundname ); - if ( target ) - freestr( target ); - } - } -} - -/* - * search.c - find a target along $(SEARCH) or $(LOCATE) - * First, check if LOCATE is set. If so, use it to determine - * the location of target and return, regardless of whether anything - * exists on that location. - * - * Second, examine all directories in SEARCH. If there's file already - * or there's another target with the same name which was placed - * to this location via LOCATE setting, stop and return the location. - * In case of previous target, return it's name via the third argument. - * - * This bevahiour allow to handle dependency on generated files. If - * caller does not expect that target is generated, 0 can be passed as - * the third argument. - */ - -char * -search( - char *target, - time_t *time, - char **another_target, - int file -) -{ - PATHNAME f[1]; - LIST *varlist; - string buf[1]; - int found = 0; - /* Will be set to 1 if target location is specified via LOCATE. */ - int explicitly_located = 0; - char *boundname = 0; - - if ( another_target ) - *another_target = 0; - - if (! explicit_bindings ) - explicit_bindings = hashinit( sizeof(BINDING), - "explicitly specified locations"); - - string_new( buf ); - /* 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->value ); - - explicitly_located = 1; - - timestamp( buf->value, time ); - found = 1; - } - else if ( ( varlist = var_get( "SEARCH" ) ) ) - { - while ( varlist ) - { - BINDING b, *ba = &b; - file_info_t *ff; - - f->f_root.ptr = varlist->string; - f->f_root.len = strlen( varlist->string ); - - string_truncate( buf, 0 ); - path_build( f, buf, 1 ); - - if ( DEBUG_SEARCH ) - printf( "search %s: %s\n", target, buf->value ); - - ff = file_query(buf->value); - timestamp( buf->value, time ); - - b.binding = buf->value; - - if ( hashcheck( explicit_bindings, (HASHDATA**)&ba ) ) - { - if ( DEBUG_SEARCH ) - printf(" search %s: found explicitly located target %s\n", - target, ba->target); - if ( another_target ) - *another_target = ba->target; - found = 1; - break; - } - else if ( ff && ff->time ) - { - if ( !file || ff->is_file ) - { - found = 1; - break; - } - } - - varlist = list_next( varlist ); - } - } - - if ( !found ) - { - /* 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; - - string_truncate( buf, 0 ); - path_build( f, buf, 1 ); - - if ( DEBUG_SEARCH ) - printf( "search %s: %s\n", target, buf->value ); - - timestamp( buf->value, time ); - } - - boundname = newstr( buf->value ); - string_free( buf ); - - if ( explicitly_located ) - { - BINDING b; - BINDING * ba = &b; - b.binding = boundname; - b.target = target; - /* CONSIDER: we probably should issue a warning is another file - is explicitly bound to the same location. This might break - compatibility, though. */ - hashenter( explicit_bindings, (HASHDATA * *)&ba ); - } - - /* prepare a call to BINDRULE if the variable is set */ - call_bind_rule( target, boundname ); - - return boundname; -} diff --git a/jam-files/engine/search.h b/jam-files/engine/search.h deleted file mode 100644 index c364cac0..00000000 --- a/jam-files/engine/search.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * 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) - */ - -char *search( char *target, time_t *time, char **another_target, int file ); diff --git a/jam-files/engine/strings.c b/jam-files/engine/strings.c deleted file mode 100644 index 89561237..00000000 --- a/jam-files/engine/strings.c +++ /dev/null @@ -1,201 +0,0 @@ -/* Copyright David Abrahams 2004. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -#include "jam.h" -#include "strings.h" -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <stdio.h> - - -#ifndef NDEBUG -# define JAM_STRING_MAGIC ((char)0xcf) -# define JAM_STRING_MAGIC_SIZE 4 -static void assert_invariants( string* self ) -{ - int i; - - if ( self->value == 0 ) - { - assert( self->size == 0 ); - assert( self->capacity == 0 ); - assert( self->opt[0] == 0 ); - return; - } - - assert( self->size < self->capacity ); - assert( ( self->capacity <= sizeof(self->opt) ) == ( self->value == self->opt ) ); - assert( strlen( self->value ) == self->size ); - - for (i = 0; i < 4; ++i) - { - assert( self->magic[i] == JAM_STRING_MAGIC ); - assert( self->value[self->capacity + i] == JAM_STRING_MAGIC ); - } -} -#else -# define JAM_STRING_MAGIC_SIZE 0 -# define assert_invariants(x) do {} while (0) -#endif - -void string_new( string* s ) -{ - s->value = s->opt; - s->size = 0; - s->capacity = sizeof(s->opt); - s->opt[0] = 0; -#ifndef NDEBUG - memset(s->magic, JAM_STRING_MAGIC, sizeof(s->magic)); -#endif - assert_invariants( s ); -} - -void string_free( string* s ) -{ - assert_invariants( s ); - if ( s->value != s->opt ) - BJAM_FREE( s->value ); - string_new( s ); -} - -static void string_reserve_internal( string* self, size_t capacity ) -{ - if ( self->value == self->opt ) - { - self->value = (char*)BJAM_MALLOC_ATOMIC( capacity + JAM_STRING_MAGIC_SIZE ); - self->value[0] = 0; - strncat( self->value, self->opt, sizeof(self->opt) ); - assert( strlen( self->value ) <= self->capacity ); /* This is a regression test */ - } - else - { - self->value = (char*)BJAM_REALLOC( self->value, capacity + JAM_STRING_MAGIC_SIZE ); - } -#ifndef NDEBUG - memcpy( self->value + capacity, self->magic, JAM_STRING_MAGIC_SIZE ); -#endif - self->capacity = capacity; -} - -void string_reserve( string* self, size_t capacity ) -{ - assert_invariants( self ); - if ( capacity <= self->capacity ) - return; - string_reserve_internal( self, capacity ); - assert_invariants( self ); -} - -static void extend_full( string* self, char const* start, char const* finish ) -{ - size_t new_size = self->capacity + ( finish - start ); - size_t new_capacity = self->capacity; - size_t old_size = self->capacity; - while ( new_capacity < new_size + 1) - new_capacity <<= 1; - string_reserve_internal( self, new_capacity ); - memcpy( self->value + old_size, start, new_size - old_size ); - self->value[new_size] = 0; - self->size = new_size; -} - -void string_append( string* self, char const* rhs ) -{ - char* p = self->value + self->size; - char* end = self->value + self->capacity; - assert_invariants( self ); - - while ( *rhs && p != end) - *p++ = *rhs++; - - if ( p != end ) - { - *p = 0; - self->size = p - self->value; - } - else - { - extend_full( self, rhs, rhs + strlen(rhs) ); - } - assert_invariants( self ); -} - -void string_append_range( string* self, char const* start, char const* finish ) -{ - char* p = self->value + self->size; - char* end = self->value + self->capacity; - assert_invariants( self ); - - while ( p != end && start != finish ) - *p++ = *start++; - - if ( p != end ) - { - *p = 0; - self->size = p - self->value; - } - else - { - extend_full( self, start, finish ); - } - assert_invariants( self ); -} - -void string_copy( string* s, char const* rhs ) -{ - string_new( s ); - string_append( s, rhs ); -} - -void string_truncate( string* self, size_t n ) -{ - assert_invariants( self ); - assert( n <= self->capacity ); - self->value[self->size = n] = 0; - assert_invariants( self ); -} - -void string_pop_back( string* self ) -{ - string_truncate( self, self->size - 1 ); -} - -void string_push_back( string* self, char x ) -{ - string_append_range( self, &x, &x + 1 ); -} - -char string_back( string* self ) -{ - assert_invariants( self ); - return self->value[self->size - 1]; -} - -#ifndef NDEBUG -void string_unit_test() -{ - string s[1]; - int i; - char buffer[sizeof(s->opt) * 2 + 2]; - int limit = sizeof(buffer) > 254 ? 254 : sizeof(buffer); - - string_new(s); - - for (i = 0; i < limit; ++i) - { - string_push_back( s, (char)(i + 1) ); - }; - - for (i = 0; i < limit; ++i) - { - assert( i < s->size ); - assert( s->value[i] == (char)(i + 1)); - } - - string_free(s); - -} -#endif - diff --git a/jam-files/engine/strings.h b/jam-files/engine/strings.h deleted file mode 100644 index 33c77bd7..00000000 --- a/jam-files/engine/strings.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef STRINGS_DWA20011024_H -# define STRINGS_DWA20011024_H - -/* Copyright David Abrahams 2004. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ - -# include <stddef.h> - -typedef struct string -{ - char* value; - unsigned long size; - unsigned long capacity; - char opt[32]; -#ifndef NDEBUG - char magic[4]; -#endif -} string; - -void string_new( string* ); -void string_copy( string*, char const* ); -void string_free( string* ); -void string_append( string*, char const* ); -void string_append_range( string*, char const*, char const* ); -void string_push_back( string* s, char x ); -void string_reserve( string*, size_t ); -void string_truncate( string*, size_t ); -void string_pop_back( string* ); -char string_back( string* ); -void string_unit_test(); - -#endif - diff --git a/jam-files/engine/subst.c b/jam-files/engine/subst.c deleted file mode 100644 index 75524ecc..00000000 --- a/jam-files/engine/subst.c +++ /dev/null @@ -1,94 +0,0 @@ -#include <stddef.h> -#include "jam.h" -#include "regexp.h" -#include "hash.h" - -#include "newstr.h" -#include "lists.h" -#include "parse.h" -#include "compile.h" -#include "frames.h" - -struct regex_entry -{ - const char* pattern; - regexp* regex; -}; -typedef struct regex_entry regex_entry; - -static struct hash* regex_hash; - -regexp* regex_compile( const char* pattern ) -{ - regex_entry entry, *e = &entry; - entry.pattern = pattern; - - if ( !regex_hash ) - regex_hash = hashinit(sizeof(regex_entry), "regex"); - - if ( hashenter( regex_hash, (HASHDATA **)&e ) ) - e->regex = regcomp( (char*)pattern ); - - return e->regex; -} - -LIST* -builtin_subst( - PARSE *parse, - FRAME *frame ) -{ - LIST* result = L0; - LIST* arg1 = lol_get( frame->args, 0 ); - - if ( arg1 && list_next(arg1) && list_next(list_next(arg1)) ) - { - - const char* source = arg1->string; - const char* pattern = list_next(arg1)->string; - regexp* repat = regex_compile( pattern ); - - if ( regexec( repat, (char*)source) ) - { - LIST* subst = list_next(arg1); - - while ((subst = list_next(subst)) != L0) - { -# define BUFLEN 4096 - char buf[BUFLEN + 1]; - const char* in = subst->string; - char* out = buf; - - for ( in = subst->string; *in && out < buf + BUFLEN; ++in ) - { - if ( *in == '\\' || *in == '$' ) - { - ++in; - if ( *in == 0 ) - { - break; - } - else if ( *in >= '0' && *in <= '9' ) - { - unsigned n = *in - '0'; - const size_t srclen = repat->endp[n] - repat->startp[n]; - const size_t remaining = buf + BUFLEN - out; - const size_t len = srclen < remaining ? srclen : remaining; - memcpy( out, repat->startp[n], len ); - out += len; - continue; - } - /* fall through and copy the next character */ - } - *out++ = *in; - } - *out = 0; - - result = list_new( result, newstr( buf ) ); -#undef BUFLEN - } - } - } - - return result; -} - diff --git a/jam-files/engine/timestamp.c b/jam-files/engine/timestamp.c deleted file mode 100644 index 8a59c8c0..00000000 --- a/jam-files/engine/timestamp.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -# include "jam.h" - -# include "hash.h" -# include "filesys.h" -# include "pathsys.h" -# include "timestamp.h" -# include "newstr.h" -# include "strings.h" - -/* - * timestamp.c - get the timestamp of a file or archive member - * - * 09/22/00 (seiwald) - downshift names on OS2, too - */ - -/* - * BINDING - all known files - */ - -typedef struct _binding BINDING; - -struct _binding { - 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 *, char *, int, time_t ); - -static char * time_progress[] = -{ - "INIT", - "NOENTRY", - "SPOTTED", - "MISSING", - "FOUND" -}; - - -/* - * timestamp() - return timestamp on a file, if present. - */ - -void timestamp( char * target, time_t * time ) -{ - PROFILE_ENTER( timestamp ); - - PATHNAME f1; - PATHNAME f2; - BINDING binding; - BINDING * b = &binding; - string buf[ 1 ]; -#ifdef DOWNSHIFT_PATHS - string path; - char * p; -#endif - -#ifdef DOWNSHIFT_PATHS - string_copy( &path, target ); - p = path.value; - - do - { - *p = tolower( *p ); -#ifdef NT - /* On NT, we must use backslashes or the file will not be found. */ - if ( *p == '/' ) - *p = PATH_DELIM; -#endif - } - while ( *p++ ); - - target = path.value; -#endif /* #ifdef DOWNSHIFT_PATHS */ - string_new( buf ); - - 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; - BINDING * b = &binding; - - f2 = f1; - f2.f_grist.len = 0; - path_parent( &f2 ); - path_build( &f2, buf, 0 ); - - b->name = buf->value; - b->time = b->flags = 0; - b->progress = BIND_INIT; - - if ( hashenter( bindhash, (HASHDATA * *)&b ) ) - b->name = newstr( buf->value ); /* never freed */ - - if ( !( b->flags & BIND_SCANNED ) ) - { - file_dirscan( buf->value, time_enter, bindhash ); - b->flags |= BIND_SCANNED; - } - } - - /* Scan archive if not already done so. */ - if ( f1.f_member.len ) - { - BINDING binding; - BINDING * b = &binding; - - f2 = f1; - f2.f_grist.len = 0; - f2.f_member.len = 0; - string_truncate( buf, 0 ); - path_build( &f2, buf, 0 ); - - b->name = buf->value; - b->time = b->flags = 0; - b->progress = BIND_INIT; - - if ( hashenter( bindhash, (HASHDATA * *)&b ) ) - b->name = newstr( buf->value ); /* never freed */ - - if ( !( b->flags & BIND_SCANNED ) ) - { - file_archscan( buf->value, time_enter, bindhash ); - b->flags |= BIND_SCANNED; - } - } - - afterscanning: - - if ( b->progress == BIND_SPOTTED ) - { - b->progress = file_time( b->name, &b->time ) < 0 - ? BIND_MISSING - : BIND_FOUND; - } - - *time = b->progress == BIND_FOUND ? b->time : 0; - string_free( buf ); -#ifdef DOWNSHIFT_PATHS - string_free( &path ); -#endif - - PROFILE_EXIT( timestamp ); -} - - -static void time_enter( void * closure, char * target, int found, time_t time ) -{ - BINDING 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 ] ); -} - - -/* - * stamps_done() - free timestamp tables. - */ - -void stamps_done() -{ - hashdone( bindhash ); -} diff --git a/jam-files/engine/timestamp.h b/jam-files/engine/timestamp.h deleted file mode 100644 index f5752763..00000000 --- a/jam-files/engine/timestamp.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * 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 stamps_done(); diff --git a/jam-files/engine/variable.c b/jam-files/engine/variable.c deleted file mode 100644 index 795f3458..00000000 --- a/jam-files/engine/variable.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Copyright 2005 Reece H. Dunn. - * Copyright 2005 Rene Rivera. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -#include "jam.h" -#include "lists.h" -#include "parse.h" -#include "variable.h" -#include "expand.h" -#include "hash.h" -#include "filesys.h" -#include "newstr.h" -#include "strings.h" -#include "pathsys.h" -#include <stdlib.h> -#include <stdio.h> - -/* - * 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 - */ - -static struct hash *varhash = 0; - -/* - * VARIABLE - a user defined multi-value variable - */ - -typedef struct _variable VARIABLE ; - -struct _variable -{ - char * symbol; - LIST * value; -}; - -static VARIABLE * var_enter( char * symbol ); -static void var_dump( char * symbol, LIST * value, char * what ); - - -/* - * var_hash_swap() - swap all variable settings with those passed - * - * Used to implement separate settings spaces for modules - */ - -void var_hash_swap( struct hash * * new_vars ) -{ - struct hash * old = varhash; - varhash = *new_vars; - *new_vars = old; -} - - -/* - * var_defines() - load a bunch of variable=value settings - * - * If preprocess is false, take the value verbatim. - * - * Otherwise, if the variable value is enclosed in quotes, strip the - * quotes. - * - * Otherwise, if variable name ends in PATH, split value at :'s. - * - * Otherwise, split the value at blanks. - */ - -void var_defines( char * const * e, int preprocess ) -{ - string buf[1]; - - string_new( buf ); - - for ( ; *e; ++e ) - { - char * val; - -# 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; - char * pp; - char * p; -# ifdef OPT_NO_EXTERNAL_VARIABLE_SPLIT - char split = '\0'; -# else - # ifdef OS_MAC - char split = ','; - # else - char split = ' '; - # endif -# endif - size_t len = strlen( val + 1 ); - - int quoted = ( val[1] == '"' ) && ( val[len] == '"' ) && - ( len > 1 ); - - if ( quoted && preprocess ) - { - string_append_range( buf, val + 2, val + len ); - l = list_new( l, newstr( buf->value ) ); - string_truncate( buf, 0 ); - } - else - { - /* 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; - preprocess && ( ( p = strchr( pp, split ) ) != 0 ); - pp = p + 1 - ) - { - string_append_range( buf, pp, p ); - l = list_new( l, newstr( buf->value ) ); - string_truncate( buf, 0 ); - } - - l = list_new( l, newstr( pp ) ); - } - - /* Get name. */ - string_append_range( buf, *e, val ); - var_set( buf->value, l, VAR_SET ); - string_truncate( buf, 0 ); - } - } - string_free( buf ); -} - - -/* - * var_string() - expand a string with variables in it - * - * Copies in to out; doesn't modify targets & sources. - */ - -int var_string( 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++; - } - #ifdef OPT_AT_FILES - else if ( ( in[ 0 ] == '@' ) && ( in[ 1 ] == '(' ) ) - { - int depth = 1; - char * ine = in + 2; - char * split = 0; - - /* Scan the content of the response file @() section. */ - while ( *ine && ( depth > 0 ) ) - { - switch ( *ine ) - { - case '(': ++depth; break; - case ')': --depth; break; - case ':': - if ( ( depth == 1 ) && ( ine[ 1 ] == 'E' ) && ( ine[ 2 ] == '=' ) ) - split = ine; - break; - } - ++ine; - } - - if ( !split ) - { - /* the @() reference doesn't match the @(foo:E=bar) format. - hence we leave it alone by copying directly to output. */ - int l = 0; - if ( out + 2 >= oute ) return -1; - *( out++ ) = '@'; - *( out++ ) = '('; - l = var_string( in + 2, out, oute - out, lol ); - if ( l < 0 ) return -1; - out += l; - if ( out + 1 >= oute ) return -1; - *( out++ ) = ')'; - } - else if ( depth == 0 ) - { - string file_name_v; - int file_name_l = 0; - const char * file_name_s = 0; - - /* Expand the temporary file name var inline. */ - #if 0 - string_copy( &file_name_v, "$(" ); - string_append_range( &file_name_v, in + 2, split ); - string_push_back( &file_name_v, ')' ); - #else - string_new( &file_name_v ); - string_append_range( &file_name_v, in + 2, split ); - #endif - file_name_l = var_string( file_name_v.value, out, oute - out + 1, lol ); - string_free( &file_name_v ); - if ( file_name_l < 0 ) return -1; - file_name_s = out; - - /* For stdout/stderr we will create a temp file and generate - * a command that outputs the content as needed. - */ - if ( ( strcmp( "STDOUT", out ) == 0 ) || - ( strcmp( "STDERR", out ) == 0 ) ) - { - int err_redir = strcmp( "STDERR", out ) == 0; - out[ 0 ] = '\0'; - file_name_s = path_tmpfile(); - file_name_l = strlen(file_name_s); - #ifdef OS_NT - if ( ( out + 7 + file_name_l + ( err_redir ? 5 : 0 ) ) >= oute ) - return -1; - sprintf( out,"type \"%s\"%s", file_name_s, - err_redir ? " 1>&2" : "" ); - #else - if ( ( out + 6 + file_name_l + ( err_redir ? 5 : 0 ) ) >= oute ) - return -1; - sprintf( out,"cat \"%s\"%s", file_name_s, - err_redir ? " 1>&2" : "" ); - #endif - /* We also make sure that the temp files created by this - * get nuked eventually. - */ - file_remove_atexit( file_name_s ); - } - - /* Expand the file value into the file reference. */ - var_string_to_file( split + 3, ine - split - 4, file_name_s, - lol ); - - /* Continue on with the expansion. */ - out += strlen( out ); - } - - /* And continue with the parsing just past the @() reference. */ - in = ine; - } - #endif - else - { - *out++ = *in++; - } - } - - /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */ - if ( out >= oute ) - return -1; - /* Do not increment, intentionally. */ - *out = '\0'; - - /* 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; - l = list_next( l ); - if ( l ) *out++ = ' '; - } - - list_free( l ); - } - } - - if ( out >= oute ) - return -1; - - *out++ = '\0'; - - return out - out0; -} - - -void var_string_to_file( const char * in, int insize, const char * out, LOL * lol ) -{ - char const * ine = in + insize; - FILE * out_file = 0; - int out_debug = DEBUG_EXEC ? 1 : 0; - if ( globs.noexec ) - { - /* out_debug = 1; */ - } - else if ( strcmp( out, "STDOUT" ) == 0 ) - { - out_file = stdout; - } - else if ( strcmp( out, "STDERR" ) == 0 ) - { - out_file = stderr; - } - else - { - /* Handle "path to file" filenames. */ - string out_name; - if ( ( out[ 0 ] == '"' ) && ( out[ strlen( out ) - 1 ] == '"' ) ) - { - string_copy( &out_name, out + 1 ); - string_truncate( &out_name, out_name.size - 1 ); - } - else - { - string_copy( &out_name,out ); - } - out_file = fopen( out_name.value, "w" ); - if ( !out_file ) - { - printf( "failed to write output file '%s'!\n", out_name.value ); - exit( EXITBAD ); - } - string_free( &out_name ); - } - - if ( out_debug ) printf( "\nfile %s\n", out ); - - while ( *in && ( in < ine ) ) - { - int dollar = 0; - const char * output_0 = in; - const char * output_1 = in; - - /* Copy white space. */ - while ( ( output_1 < ine ) && isspace( *output_1 ) ) - ++output_1; - - if ( output_0 < output_1 ) - { - if ( out_file ) fwrite( output_0, output_1 - output_0, 1, out_file ); - if ( out_debug ) fwrite( output_0, output_1 - output_0, 1, stdout ); - } - output_0 = output_1; - - /* Copy non-white space, watching for variables. */ - while ( ( output_1 < ine ) && *output_1 && !isspace( *output_1 ) ) - { - if ( ( output_1[ 0 ] == '$' ) && ( output_1[ 1 ] == '(' ) ) - ++dollar; - ++output_1; - } - - /* If a variable encountered, expand it and embed the space-separated - * members of the list in the output. - */ - if ( dollar ) - { - LIST * l = var_expand( L0, (char *)output_0, (char *)output_1, lol, 0 ); - - while ( l ) - { - if ( out_file ) fputs( l->string, out_file ); - if ( out_debug ) puts( l->string ); - l = list_next( l ); - if ( l ) - { - if ( out_file ) fputc( ' ', out_file ); - if ( out_debug ) fputc( ' ', stdout ); - } - } - - list_free( l ); - } - else if ( output_0 < output_1 ) - { - if ( out_file ) - { - const char * output_n = output_0; - while ( output_n < output_1 ) - { - output_n += fwrite( output_n, 1, output_1-output_n, out_file ); - } - } - if ( out_debug ) - { - const char * output_n = output_0; - while ( output_n < output_1 ) - { - output_n += fwrite( output_n, 1, output_1-output_n, stdout ); - } - } - } - - in = output_1; - } - - if ( out_file && ( out_file != stdout ) && ( out_file != stderr ) ) - { - fflush( out_file ); - fclose( out_file ); - } - - if ( out_debug ) fputc( '\n', stdout ); -} - - -/* - * var_get() - get value of a user defined symbol. - * - * Returns NULL if symbol unset. - */ - -LIST * var_get( char * symbol ) -{ - LIST * result = 0; -#ifdef OPT_AT_FILES - /* Some "fixed" variables... */ - if ( strcmp( "TMPDIR", symbol ) == 0 ) - { - result = list_new( L0, newstr( (char *)path_tmpdir() ) ); - } - else if ( strcmp( "TMPNAME", symbol ) == 0 ) - { - result = list_new( L0, newstr( (char *)path_tmpnam() ) ); - } - else if ( strcmp( "TMPFILE", symbol ) == 0 ) - { - result = list_new( L0, newstr( (char *)path_tmpfile() ) ); - } - else if ( strcmp( "STDOUT", symbol ) == 0 ) - { - result = list_new( L0, newstr( "STDOUT" ) ); - } - else if ( strcmp( "STDERR", symbol ) == 0 ) - { - result = list_new( L0, newstr( "STDERR" ) ); - } - else -#endif - { - VARIABLE var; - VARIABLE * v = &var; - - v->symbol = symbol; - - if ( varhash && hashcheck( varhash, (HASHDATA * *)&v ) ) - { - if ( DEBUG_VARGET ) - var_dump( v->symbol, v->value, "get" ); - result = v->value; - } - } - return result; -} - - -/* - * 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( 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( 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( char * symbol ) -{ - VARIABLE var; - VARIABLE * 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( char * symbol, LIST * value, char * what ) -{ - printf( "%s %s = ", what, symbol ); - list_print( value ); - printf( "\n" ); -} - - -/* - * var_done() - free variable tables. - */ - -static void delete_var_( void * xvar, void * data ) -{ - VARIABLE * v = (VARIABLE *)xvar; - freestr( v->symbol ); - list_free( v-> value ); -} - - -void var_done() -{ - hashenumerate( varhash, delete_var_, (void *)0 ); - hashdone( varhash ); -} diff --git a/jam-files/engine/variable.h b/jam-files/engine/variable.h deleted file mode 100644 index 5c49e3ca..00000000 --- a/jam-files/engine/variable.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * variable.h - handle jam multi-element variables - */ - -struct hash; - -void var_defines( char* const *e, int preprocess ); -int var_string( char *in, char *out, int outsize, LOL *lol ); -LIST * var_get( char *symbol ); -void var_set( char *symbol, LIST *value, int flag ); -LIST * var_swap( char *symbol, LIST *value ); -void var_done(); -void var_hash_swap( struct hash** ); - -/** Expands the "in" expression directly into the "out" file. - The file can be one of: a path, STDOUT, or STDERR to send - the output to a file overwriting previous content, to - the console, or to the error output respectively. -*/ -void var_string_to_file( const char * in, int insize, const char * out, LOL * lol ); - -/* - * 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 */ - diff --git a/jam-files/engine/w32_getreg.c b/jam-files/engine/w32_getreg.c deleted file mode 100644 index 5a06f43e..00000000 --- a/jam-files/engine/w32_getreg.c +++ /dev/null @@ -1,207 +0,0 @@ -/* -Copyright Paul Lin 2003. Copyright 2006 Bojan Resnik. -Distributed under the Boost Software License, Version 1.0. (See accompanying -file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -*/ - -# include "jam.h" - -# if defined( OS_NT ) || defined( OS_CYGWIN ) - -# include "lists.h" -# include "newstr.h" -# include "parse.h" -# include "frames.h" -# include "strings.h" - -# define WIN32_LEAN_AND_MEAN -# include <windows.h> - -# define MAX_REGISTRY_DATA_LENGTH 4096 -# define MAX_REGISTRY_KEYNAME_LENGTH 256 -# define MAX_REGISTRY_VALUENAME_LENGTH 16384 - -typedef struct -{ - LPCSTR name; - HKEY value; -} KeyMap; - -static const KeyMap dlRootKeys[] = { - { "HKLM", HKEY_LOCAL_MACHINE }, - { "HKCU", HKEY_CURRENT_USER }, - { "HKCR", HKEY_CLASSES_ROOT }, - { "HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE }, - { "HKEY_CURRENT_USER", HKEY_CURRENT_USER }, - { "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT }, - { 0, 0 } -}; - -static HKEY get_key(char const** path) -{ - const KeyMap *p; - - for (p = dlRootKeys; p->name; ++p) - { - int n = strlen(p->name); - if (!strncmp(*path,p->name,n)) - { - if ((*path)[n] == '\\' || (*path)[n] == 0) - { - *path += n + 1; - break; - } - } - } - - return p->value; -} - -LIST* -builtin_system_registry( - PARSE *parse, - FRAME *frame ) -{ - char const* path = lol_get(frame->args, 0)->string; - LIST* result = L0; - HKEY key = get_key(&path); - - if ( - key != 0 - && ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key) - ) - { - DWORD type; - BYTE data[MAX_REGISTRY_DATA_LENGTH]; - DWORD len = sizeof(data); - LIST const* const field = lol_get(frame->args, 1); - - if ( ERROR_SUCCESS == - RegQueryValueEx(key, field ? field->string : 0, 0, &type, data, &len) ) - { - switch (type) - { - - case REG_EXPAND_SZ: - { - long len; - string expanded[1]; - string_new(expanded); - - while ( - (len = ExpandEnvironmentStrings( - (LPCSTR)data, expanded->value, expanded->capacity)) - > expanded->capacity - ) - string_reserve(expanded, len); - - expanded->size = len - 1; - - result = list_new( result, newstr(expanded->value) ); - string_free( expanded ); - } - break; - - case REG_MULTI_SZ: - { - char* s; - - for (s = (char*)data; *s; s += strlen(s) + 1) - result = list_new( result, newstr(s) ); - - } - break; - - case REG_DWORD: - { - char buf[100]; - sprintf( buf, "%u", *(PDWORD)data ); - result = list_new( result, newstr(buf) ); - } - break; - - case REG_SZ: - result = list_new( result, newstr((char*)data) ); - break; - } - } - RegCloseKey(key); - } - return result; -} - -static LIST* get_subkey_names(HKEY key, char const* path) -{ - LIST* result = 0; - - if ( ERROR_SUCCESS == - RegOpenKeyEx(key, path, 0, KEY_ENUMERATE_SUB_KEYS, &key) - ) - { - char name[MAX_REGISTRY_KEYNAME_LENGTH]; - DWORD name_size = sizeof(name); - DWORD index; - FILETIME last_write_time; - - for ( index = 0; - ERROR_SUCCESS == RegEnumKeyEx( - key, index, name, &name_size, 0, 0, 0, &last_write_time); - ++index, - name_size = sizeof(name) - ) - { - name[name_size] = 0; - result = list_append(result, list_new(0, newstr(name))); - } - - RegCloseKey(key); - } - - return result; -} - -static LIST* get_value_names(HKEY key, char const* path) -{ - LIST* result = 0; - - if ( ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key) ) - { - char name[MAX_REGISTRY_VALUENAME_LENGTH]; - DWORD name_size = sizeof(name); - DWORD index; - - for ( index = 0; - ERROR_SUCCESS == RegEnumValue( - key, index, name, &name_size, 0, 0, 0, 0); - ++index, - name_size = sizeof(name) - ) - { - name[name_size] = 0; - result = list_append(result, list_new(0, newstr(name))); - } - - RegCloseKey(key); - } - - return result; -} - -LIST* -builtin_system_registry_names( - PARSE *parse, - FRAME *frame ) -{ - char const* path = lol_get(frame->args, 0)->string; - char const* result_type = lol_get(frame->args, 1)->string; - - HKEY key = get_key(&path); - - if ( !strcmp(result_type, "subkeys") ) - return get_subkey_names(key, path); - if ( !strcmp(result_type, "values") ) - return get_value_names(key, path); - return 0; -} - -# endif diff --git a/jam-files/engine/yyacc.c b/jam-files/engine/yyacc.c deleted file mode 100644 index b5efc96b..00000000 --- a/jam-files/engine/yyacc.c +++ /dev/null @@ -1,268 +0,0 @@ -/* Copyright 2002 Rene Rivera. -** Distributed under the Boost Software License, Version 1.0. -** (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -*/ - -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> - -/* -# 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 -# -# 3-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 -# 11-20-2002 -# Reimplemented as a C program for portability. (Rene Rivera) -*/ - -void print_usage(); -char * copy_string(char * s, int l); -char * tokenize_string(char * s); -int cmp_literal(const void * a, const void * b); - -typedef struct -{ - char * string; - char * token; -} literal; - -int main(int argc, char ** argv) -{ - int result = 0; - if (argc != 4) - { - print_usage(); - result = 1; - } - else - { - FILE * token_output_f = 0; - FILE * grammar_output_f = 0; - FILE * grammar_source_f = 0; - - grammar_source_f = fopen(argv[3],"r"); - if (grammar_source_f == 0) { result = 1; } - if (result == 0) - { - literal literals[1024]; - int t = 0; - char l[2048]; - while (1) - { - if (fgets(l,2048,grammar_source_f) != 0) - { - char * c = l; - while (1) - { - char * c1 = strchr(c,'`'); - if (c1 != 0) - { - char * c2 = strchr(c1+1,'`'); - if (c2 != 0) - { - literals[t].string = copy_string(c1+1,c2-c1-1); - literals[t].token = tokenize_string(literals[t].string); - t += 1; - c = c2+1; - } - else - break; - } - else - break; - } - } - else - { - break; - } - } - literals[t].string = 0; - literals[t].token = 0; - qsort(literals,t,sizeof(literal),cmp_literal); - { - int p = 1; - int i = 1; - while (literals[i].string != 0) - { - if (strcmp(literals[p-1].string,literals[i].string) != 0) - { - literals[p] = literals[i]; - p += 1; - } - i += 1; - } - literals[p].string = 0; - literals[p].token = 0; - t = p; - } - token_output_f = fopen(argv[2],"w"); - if (token_output_f != 0) - { - int i = 0; - while (literals[i].string != 0) - { - fprintf(token_output_f," { \"%s\", %s },\n",literals[i].string,literals[i].token); - i += 1; - } - fclose(token_output_f); - } - else - result = 1; - if (result == 0) - { - grammar_output_f = fopen(argv[1],"w"); - if (grammar_output_f != 0) - { - int i = 0; - while (literals[i].string != 0) - { - fprintf(grammar_output_f,"%%token %s\n",literals[i].token); - i += 1; - } - rewind(grammar_source_f); - while (1) - { - if (fgets(l,2048,grammar_source_f) != 0) - { - char * c = l; - while (1) - { - char * c1 = strchr(c,'`'); - if (c1 != 0) - { - char * c2 = strchr(c1+1,'`'); - if (c2 != 0) - { - literal key; - literal * replacement = 0; - key.string = copy_string(c1+1,c2-c1-1); - key.token = 0; - replacement = (literal*)bsearch( - &key,literals,t,sizeof(literal),cmp_literal); - *c1 = 0; - fprintf(grammar_output_f,"%s%s",c,replacement->token); - c = c2+1; - } - else - { - fprintf(grammar_output_f,"%s",c); - break; - } - } - else - { - fprintf(grammar_output_f,"%s",c); - break; - } - } - } - else - { - break; - } - } - fclose(grammar_output_f); - } - else - result = 1; - } - } - if (result != 0) - { - perror("yyacc"); - } - } - return result; -} - -static char * usage[] = { - "yyacc <grammar output.y> <token table output.h> <grammar source.yy>", - 0 }; - -void print_usage() -{ - char ** u; - for (u = usage; *u != 0; ++u) - { - fputs(*u,stderr); putc('\n',stderr); - } -} - -char * copy_string(char * s, int l) -{ - char * result = (char*)malloc(l+1); - strncpy(result,s,l); - result[l] = 0; - return result; -} - -char * tokenize_string(char * s) -{ - char * result; - char * literal = s; - int l; - int c; - - if (strcmp(s,":") == 0) literal = "_colon"; - else if (strcmp(s,"!") == 0) literal = "_bang"; - else if (strcmp(s,"!=") == 0) literal = "_bang_equals"; - else if (strcmp(s,"&&") == 0) literal = "_amperamper"; - else if (strcmp(s,"&") == 0) literal = "_amper"; - else if (strcmp(s,"+") == 0) literal = "_plus"; - else if (strcmp(s,"+=") == 0) literal = "_plus_equals"; - else if (strcmp(s,"||") == 0) literal = "_barbar"; - else if (strcmp(s,"|") == 0) literal = "_bar"; - else if (strcmp(s,";") == 0) literal = "_semic"; - else if (strcmp(s,"-") == 0) literal = "_minus"; - else if (strcmp(s,"<") == 0) literal = "_langle"; - else if (strcmp(s,"<=") == 0) literal = "_langle_equals"; - else if (strcmp(s,">") == 0) literal = "_rangle"; - else if (strcmp(s,">=") == 0) literal = "_rangle_equals"; - else if (strcmp(s,".") == 0) literal = "_period"; - else if (strcmp(s,"?") == 0) literal = "_question"; - else if (strcmp(s,"?=") == 0) literal = "_question_equals"; - else if (strcmp(s,"=") == 0) literal = "_equals"; - else if (strcmp(s,",") == 0) literal = "_comma"; - else if (strcmp(s,"[") == 0) literal = "_lbracket"; - else if (strcmp(s,"]") == 0) literal = "_rbracket"; - else if (strcmp(s,"{") == 0) literal = "_lbrace"; - else if (strcmp(s,"}") == 0) literal = "_rbrace"; - else if (strcmp(s,"(") == 0) literal = "_lparen"; - else if (strcmp(s,")") == 0) literal = "_rparen"; - l = strlen(literal)+2; - result = (char*)malloc(l+1); - for (c = 0; literal[c] != 0; ++c) - { - result[c] = toupper(literal[c]); - } - result[l-2] = '_'; - result[l-1] = 't'; - result[l] = 0; - return result; -} - -int cmp_literal(const void * a, const void * b) -{ - return strcmp(((const literal *)a)->string,((const literal *)b)->string); -} |