2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-15 00:52:16 +00:00

Merge Boost Jam 3.1.17 release to Boost release.

[SVN r50535]
This commit is contained in:
Rene Rivera
2009-01-10 19:42:28 +00:00
parent 6d33c45e20
commit 8e4fd9daa8
86 changed files with 10782 additions and 10763 deletions

View File

@@ -18,9 +18,10 @@ if $(NT)
}
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.
# 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 + )
{
@@ -33,6 +34,7 @@ rule find-to-root ( dir : patterns + )
return $(globs) ;
}
# This global will hold the location of the user's boost-build.jam file.
.boost-build-file = ;
@@ -42,16 +44,16 @@ rule find-to-root ( dir : patterns + )
# 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 user, put
# sensible default value. This allowes Boost.Build to work without
# any environment variables, which is good in itself and also
# required by Debian Policy.
# 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 $(<)
@@ -60,41 +62,37 @@ rule _poke ( module-name ? : variables + : value * )
}
}
# 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.
# 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)
{
EXIT "Error: Illegal attempt to re-bootstrap the build system by invoking" ;
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.
#
# 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 files uses os.environ, so we need to
# update the value there.
# 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 ] ;
local bootstrap-file = [ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;
.bootstrap-file = $(bootstrap-file[1]) ;
# There is no boost-build.jam we can find, exit with an error
#
# 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." ;
@@ -108,44 +106,43 @@ rule boost-build ( dir ? )
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) ] ;
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 .*(bjam).* : $(ARGV[1]:BL) ]
|| $(BOOST_ROOT) # A temporary measure so Jam works with Boost.Build v1
|| $(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.
# 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.
# 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 boost-build-files =
[ find-to-root [ PWD ] : boost-build.jam ]
# Another temporary measure so Jam works with Boost.Build v1
# 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.
#
# 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 " ;
@@ -158,23 +155,21 @@ if [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]
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) ]
if [ MATCH .*(--debug-configuration).* : $(ARGV) ]
{
ECHO "notice: found boost-build.jam at"
[ NORMALIZE_PATH $(.boost-build-file) ] ;
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 wether we are loading the new V2
# system or the the old V1 system.
#
# 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" ;
@@ -211,7 +206,7 @@ else
# 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) - 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.
@@ -226,15 +221,15 @@ else
# Special targets defined in this file:
#
# all - parent of first, shell, files, lib, exe
# first - first dependent of 'all', for potential initialization
# shell - parent of all Shell targets
# 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:
#
@@ -314,7 +309,7 @@ else
# 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
# 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
#
@@ -347,35 +342,35 @@ if $(NT)
#
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
#
@@ -469,7 +464,7 @@ if $(NT)
C++FLAGS ?= $(CCFLAGS) ;
LINK ?= $(CC) ;
LINKFLAGS ?= $(CCFLAGS) ;
LINKLIBS ?=
LINKLIBS ?=
\"$(VISUALC16)\\lib\\mlibce.lib\"
\"$(VISUALC16)\\lib\\oldnames.lib\"
;
@@ -582,7 +577,7 @@ if $(NT)
else if $(TOOLSET) = MINGW
{
ECHO "Compiler is GCC with Mingw" ;
AR ?= ar -ru ;
CC ?= gcc ;
CCFLAGS ?= "" ;
@@ -600,7 +595,7 @@ if $(NT)
else if $(TOOLSET) = LCC
{
ECHO "Compiler is Win32-LCC" ;
AR ?= lcclib ;
CC ?= lcc ;
CCFLAGS ?= "" ;
@@ -616,7 +611,7 @@ if $(NT)
{
#
# XXX: We need better comments here !!
#
#
EXIT On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the
Borland or Microsoft directories. ;
}
@@ -627,18 +622,18 @@ 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
@@ -650,12 +645,12 @@ else if $(OS2)
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
#
@@ -698,7 +693,7 @@ else if $(OS2)
SUFLIB ?= .lib ;
SUFOBJ ?= .obj ;
SUFEXE ?= .exe ;
if $(TOOLSET) = WATCOM
{
AR ?= wlib ;
@@ -769,7 +764,7 @@ else if $(VMS)
SUFLIB ?= .olb ;
SUFOBJ ?= .obj ;
switch $(OS)
switch $(OS)
{
case OPENVMS : CCFLAGS ?= /stand=vaxc ;
case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;
@@ -778,7 +773,7 @@ else if $(VMS)
else if $(MAC)
{
local OPT ;
CW ?= "{CW}" ;
MACHDRS ?=
@@ -790,19 +785,19 @@ else if $(MAC)
"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib"
"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ;
MPWLIBS ?=
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 ?=
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 ?=
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 SIOUX.PPC.Lib"
"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC.Lib" ;
C++ ?= mwcppc ;
@@ -814,15 +809,15 @@ else if $(MAC)
DOTDOT ?= "::" ;
HDRS ?= $(MACHDRS) $(MPWHDRS) ;
LINK ?= mwlinkppc ;
LINKFLAGS ?= -mpwtool -warn ;
LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ;
LINKFLAGS ?= -mpwtool -warn ;
LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ;
MKDIR ?= newfolder ;
MV ?= rename -y ;
NOARSCAN ?= true ;
OPTIM ?= ;
RM ?= delete -y ;
SLASH ?= ":" ;
STDHDRS ?= ;
STDHDRS ?= ;
SUFLIB ?= .lib ;
SUFOBJ ?= .o ;
}
@@ -842,7 +837,7 @@ else if $(OS) = BEOS && $(METROWERKS)
NOARSCAN ?= true ;
STDHDRS ?= /boot/develop/headers/posix ;
}
else if $(OS) = BEOS
else if $(OS) = BEOS
{
BINDIR ?= /boot/apps ;
CC ?= gcc ;
@@ -865,7 +860,7 @@ else if $(UNIX)
CC ?= gcc ;
YACC ?= "bison -y" ;
case CYGWIN :
case CYGWIN :
CC ?= gcc ;
CCFLAGS += -D__cygwin__ ;
LEX ?= flex ;
@@ -895,12 +890,12 @@ else if $(UNIX)
C++ ?= gcc ;
CCFLAGS += -D_POSIX_SOURCE ;
HDRS += /usr/include ;
RANLIB ?= "" ;
RANLIB ?= "" ;
NOARSCAN ?= true ;
NOARUPDATE ?= true ;
case MVS :
RANLIB ?= "" ;
RANLIB ?= "" ;
case NEXT :
AR ?= libtool -o ;
@@ -1017,7 +1012,7 @@ else if $(UNIX)
YACCFILES ?= ;
YACCFLAGS ?= ;
HDRPATTERN =
HDRPATTERN =
"^[ ]*#[ ]*include[ ]*[<\"]([^\">]*)[\">].*$" ;
OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
@@ -1137,7 +1132,7 @@ rule Fortran
DEPENDS $(<) : $(>) ;
}
rule GenFile
rule GenFile
{
local _t = [ FGristSourceFiles $(<) ] ;
local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
@@ -1188,11 +1183,11 @@ rule HdrRule
local s ;
if $(HDRGRIST)
{
if $(HDRGRIST)
{
s = $(>:G=$(HDRGRIST)) ;
} else {
s = $(>) ;
} else {
s = $(>) ;
}
INCLUDES $(<) : $(s) ;
@@ -1236,14 +1231,14 @@ rule InstallInto
Install $(tt) : $(i) ;
Chmod $(tt) ;
if $(OWNER) && $(CHOWN)
{
if $(OWNER) && $(CHOWN)
{
Chown $(tt) ;
OWNER on $(tt) = $(OWNER) ;
}
if $(GROUP) && $(CHGRP)
{
if $(GROUP) && $(CHGRP)
{
Chgrp $(tt) ;
GROUP on $(tt) = $(GROUP) ;
}
@@ -1344,11 +1339,11 @@ rule LibraryFromObjects
MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
}
if $(NOARSCAN)
{
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.
# on-disk object files.
DEPENDS $(_l) : $(_s) ;
}
@@ -1446,12 +1441,12 @@ rule MkDir
NOUPDATE $(<) ;
if $(<) != $(DOT) && ! $($(<)-mkdir)
if $(<) != $(DOT) && ! $($(<)-mkdir)
{
local s ;
# Cheesy gate to prevent multiple invocations on same dir
# MkDir1 has the actions
# MkDir1 has the actions
# Arrange for jam dirs
$(<)-mkdir = true ;
@@ -1508,7 +1503,7 @@ rule Object
# 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
# 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.
@@ -1603,23 +1598,23 @@ rule SubDir
#
# SubDir TOP d1 [ ... ]
#
# This introduces a Jamfile that is part of a project tree
# 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
# 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
# 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.
#
# directory elements in order to set search & locate stuff.
#
if ! $($(<[1]))
{
if ! $(<[1])
{
EXIT SubDir syntax error ;
EXIT SubDir syntax error ;
}
$(<[1]) = [ FSubDir $(<[2-]) ] ;
@@ -1703,7 +1698,7 @@ rule SubInclude
}
_s = [ FDirName $(<[2-]) ] ;
include $(JAMFILE:D=$(_s):R=$($(<[1]))) ;
}
@@ -1735,14 +1730,13 @@ rule Yacc
Clean clean : $(<) $(_h) ;
}
# make sure someone includes $(_h) else it will be
# a deadly independent target
# Make sure someone includes $(_h) else it will be a deadly independent
# target.
INCLUDES $(<) : $(_h) ;
}
#
# Utility rules; no side effects on these
# Utility rules; no side effects on these.
#
rule FGrist
@@ -1761,13 +1755,13 @@ rule FGrist
return $(_g) ;
}
rule FGristFiles
rule FGristFiles
{
if ! $(SOURCE_GRIST)
{
return $(<) ;
}
else
else
{
return $(<:G=$(SOURCE_GRIST)) ;
}
@@ -1775,7 +1769,7 @@ rule FGristFiles
rule FGristSourceFiles
{
# Produce source file name name with grist in it,
# Produce source file name name with grist in it,
# if SOURCE_GRIST is set.
# Leave header files alone, because they have a global
@@ -1785,7 +1779,7 @@ rule FGristSourceFiles
{
return $(<) ;
}
else
else
{
local _i _o ;
@@ -1826,10 +1820,10 @@ rule FSubDir
# path (using ../../ etc) back to that root directory.
# Sets result in $(<)
if ! $(<[1])
if ! $(<[1])
{
_d = $(DOT) ;
}
}
else
{
_d = $(DOTDOT) ;
@@ -1877,7 +1871,7 @@ rule FDirName
else if $(MAC)
{
_s = $(DOT) ;
for _i in $(<)
{
_s = $(_i:R=$(_s)) ;
@@ -1885,7 +1879,7 @@ rule FDirName
}
else
{
_s = $(<[1]) ;
_s = $(<[1]) ;
for _i in $(<[2-])
{
@@ -1940,7 +1934,7 @@ rule FRelPath
rule FAppendSuffix
{
# E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
# returns (yacc,lex,foo.bat) on Unix and
# returns (yacc,lex,foo.bat) on Unix and
# (yacc.exe,lex.exe,foo.bat) on NT.
if $(>)
@@ -1968,7 +1962,7 @@ rule FAppendSuffix
rule unmakeDir
{
if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\
if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\
{
unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;
}
@@ -1982,10 +1976,10 @@ rule unmakeDir
rule FConvertToSlashes
{
local _d, _s, _i ;
unmakeDir _d : $(<) ;
_s = $(_d[1]) ;
_s = $(_d[1]) ;
for _i in $(_d[2-])
{
_s = $(_s)/$(_i) ;
@@ -2064,7 +2058,7 @@ actions HardLink
actions Install
{
$(CP) $(>) $(<)
$(CP) $(>) $(<)
}
actions Lex
@@ -2079,7 +2073,7 @@ actions LexMv
actions Link bind NEEDLIBS
{
$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
}
actions MkDir1
@@ -2252,7 +2246,7 @@ if $(NT)
{
actions together piecemeal Archive
{
$(AR) $(<) +-$(>)
$(AR) $(<) +-$(>)
}
actions Cc
@@ -2279,7 +2273,7 @@ if $(NT)
{
actions together piecemeal Archive
{
$(AR) /out:$(<) $(>)
$(AR) /out:$(<) $(>)
}
actions Cc
@@ -2303,13 +2297,13 @@ if $(NT)
# OS2 specific actions
#
else if $(OS2)
else if $(OS2)
{
if $(TOOLSET) = WATCOM
{
actions together piecemeal Archive
{
$(AR) $(<) +-$(>)
$(AR) $(<) +-$(>)
}
actions Cc
@@ -2357,19 +2351,19 @@ else if $(OS2)
else if $(VMS)
{
actions updated together piecemeal Archive
actions updated together piecemeal Archive
{
lib/replace $(<) $(>[1]) ,$(>[2-])
}
actions Cc
{
$(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>)
{
$(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>)
}
actions C++
{
$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>)
{
$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>)
}
actions piecemeal together existing Clean
@@ -2409,7 +2403,7 @@ else if $(VMS)
else if $(MAC)
{
actions together Archive
actions together Archive
{
$(LINK) -library -o $(<) $(>)
}
@@ -2417,13 +2411,13 @@ else if $(MAC)
actions Cc
{
set -e MWCincludes $(MACINC)
$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>)
$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>)
}
actions C++
{
{
set -e MWCincludes $(MACINC)
$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>)
$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>)
}
actions Link bind NEEDLIBS

View File

@@ -1,5 +1,5 @@
Name: boost-jam
Version: 3.1.16
Version: 3.1.17
Summary: Build tool
Release: 1
Source: %{name}-%{version}.tgz
@@ -11,9 +11,9 @@ 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
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
its use in the Boost Build System, but should be backward compatible
with Perforce Jam.
Authors:
@@ -26,7 +26,7 @@ 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
freely, as long as this copyright notice is retained and modifications
are clearly marked.
ALL WARRANTIES ARE HEREBY DISCLAIMED.
@@ -34,7 +34,7 @@ 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)

View File

@@ -7,8 +7,15 @@ REM ~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0
setlocal
goto Start
REM NOTE: The "setlocal & endlocal" construct is used to reset the errorlevel to 0.
REM NOTE: The "set _error_=" construct is used to set the errorlevel to 1
:Set_Error
color 00
goto :eof
:Clear_Error
ver >nul
goto :eof
:Error_Print
@@ -20,9 +27,10 @@ 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, intel-win32, metrowerks, mingw, msvc, vc7, vc8
ECHO ### Toolsets supported by this script are: borland, como, gcc, gcc-nocygwin,
ECHO ### intel-win32, metrowerks, mingw, msvc, vc7, vc8, vc9
ECHO ###
set _error_=
call :Set_Error
endlocal
goto :eof
@@ -31,7 +39,7 @@ goto :eof
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.
setlocal & endlocal
call :Clear_Error
setlocal
set test=%~$PATH:1
endlocal
@@ -40,15 +48,39 @@ goto :eof
:Test_Option
REM Tests wether the given string is in the form of an option: "--*"
setlocal & endlocal
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%] set _error_=
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
@@ -64,132 +96,134 @@ 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.
if "_%ProgramFiles%_" == "__" set ProgramFiles=C:\Program Files
call :Clear_Error
call :Test_Empty %ProgramFiles%
if not errorlevel 1 set ProgramFiles=C:\Program Files
setlocal & endlocal
call :Clear_Error
if NOT "_%VS90COMNTOOLS%_" == "__" (
set "BOOST_JAM_TOOLSET=vc9"
set "BOOST_JAM_TOOLSET_ROOT=%VS90COMNTOOLS%..\..\VC\"
goto :eof)
setlocal & endlocal
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)
setlocal & endlocal
call :Clear_Error
if NOT "_%VS80COMNTOOLS%_" == "__" (
set "BOOST_JAM_TOOLSET=vc8"
set "BOOST_JAM_TOOLSET_ROOT=%VS80COMNTOOLS%..\..\VC\"
goto :eof)
setlocal & endlocal
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)
setlocal & endlocal
call :Clear_Error
if NOT "_%VS71COMNTOOLS%_" == "__" (
set "BOOST_JAM_TOOLSET=vc7"
set "BOOST_JAM_TOOLSET_ROOT=%VS71COMNTOOLS%\..\..\VC7\"
goto :eof)
setlocal & endlocal
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)
setlocal & endlocal
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)
setlocal & endlocal
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)
setlocal & endlocal
call :Clear_Error
if NOT "_%MSVCDir%_" == "__" (
set "BOOST_JAM_TOOLSET=msvc"
set "BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\"
goto :eof)
setlocal & endlocal
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)
setlocal & endlocal
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)
setlocal & endlocal
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)
setlocal & endlocal
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)
setlocal & endlocal
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)
setlocal & endlocal
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)
setlocal & endlocal
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)
setlocal & endlocal
call :Clear_Error
if EXIST "C:\MinGW\bin\gcc.exe" (
set "BOOST_JAM_TOOLSET=mingw"
set "BOOST_JAM_TOOLSET_ROOT=C:\MinGW\"
goto :eof)
setlocal & endlocal
call :Clear_Error
if NOT "_%CWFolder%_" == "__" (
set "BOOST_JAM_TOOLSET=metrowerks"
set "BOOST_JAM_TOOLSET_ROOT=%CWFolder%\"
goto :eof )
setlocal & endlocal
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)
setlocal & endlocal
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.
setlocal & endlocal
call :Clear_Error
call :Test_Path yacc.exe
if not errorlevel 1 (
set "YACC=yacc -d"
goto :eof)
setlocal & endlocal
call :Clear_Error
call :Test_Path bison.exe
if not errorlevel 1 (
set "YACC=bison -d --yacc"
goto :eof)
setlocal & endlocal
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)
setlocal & endlocal
call :Clear_Error
call :Error_Print "Could not find Yacc to build the Jam grammar."
goto :eof
@@ -201,22 +235,24 @@ 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.
if "_%1_" == "__" (
call :Clear_Error
call :Test_Empty %1
if not errorlevel 1 (
call :Guess_Toolset
if not errorlevel 1 goto Setup_Toolset
) else (
call :Test_Option "%1"
if not errorlevel 1 (
call :Guess_Toolset
if not errorlevel 1 goto Setup_Toolset
) else (
setlocal & endlocal
set "BOOST_JAM_TOOLSET=%1"
shift
goto Setup_Toolset
)
if not errorlevel 1 ( goto Setup_Toolset ) else ( goto Finish )
)
if errorlevel 1 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
@@ -229,15 +265,18 @@ 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
if "_%1_" == "__" goto Config_Toolset
call :Test_Option "%1"
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 "_%BOOST_JAM_TOOLSET%_" == "_metrowerks_" goto Skip_METROWERKS
if NOT "_%CWFolder%_" == "__" (
set "BOOST_JAM_TOOLSET_ROOT=%CWFolder%\"
)
@@ -248,7 +287,7 @@ 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 "_%BOOST_JAM_TOOLSET%_" == "_msvc_" goto Skip_MSVC
if NOT "_%MSVCDir%_" == "__" (
set "BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\"
)
@@ -262,7 +301,7 @@ 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 "_%BOOST_JAM_TOOLSET%_" == "_vc7_" goto Skip_VC7
if NOT "_%VS71COMNTOOLS%_" == "__" (
set "BOOST_JAM_TOOLSET_ROOT=%VS71COMNTOOLS%..\..\VC7\"
)
@@ -277,7 +316,7 @@ 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 "_%BOOST_JAM_TOOLSET%_" == "_vc8_" goto Skip_VC8
if NOT "_%VS80COMNTOOLS%_" == "__" (
set "BOOST_JAM_TOOLSET_ROOT=%VS80COMNTOOLS%..\..\VC\"
)
@@ -292,7 +331,7 @@ 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 "_%BOOST_JAM_TOOLSET%_" == "_vc9_" goto Skip_VC9
if NOT "_%VS90COMNTOOLS%_" == "__" (
set "BOOST_JAM_TOOLSET_ROOT=%VS90COMNTOOLS%..\..\VC\"
)
@@ -307,7 +346,7 @@ set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
set "_known_=1"
:Skip_VC9
if NOT "_%BOOST_JAM_TOOLSET%_" == "_borland_" goto :Skip_BORLAND
if NOT "_%BOOST_JAM_TOOLSET%_" == "_borland_" goto Skip_BORLAND
if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
call :Test_Path bcc32.exe )
if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
@@ -323,35 +362,35 @@ 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
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
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
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
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%_" == "_mingw_" goto Skip_MINGW
if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%"
)
@@ -361,7 +400,7 @@ set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe"
set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe"
set "_known_=1"
:Skip_MINGW
setlocal & endlocal
call :Clear_Error
if "_%_known_%_" == "__" (
call :Error_Print "Unknown toolset: %BOOST_JAM_TOOLSET%"
)
@@ -379,29 +418,31 @@ set BJAM_SOURCES=%BJAM_SOURCES% hdrmacro.c headers.c jam.c jambase.c jamgram.c l
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 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/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=
if "_%1" == "_--update" (
set BJAM_UPDATE=update
)
if "_%2" == "_--update" (
set BJAM_UPDATE=update
)
if "_%3" == "_--update" (
set BJAM_UPDATE=update
)
if "_%4" == "_--update" (
set BJAM_UPDATE=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
rd /S /Q bootstrap
@@ -443,13 +484,23 @@ rename y.tab.h jamgram.h
@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=
@set args=%*
@echo OFF
:Set_Args
@if not "_%1_" == "__" (
set args=%args% %1
shift
goto 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

View File

@@ -10,10 +10,10 @@ else if $(MAC) { rule .path { return ":$(<:J=\:)" ; } }
else { rule .path { return "$(<:J=/)" ; } }
if $(VMS) { . = "_" ; }
else { . = "." ; }
./ ?= "" ;
./ ?= "" ;
# Info about what we are building.
_VERSION_ = 3 1 16 ;
_VERSION_ = 3 1 17 ;
NAME = boost-jam ;
VERSION = $(_VERSION_:J=$(.)) ;
RELEASE = 1 ;
@@ -25,6 +25,11 @@ if --debug in $(ARGV)
debug = true ;
}
if --profile in $(ARGV)
{
profile = true ;
}
# Attempt to generate and/or build the grammar?
if --grammar in $(ARGV)
{
@@ -33,7 +38,8 @@ if --grammar in $(ARGV)
# Do we need to add a default build type argument?
if ! ( --release in $(ARGV) ) &&
! ( --debug in $(ARGV) )
! ( --debug in $(ARGV) ) &&
! ( --profile in $(ARGV) )
{
ARGV += --release ;
}
@@ -126,6 +132,7 @@ toolset-root = [ MATCH --toolset-root=(.*) : $(ARGV) ] ;
# 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 ?= "" ;
@@ -136,7 +143,13 @@ rule toolset ( name command .type ? : opt.out + : opt.define * : flags * : linkl
tool.$(name)$(.type).linklibs ?= $(linklibs) ;
if ! $(name) in $(toolsets) { toolsets += $(name) ; }
}
rule opt ( type : yes-opt * : no-opt * ) { if $(type) in $(ARGV) { return $(yes-opt) ; } else { return $(no-opt) ; } }
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
@@ -171,6 +184,7 @@ 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
@@ -254,7 +268,7 @@ toolset msvc cl : /Fe /Fe /Fd /Fo : -D
: 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,-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)
@@ -278,7 +292,6 @@ toolset sun cc : "-o " : -D
:
[ opt --release : -s -fast -xO4 ]
[ opt --debug : -g ]
-xarch=generic
-I$(--python-include) -I$(--extra-include)
: -L$(--python-lib[1]) -l$(--python-lib[2]) ;
## Sun Workshop 6 C++ (old alias)
@@ -286,7 +299,6 @@ toolset sunpro cc : "-o " : -D
:
[ opt --release : -s -fast -xO4 ]
[ opt --debug : -g ]
-xarch=generic
-I$(--python-include) -I$(--extra-include)
: -L$(--python-lib[1]) -l$(--python-lib[2]) ;
## Compaq Alpha CXX
@@ -302,7 +314,7 @@ 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]) -bmaxdata:0x40000000 ;
: -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
@@ -341,13 +353,12 @@ toolset vmsdecc link .link : /EXECUTABLE= :
toolset = [ MATCH --toolset=(.*) : $(ARGV) ] ;
if ! $(toolset)
{
# For some reason, the following test does not catch
# empty 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 "###" ;
EXIT "###" ;
}
if ! $(toolset) in $(toolsets)
{
@@ -431,6 +442,10 @@ if $(debug)
{
locate-target = [ .path $(locate-target)$(.)debug ] ;
}
if $(profile)
{
locate-target = [ .path $(locate-target)$(.)profile ] ;
}
else
{
locate-target = [ .path $(locate-target) ] ;
@@ -449,8 +464,8 @@ jam.source =
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 modules/set.c
timestamp.c variable.c modules.c strings.c filesys.c
builtins.c pwd.c class.c native.c modules/set.c
modules/path.c modules/regex.c modules/property-set.c
modules/sequence.c modules/order.c
;
@@ -461,7 +476,7 @@ if $(NT)
else if $(OS2)
{
jam.source += execunix.c fileos2.c pathunix.c ;
}
}
else if $(VMS)
{
jam.source += execvms.c filevms.c pathvms.c ;
@@ -541,10 +556,10 @@ rule .clean
[DELETE] clean : $(<) ;
}
if $(NT) { actions piecemeal together existing [DELETE] {
del /F /Q $(>)
del /F /Q "$(>)"
} }
if $(UNIX) { actions piecemeal together existing [DELETE] {
rm -f $(>)
rm -f "$(>)"
} }
if $(VMS) { actions piecemeal together existing [DELETE] {
DELETE $(>[--2]:J=";*, ") $(>[-1]);*
@@ -566,10 +581,10 @@ rule .mkdir
if ! $(md<$(<)>) { [MKDIR] $(<) ; md<$(<)> = - ; }
}
if $(NT) { actions [MKDIR] {
md $(<)
md "$(<)"
} }
if $(UNIX) { actions [MKDIR] {
mkdir $(<)
mkdir "$(<)"
} }
if $(VMS) { actions [MKDIR] {
CREATE/DIR $(<J=", ")
@@ -614,16 +629,16 @@ rule .exe
return $(exe) ;
}
if ! $(--def[2]) { actions [COMPILE] {
"$(--cc)" $(--bin)$(<:D=) $(--dir)$(<:D)$(./) $(--out)$(<) $(--def)$(--defs) $(--flags) "$(--libs)" $(>)
"$(--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)" $(>)
"$(--cc)" "$(--bin)$(<:D=)" "$(--dir)$(<:D)$(./)" $(--out)$(<) "$(--def[1])$(--defs:J=$(--def[2]))$(--def[3])" "$(--flags)" "$(--libs)" "$(>)"
} }
if $(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)" $(>)
"$(--link)" "$(--link-bin)$(<:D=)" "$(--link-dir)$(<:D)$(./)" "$(--link-out)$(<)" "$(--link-def)$(--link-defs)" "$(--link-flags)" "$(--link-libs)" "$(>)"
} }
rule .link
@@ -634,10 +649,10 @@ rule .link
.clean $(<) ;
}
if $(NT) { actions [LINK] {
copy $(>) $(<)
copy "$(>)" "$(<)"
} }
if $(UNIX) { actions [LINK] {
ln -fs $(>) $(<)
ln -fs "$(>)" "$(<)"
} }
if $(VMS) { actions [LINK] {
COPY/REPLACE $(>) $(<)
@@ -649,14 +664,14 @@ rule .move
[MOVE] $(<) : $(>) ;
}
if $(NT) { actions [MOVE] {
del /f $(<)
rename $(>) $(<)
del /f "$(<)"
rename "$(>)" "$(<)"
} }
if $(UNIX) { actions [MOVE] {
mv -f $(>) $(<)
mv -f "$(>)" "$(<)"
} }
if $(VMS) { actions [MOVE] {
RENAME $(>) $(<)
RENAME "$(>)" "$(<)"
} }
# Generate the grammar tokens table, and the real yacc grammar.
@@ -672,7 +687,7 @@ rule .yyacc
actions [YYACC] {
$(--chmod+w)$(<[1])
$(--chmod+w)$(<[2])
"$(yyacc.exe)" $(<) $(>)
"$(yyacc.exe)" "$(<)" "$(>)"
}
if $(grammar)
{
@@ -715,18 +730,18 @@ rule .yacc
[YACC] $(<) : $(>) ;
}
if $(NT) { actions [YACC] {
"$(yacc)" $(>)
"$(yacc)" "$(>)"
if not errorlevel 1 (
del /f $(<[1])
rename y.tab$(<[1]:S) $(<[1])
del /f "$(<[1])"
rename y.tab$(<[1]:S) "$(<[1])"
del /f $(<[2])
rename y.tab$(<[2]:S) $(<[2])
rename y.tab$(<[2]:S) "$(<[2])"
) else set _error_ =
} }
if $(UNIX) { actions [YACC] {
if ` "$(yacc)" $(>) ` ; then
mv -f y.tab$(<[1]:S) $(<[1])
mv -f y.tab$(<[2]:S) $(<[2])
if ` "$(yacc)" "$(>)" ` ; then
mv -f y.tab$(<[1]:S) "$(<[1])"
mv -f y.tab$(<[2]:S) "$(<[2])"
else
exit 1
fi
@@ -758,7 +773,7 @@ rule .mkjambase
}
actions [MKJAMBASE] {
$(--chmod+w)$(<)
$(mkjambase.exe) $(<) $(>)
$(mkjambase.exe) "$(<)" "$(>)"
}
if $(debug)
{
@@ -770,7 +785,7 @@ rule .jam
{
$(>).exe = [ .exe $(>) : $(jam.source) ] ;
DEPENDS all : $($(>).exe) ;
if $(debug)
{
$(<).exe = $(<:S=$($(>).exe:S)) ;
@@ -929,14 +944,14 @@ rule .package ( dst-dir : src-files + )
src-files-actual += $(src-path) ;
}
}
local pack = ;
if $(NT) { pack = $(dst-dir).zip ; }
if $(UNIX) { 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)
{
@@ -944,11 +959,11 @@ rule .package ( dst-dir : src-files + )
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) ;
}

View File

@@ -127,15 +127,15 @@ case $BOOST_JAM_TOOLSET in
fi
BOOST_JAM_CC="gcc -DNT"
;;
gcc)
BOOST_JAM_CC=gcc
;;
darwin)
BOOST_JAM_CC=cc
;;
intel-linux)
if test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then
BOOST_JAM_TOOLSET_ROOT=/opt/intel/cc/9.0/
@@ -164,35 +164,35 @@ case $BOOST_JAM_TOOLSET in
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/
@@ -203,15 +203,15 @@ case $BOOST_JAM_TOOLSET in
fi
BOOST_JAM_CC=cc
;;
tru64cxx)
BOOST_JAM_CC=cc
;;
acc)
BOOST_JAM_CC="cc -Ae"
;;
cc)
if test -z "$CC" ; then CC=cc ; fi
BOOST_JAM_CC=$CC
@@ -219,11 +219,11 @@ case $BOOST_JAM_TOOLSET in
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"
;;
@@ -247,7 +247,7 @@ case $BOOST_JAM_TOOLSET in
mingw)
BJAM_SOURCES="${BJAM_SOURCES} execnt.c filent.c"
;;
*)
BJAM_SOURCES="${BJAM_SOURCES} execunix.c fileunix.c"
;;

View File

@@ -1,35 +1,35 @@
$ ! 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
@@ -95,11 +95,11 @@ $ link -
[.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

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* Copyright Vladiir Prus 2003. Distributed under the Boost */
/* 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) */
@@ -11,121 +11,131 @@
#include "hash.h"
static struct hash* classes = 0;
static void check_defined(LIST* class_names)
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);
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);
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;
struct import_base_data
{
char * base_name;
module_t * base_module;
module_t * class_module;
};
static void import_base_rule(void* r_, void* d_)
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];
int basename_lenght = strlen(d->base_name)+1;
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);
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);
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're importing 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);
/* 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)
/*
* 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));
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);
if ( base_module->rules )
hashenumerate( base_module->rules, import_base_rule, &d );
import_module( imported_modules(base_module), class );
import_module( imported_modules( base_module ), class );
}
char* make_class_module(LIST* xname, LIST* bases, FRAME* frame)
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;
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 ( !classes )
classes = hashinit( sizeof( char * ), "classes" );
if (hashcheck(classes, (HASHDATA**)&pp)) {
printf("Class %s already defined\n", xname->string);
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);
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);
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);
for ( ; bases; bases = bases->next )
import_base_rules( class_module, bases->string );
return name;
}

View File

@@ -14,30 +14,26 @@
* command.c - maintain lists of commands
*/
# include "jam.h"
#include "jam.h"
# include "lists.h"
# include "parse.h"
# include "variable.h"
# include "rules.h"
#include "lists.h"
#include "parse.h"
#include "variable.h"
#include "rules.h"
#include "command.h"
#include <limits.h>
#include <string.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_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 "%" */
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;
@@ -53,34 +49,34 @@ cmd_new(
do
{
BJAM_FREE(cmd->buf); /* free any buffer from previous iteration */
cmd->buf = (char*)BJAM_MALLOC_ATOMIC(max_line + 1);
if (cmd->buf == 0)
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 );
while ( ( allocated < 0 ) && ( max_line < INT_MAX / 2 ) );
if ( !no_limit )
{
/* Bail if the result won't fit in MAXLINE */
char *s = cmd->buf;
/* 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 don't free targets/sources/shell if bailing. */
/* We do not free targets/sources/shell if bailing. */
cmd_free( cmd );
return 0;
}
s += l;
if ( *s )
++s;
@@ -90,15 +86,15 @@ cmd_new(
return cmd;
}
/*
* cmd_free() - free a CMD
*/
void
cmd_free( CMD *cmd )
void cmd_free( CMD * cmd )
{
lol_free( &cmd->args );
list_free( cmd->shell );
lol_free( &cmd->args );
list_free( cmd->shell );
BJAM_FREE( cmd->buf );
BJAM_FREE( (char *)cmd );
BJAM_FREE( (char *)cmd );
}

View File

@@ -12,47 +12,50 @@
* 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'.
* 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
* 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
* 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_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
* 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 * 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) */
CMD * cmd_new
(
RULE * rule, /* rule (referenced) */
LIST * targets, /* $(<) (freed) */
LIST * sources, /* $(>) (freed) */
LIST * shell /* $(SHELL) (freed) */
);
void cmd_free( CMD *cmd );
void cmd_free( CMD * );
# define cmd_next( c ) ((c)->next)
#define cmd_next( c ) ( ( c )->next )

File diff suppressed because it is too large Load Diff

View File

@@ -50,33 +50,33 @@ 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 */
# 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 */
# 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_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 */
# 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

View File

@@ -4,45 +4,47 @@
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
*/
# include "jam.h"
#include "jam.h"
# include "hash.h"
#include "hash.h"
# include <time.h>
# include <assert.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 )
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);
if ( DEBUG_PROFILE ) profile_enter( rulename, frame );
return frame;
}
void profile_enter( char* rulename, profile_frame* frame )
void profile_enter( char * rulename, profile_frame * frame )
{
if ( DEBUG_PROFILE )
{
clock_t start = clock();
profile_info info, *p = &info;
profile_info info;
profile_info * p = &info;
if ( !rulename ) p = &profile_other;
if ( !profile_hash )
{
if ( rulename ) profile_hash = hashinit(sizeof(profile_info), "profile");
}
if ( !profile_hash && rulename )
profile_hash = hashinit( sizeof( profile_info ), "profile" );
info.name = rulename;
if ( rulename && hashenter( profile_hash, (HASHDATA **)&p ) )
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);
++p->num_entries;
++p->stack_count;
frame->info = p;
@@ -59,75 +61,72 @@ void profile_enter( char* rulename, profile_frame* frame )
}
}
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)
void profile_exit( profile_frame * frame )
{
if ( DEBUG_PROFILE )
{
/* cumulative time for this call */
/* 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)
* 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. */
/* Net time does not depend on presense of the same rule in call stack.
*/
frame->info->net += t - frame->subrules;
if (frame->caller)
if ( frame->caller )
{
/* caller's cumulative time must account for this overhead */
/* Caller's cumulative time must account for this overhead. */
frame->caller->overhead += frame->overhead;
frame->caller->subrules += t;
}
/* pop this stack frame */
/* Pop this stack frame. */
--frame->info->stack_count;
profile_stack = frame->caller;
}
}
static void dump_profile_entry(void* p_, void* ignored)
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));
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);
q /= ( p->num_entries ? p->num_entries : 1 );
cumulative /= CLOCKS_PER_SEC;
net /= CLOCKS_PER_SEC;
q /= CLOCKS_PER_SEC;
if (!ignored)
if ( !ignored )
{
profile_total.cumulative += p->net;
profile_total.memory += p->memory;
}
printf("%10d %12.6f %12.6f %12.8f %10d %10d %s\n",
p->num_entries,
cumulative,net,q,
p->memory, mem_each,
p->name);
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--");
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);
dump_profile_entry( &profile_other, 0 );
dump_profile_entry( &profile_total, (void *)1 );
}
}

View File

@@ -6,8 +6,9 @@
#ifndef BJAM_DEBUG_H
#define BJAM_DEBUG_H
# include "jam.h"
# include <time.h>
#include "jam.h"
#include <time.h>
struct profile_info
{
@@ -41,13 +42,13 @@ struct profile_frame
};
typedef struct profile_frame profile_frame;
profile_frame * profile_init( char* rulename, profile_frame* frame );
void profile_enter( char* rulename, profile_frame* 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_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)
#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

View File

@@ -5,7 +5,10 @@
*/
/*
* execcmd.h - execute a shell script
* execcmd.h - execute a shell script.
*
* Defines the interface to be implemented in platform specific implementation
* modules.
*
* 05/04/94 (seiwald) - async multiprocess interface
*/
@@ -23,18 +26,20 @@ typedef struct timing_info
time_t end;
} timing_info;
void execcmd(
char *string,
void (*func)( void *closure, int status, timing_info*, char *, char * ),
void *closure,
LIST *shell,
char *action,
char *target);
void exec_cmd
(
char * string,
void (* func)( void * closure, int status, timing_info *, char *, char * ),
void * closure,
LIST * shell,
char * action,
char * target
);
int execwait();
int exec_wait();
# define EXEC_CMD_OK 0
# define EXEC_CMD_FAIL 1
# define EXEC_CMD_INTR 2
#define EXEC_CMD_OK 0
#define EXEC_CMD_FAIL 1
#define EXEC_CMD_INTR 2
#endif

View File

@@ -4,12 +4,12 @@
* This file is part of Jam - see jam.c for Copyright information.
*/
# include "jam.h"
# include "lists.h"
# include "execcmd.h"
# include <errno.h>
#include "jam.h"
#include "lists.h"
#include "execcmd.h"
#include <errno.h>
# ifdef OS_MAC
#ifdef OS_MAC
/*
* execunix.c - execute a shell script on UNIX
@@ -17,11 +17,11 @@
* If $(JAMSHELL) is defined, uses that to formulate execvp().
* The default is:
*
* /bin/sh -c %
* /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
* 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.
@@ -29,41 +29,41 @@
* Don't just set JAMSHELL to /bin/sh - it won't work!
*
* External routines:
* execcmd() - launch an async command execution
* execwait() - wait and drive at most one execution completion
* 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
* 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
*/
/*
* execcmd() - launch an async command execution
* exec_cmd() - launch an async command execution.
*/
void
execcmd(
char *string,
void (*func)( void *closure, int status, timing_info*, char *, char * ),
void *closure,
LIST *shell )
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 );
printf( "%s", string );
(*func)( closure, EXEC_CMD_OK );
}
/*
* execwait() - wait and drive at most one execution completion
* exec_wait() - wait and drive at most one execution completion.
*/
int
execwait()
int exec_wait()
{
return 0;
return 0;
}
# endif /* OS_MAC */
#endif /* OS_MAC */

File diff suppressed because it is too large Load Diff

View File

@@ -5,29 +5,35 @@
* 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>
#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>
#include <wait.h>
#endif
# ifdef USE_EXECUNIX
# include <sys/times.h>
#ifdef USE_EXECUNIX
#include <sys/times.h>
#if defined(__APPLE__)
#define NO_VFORK
#endif
#ifdef NO_VFORK
#define vfork() fork()
#endif
# ifdef NO_VFORK
# define vfork() fork()
# endif
/*
* execunix.c - execute a shell script on UNIX/WinNT/OS2/AmigaOS
@@ -35,24 +41,23 @@
* 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 ]
* /bin/sh -c % [ on UNIX/AmigaOS ]
* cmd.exe /c % [ on OS2/WinNT ]
*
* Each word must be an individual element in a jam variable value.
*
* In $(JAMSHELL), % expands to the command string and ! expands to
* the slot number (starting at 1) for multiprocess (-j) invocations.
* If $(JAMSHELL) doesn't include a %, it is tacked on as the last
* argument.
* 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.
*
* Don't just set JAMSHELL to /bin/sh or cmd.exe - it won't work!
* Do not just set JAMSHELL to /bin/sh or cmd.exe - it will not work!
*
* External routines:
* execcmd() - launch an async command execution
* execwait() - wait and drive at most one execution completion
* 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
* onintr() - bump intr to note command interruption.
*
* 04/08/94 (seiwald) - Coherent/386 support added.
* 05/04/94 (seiwald) - async multiprocess interface
@@ -72,7 +77,7 @@ static struct tms old_time;
static struct
{
int pid; /* on win32, a real process handle */
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 */
@@ -92,446 +97,466 @@ static struct
* onintr() - bump intr to note command interruption
*/
void
onintr( int disp )
void onintr( int disp )
{
intr++;
printf( "...interrupted\n" );
++intr;
printf( "...interrupted\n" );
}
/*
* execcmd() - launch an async command execution
* exec_cmd() - launch an async command execution.
*/
void
execcmd(
char *string,
void (*func)( void *closure, int status, timing_info*, char *, char * ),
void *closure,
LIST *shell,
char *action,
char *target )
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], err[2];
int slot, len;
char *argv[ MAXARGC + 1 ]; /* +1 for NULL */
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. */
/* Find a slot in the running commands table for this one. */
for ( slot = 0; slot < MAXJOBS; ++slot )
if ( !cmdtab[ slot ].pid )
break;
for( slot = 0; slot < MAXJOBS; slot++ )
if( !cmdtab[ slot ].pid )
break;
if ( slot == MAXJOBS )
{
printf( "no slots for child!\n" );
exit( EXITBAD );
}
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;
/* Forumulate argv */
/* If shell was defined, be prepared for % and ! subs. */
/* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */
sprintf( jobno, "%d", slot + 1 );
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 pipe from child to parent */
if (pipe(out) < 0)
exit(EXITBAD);
fcntl(out[0], F_SETFL, O_NONBLOCK);
fcntl(out[1], F_SETFL, O_NONBLOCK);
if (pipe(err) < 0)
exit(EXITBAD);
fcntl(err[0], F_SETFL, O_NONBLOCK);
fcntl(err[1], F_SETFL, O_NONBLOCK);
/* 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)
{
close(out[0]);
close(err[0]);
dup2(out[1], STDOUT_FILENO);
if (globs.pipe_action == 0)
for ( i = 0; shell && i < MAXARGC; ++i, shell = list_next( shell ) )
{
switch ( shell->string[0] )
{
dup2(out[1], STDERR_FILENO);
close(err[1]);
case '%': argv[ i ] = string; ++gotpercent; break;
case '!': argv[ i ] = jobno; break;
default : argv[ i ] = shell->string;
}
else
dup2(err[1], STDERR_FILENO);
if ( DEBUG_EXECCMD )
printf( "argv[%d] = '%s'\n", i, argv[ i ] );
}
/* 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(cmdtab[slot].pid, cmdtab[slot].pid);
if ( !gotpercent )
argv[ i++ ] = string;
execvp( argv[0], argv );
_exit(127);
}
else if( cmdtab[slot].pid == -1 )
{
perror( "vfork" );
exit( EXITBAD );
}
argv[ i ] = 0;
}
else
{
argv[ 0 ] = "/bin/sh";
argv[ 1 ] = "-c";
argv[ 2 ] = string;
argv[ 3 ] = 0;
}
/* close write end of pipes */
close(out[1]);
close(err[1]);
/* Increment jobs running. */
++cmdsrunning;
/* 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) {
/* 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 );
fcntl( out[0], F_SETFL, O_NONBLOCK );
fcntl( out[1], F_SETFL, O_NONBLOCK );
if ( pipe( err ) < 0 )
exit( EXITBAD );
fcntl( err[0], F_SETFL, O_NONBLOCK );
fcntl( err[1], F_SETFL, O_NONBLOCK );
}
/* 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 );
close( err[1] );
}
else
dup2( err[1], STDERR_FILENO );
/* 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] );
/* 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 );
}
}
/* child writes stderr to err[1], parent reads from err[0] */
if (globs.pipe_action == 0)
/* Ensure enough room for rule and target name. */
if ( action && target )
{
len = strlen( action ) + 1;
if ( cmdtab[ slot ].action_length < len )
{
close(err[0]);
BJAM_FREE( cmdtab[ slot ].action );
cmdtab[ slot ].action = BJAM_MALLOC_ATOMIC( len );
cmdtab[ slot ].action_length = len;
}
else
strcpy( cmdtab[ slot ].action, action );
len = strlen( target ) + 1;
if ( cmdtab[ slot ].target_length < len )
{
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 );
}
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;
}
/* ensure enough room for rule and target name */
/* Save the operation for exec_wait() to find. */
cmdtab[ slot ].func = func;
cmdtab[ slot ].closure = closure;
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 execwait() to find. */
cmdtab[ slot ].func = func;
cmdtab[ slot ].closure = closure;
/* Wait until we're under the limit of concurrent commands. */
/* Don't trust globs.jobs alone. */
while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs )
if( !execwait() )
break;
/* 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
/* 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] and
* cmdtab[i].fd[s]
* s (stream) indexes:
* - cmdtab[ i ].stream[ s ]
* - cmdtab[ i ].buffer[ s ]
* - cmdtab[ i ].fd [ s ]
*/
int read_descriptor(int i, int s)
int read_descriptor( int i, int s )
{
int ret, len;
int ret;
int len;
char buffer[BUFSIZ];
while (0 < (ret = fread(buffer, sizeof(char), BUFSIZ-1, cmdtab[i].stream[s])))
while ( 0 < ( ret = fread( buffer, sizeof(char), BUFSIZ-1, cmdtab[ i ].stream[ s ] ) ) )
{
buffer[ret] = 0;
if (!cmdtab[i].buffer[s])
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);
/* 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);
/* 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]);
return feof(cmdtab[ i ].stream[ s ]);
}
void close_streams(int i, int 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;
/* 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)
void populate_file_descriptors( int * fmax, fd_set * fds)
{
int i, fd_max = 0;
struct tms buf;
clock_t current = times(&buf);
clock_t current = times( &buf );
select_timeout = globs.timeout;
/* compute max read file descriptor for use in select */
/* Compute max read file descriptor for use in select. */
FD_ZERO(fds);
for (i=0; i<globs.jobs; ++i)
for ( i = 0; i < globs.jobs; ++i )
{
if (0 < cmdtab[i].fd[OUT])
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);
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 ( globs.pipe_action != 0 )
{
if (0 < cmdtab[i].fd[ERR])
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);
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;
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;
if ( globs.timeout <= consumed )
{
killpg( cmdtab[ i ].pid, SIGKILL );
cmdtab[ i ].exit_reason = EXIT_TIMEOUT;
}
}
}
*fmax = fd_max;
}
/*
* execwait() - wait and drive at most one execution completion
* exec_wait() - wait and drive at most one execution completion.
*/
int
execwait()
int exec_wait()
{
int i, ret, fd_max;
int pid, status, finished;
int rstat;
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;
fd_set fds;
struct tms new_time;
/* Handle naive make1() which doesn't know if cmds are running. */
if( !cmdsrunning )
/* Handle naive make1() which does not know if commands are running. */
if ( !cmdsrunning )
return 0;
/* process children that signaled */
/* Process children that signaled. */
finished = 0;
while (!finished && cmdsrunning)
while ( !finished && cmdsrunning )
{
/* compute max read file descriptor for use in select */
populate_file_descriptors(&fd_max, &fds);
/* 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 */
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: io on a descriptor, a signal, or we time out */
ret = select(fd_max+1, &fds, 0, 0, &tv);
/* 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 io on a descriptor or a signal */
ret = select(fd_max+1, &fds, 0, 0, 0);
}
if (0 < ret)
else
{
for (i=0; i<globs.jobs; ++i)
/* 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, err = 0;
if (FD_ISSET(cmdtab[i].fd[OUT], &fds))
out = read_descriptor(i, OUT);
int out = 0;
int err = 0;
if ( FD_ISSET( cmdtab[ i ].fd[ OUT ], &fds ) )
out = read_descriptor( i, OUT );
if (FD_ISSET(cmdtab[i].fd[ERR], &fds))
err = read_descriptor(i, ERR);
if ( ( globs.pipe_action != 0 ) &&
( FD_ISSET( cmdtab[ i ].fd[ ERR ], &fds ) ) )
err = read_descriptor( i, ERR );
/* if feof on either descriptor, then we're done */
if (out || 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);
/* 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);
/* Reap the child and release resources. */
pid = waitpid( cmdtab[ i ].pid, &status, 0 );
if (pid == cmdtab[i].pid)
if ( pid == cmdtab[ i ].pid )
{
finished = 1;
pid = 0;
cmdtab[i].pid = 0;
cmdtab[ i ].pid = 0;
/* set reason for exit if not timed out */
if (WIFEXITED(status))
/* Set reason for exit if not timed out. */
if ( WIFEXITED( status ) )
{
if (0 == WEXITSTATUS(status))
cmdtab[i].exit_reason = EXIT_OK;
else
cmdtab[i].exit_reason = EXIT_FAIL;
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);
/* 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);
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 );
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 */
/* Drive the completion. */
--cmdsrunning;
if( intr )
if ( intr )
rstat = EXEC_CMD_INTR;
else if( status != 0 )
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] );
/* 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[ OUT ] );
cmdtab[ i ].buffer[ OUT ] = 0;
BJAM_FREE(cmdtab[i].buffer[ERR]);
cmdtab[i].buffer[ERR] = 0;
BJAM_FREE( cmdtab[ i ].buffer[ ERR ] );
cmdtab[ i ].buffer[ ERR ] = 0;
BJAM_FREE(cmdtab[i].command);
cmdtab[i].command = 0;
BJAM_FREE( cmdtab[ i ].command );
cmdtab[ i ].command = 0;
cmdtab[i].func = 0;
cmdtab[i].closure = 0;
cmdtab[i].start_time = 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);
printf( "unknown pid %d with errno = %d\n", pid, errno );
exit( EXITBAD );
}
}
}

View File

@@ -1,14 +1,14 @@
/*
/*
* 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 "jam.h"
#include "lists.h"
#include "execcmd.h"
# ifdef OS_VMS
#ifdef OS_VMS
#include <stdio.h>
#include <string.h>
@@ -20,150 +20,142 @@
#include <clidef.h>
/*
* execvms.c - execute a shell script, ala VMS
* 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 a single line, and shorter than WRTLEN (what we believe to
* be the maximum line length), we just system() it.
*
* If the command is multi-line, or longer than WRTLEN, we write the
* command block to a temp file, splitting long lines (using "-" at
* the end of the line to indicate contiuation), and then source that
* temp file. We use special logic to make sure we don't continue in
* the middle of a quoted string.
* 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) - don't put -'s between "'s
* 01/14/96 (seiwald) - do not put -'s between "'s
*/
#define WRTLEN 240
#define MIN( a, b ) ((a) < (b) ? (a) : (b))
#define MIN( a, b ) ((a) < (b) ? (a) : (b))
/* 1 for the @ and 4 for the .com */
char tempnambuf[ L_tmpnam + 1 + 4 ] = {0};
char tempnambuf[ L_tmpnam + 1 + 4 ] = { 0 };
void
execcmd(
char *string,
void (*func)( void *closure, int status, timing_info*, char *, char * ),
void *closure,
LIST *shell,
char *rule_name,
char *target )
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, *e, *p;
int rstat = EXEC_CMD_OK;
int status;
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 */
/* See if string is more than one line discounting leading/trailing white
* space.
*/
for ( s = string; *s && isspace( *s ); ++s );
for( s = string; *s && isspace( *s ); s++ )
;
e = p = strchr( s, '\n' );
e = p = strchr( s, '\n' );
while ( p && isspace( *p ) )
++p;
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;
/* If multi line or long, write to com file. */
/* Otherwise, exec directly. */
/* Create temp file invocation "@sys$scratch:tempfile.com". */
if ( !*tempnambuf )
{
tempnambuf[0] = '@';
(void)tmpnam( tempnambuf + 1 );
strcat( tempnambuf, ".com" );
}
if( p && *p || e - s > WRTLEN )
{
FILE *f;
/* Open tempfile. */
if ( !( f = fopen( tempnambuf + 1, "w" ) ) )
{
printf( "can't open command file\n" );
(*func)( closure, EXEC_CMD_FAIL );
return;
}
/* Create temp file invocation "@sys$scratch:tempfile.com" */
/* For each line of the string. */
while ( *string )
{
char * s = strchr( string, '\n' );
int len = s ? s + 1 - string : strlen( string );
if( !*tempnambuf )
{
tempnambuf[0] = '@';
(void)tmpnam( tempnambuf + 1 );
strcat( tempnambuf, ".com" );
}
/* Open tempfile */
fputc( '$', f );
if( !( f = fopen( tempnambuf + 1, "w" ) ) )
{
printf( "can't open command file\n" );
(*func)( closure, EXEC_CMD_FAIL );
return;
}
/* 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;
/* For each line of the string */
/* Look for matching "s. */
for ( ; q < qe; ++q )
if ( ( *q == '"' ) && ( quote = !quote ) )
qq = q;
while( *string )
{
char *s = strchr( string, '\n' );
int len = s ? s + 1 - string : strlen( string );
/* Back up to opening quote, if in one. */
if ( quote )
q = qq;
fputc( '$', f );
fwrite( string, ( q - string ), 1, f );
/* For each chunk of a line that needs to be split */
len -= ( q - string );
string = q;
while( len > 0 )
{
char *q = string;
char *qe = string + MIN( len, WRTLEN );
char *qq = q;
int quote = 0;
if ( len )
{
fputc( '-', f );
fputc( '\n', f );
}
}
}
/* Look for matching "'s */
fclose( f );
for( ; q < qe; q++ )
if( *q == '"' && ( quote = !quote ) )
qq = q;
status = system( tempnambuf ) & 0x07;
/* Back up to opening quote, if in one */
unlink( tempnambuf + 1 );
}
else
{
/* Execute single line command. Strip trailing newline before execing.
*/
if ( e ) *e = 0;
status = system( s ) & 0x07;
}
if( quote )
q = qq;
/* Fail for error or fatal error. OK on OK, warning or info exit. */
if ( ( status == 2 ) || ( status == 4 ) )
rstat = EXEC_CMD_FAIL;
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 );
(*func)( closure, rstat );
}
int
execwait()
int exec_wait()
{
return 0;
return 0;
}
# endif /* VMS */

File diff suppressed because it is too large Load Diff

View File

@@ -10,5 +10,5 @@
#include "lists.h"
LIST *var_expand( LIST *l, char *in, char *end, LOL *lol, int cancopyin );
LIST *var_expand( LIST *l, char *in, char *end, LOL *lol, int cancopyin );
void var_expand_unit_test();

View File

@@ -3,7 +3,7 @@
*
* 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.
@@ -26,9 +26,9 @@
*
* 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() - 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()
@@ -43,90 +43,84 @@
* 11/21/96 (peterk) - BEOS does not have Unix-style archives
*/
void CopyC2PStr(const char * cstr, StringPtr pstr)
void CopyC2PStr( char const * cstr, StringPtr pstr )
{
int len;
for (len = 0; *cstr && len<255; pstr[++len] = *cstr++)
;
pstr[0] = len;
int len;
for ( len = 0; *cstr && ( len < 255 ); pstr[ ++len ] = *cstr++ );
pstr[ 0 ] = len;
}
/*
* file_dirscan() - scan a directory for files
* file_dirscan() - scan a directory for files.
*/
void
file_dirscan(
char *dir,
scanback func,
void *closure )
void file_dirscan( char * dir, scanback func, void * closure )
{
PATHNAME f;
string filename[1];
string filename[ 1 ];
unsigned char fullPath[ 512 ];
FSSpec spec;
WDPBRec vol;
Str63 volName;
Str63 volName;
CInfoPBRec lastInfo;
int index = 1;
/* First enter directory itself */
/* First enter directory itself. */
memset( (char *)&f, '\0', sizeof( f ) );
f.f_dir.ptr = dir;
f.f_dir.len = strlen(dir);
if( DEBUG_BINDSCAN )
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 );
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 ) )
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) )
if ( FSMakeFSSpec( vol.ioWDVRefNum, vol.ioWDDirID, fullPath, &spec ) )
return;
if (!(lastInfo.dirInfo.ioFlAttrib & 0x10))
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;
// ioDrDirID must be reset each time.
if ( !( lastInfo.dirInfo.ioFlAttrib & 0x10 ) )
return;
/* ioDrDirID must be reset each time. */
spec.parID = lastInfo.dirInfo.ioDrDirID;
string_new( filename );
for( ;; )
for ( ; ; )
{
lastInfo.dirInfo.ioVRefNum = spec.vRefNum;
lastInfo.dirInfo.ioDrDirID = spec.parID;
lastInfo.dirInfo.ioNamePtr = fullPath;
lastInfo.dirInfo.ioVRefNum = spec.vRefNum;
lastInfo.dirInfo.ioDrDirID = spec.parID;
lastInfo.dirInfo.ioNamePtr = fullPath;
lastInfo.dirInfo.ioFDirIndex = index++;
if( PBGetCatInfoSync(&lastInfo) )
if ( PBGetCatInfoSync( &lastInfo ) )
return;
f.f_base.ptr = (char *)fullPath + 1;
f.f_base.len = *fullPath;
@@ -137,51 +131,40 @@ file_dirscan(
string_free( filename );
}
/*
* file_time() - get timestamp of file, if not done by file_dirscan()
* file_time() - get timestamp of file, if not done by file_dirscan().
*/
int
file_time(
char *filename,
time_t *time )
int file_time( char * filename, time_t * time )
{
struct stat statbuf;
struct stat statbuf;
if( stat( filename, &statbuf ) < 0 )
return -1;
if ( stat( filename, &statbuf ) < 0 )
return -1;
*time = statbuf.st_mtime;
return 0;
*time = statbuf.st_mtime;
return 0;
}
int file_is_file(char* filename)
int file_is_file( char * filename )
{
struct stat statbuf;
if( stat( filename, &statbuf ) < 0 )
return -1;
if (S_ISREG(statbuf.st_mode))
return 1;
else
return 0;
struct stat statbuf;
if ( stat( filename, &statbuf ) < 0 )
return -1;
return S_ISREG( statbuf.st_mode ) ? 1 : 0;
}
/*
* file_archscan() - scan an archive for files
* file_archscan() - scan an archive for files.
*/
void
file_archscan(
char *archive,
scanback func,
void *closure )
void file_archscan( char * archive, scanback func, void * closure )
{
}
# endif /* macintosh */

View File

@@ -25,7 +25,7 @@
# include <dir.h>
# include <dos.h>
# endif
# undef FILENAME /* cpp namespace collision */
# undef FILENAME /* cpp namespace collision */
# define _finddata_t ffblk
# endif
@@ -38,9 +38,9 @@
*
* 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() - 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()
@@ -56,14 +56,10 @@
* file_dirscan() - scan a directory for files
*/
void
file_dirscan(
char *dir,
scanback func,
void *closure )
void file_dirscan( char * dir, scanback func, void * closure )
{
PROFILE_ENTER(FILE_DIRSCAN);
PROFILE_ENTER( FILE_DIRSCAN );
file_info_t * d = 0;
dir = short_path_to_long_path( dir );
@@ -71,49 +67,64 @@ file_dirscan(
/* First enter directory itself */
d = file_query( dir );
if ( ! d || ! d->is_dir )
if ( !d || !d->is_dir )
{
PROFILE_EXIT(FILE_DIRSCAN);
PROFILE_EXIT( FILE_DIRSCAN );
return;
}
if ( ! d->files )
if ( !d->files )
{
PATHNAME f;
string filespec[1];
string filename[1];
string filespec[ 1 ];
string filename[ 1 ];
long handle;
int ret;
struct _finddata_t finfo[1];
LIST* files = L0;
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 = strlen(d->name);
f.f_dir.len = d_length;
/* Now enter contents of directory */
string_copy( filespec, *d->name ? d->name : "." );
string_append( filespec, "/*" );
/* 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 )
if ( DEBUG_BINDSCAN )
printf( "scan directory %s\n", dir );
# if defined(__BORLANDC__) && __BORLANDC__ < 0x550
#if defined(__BORLANDC__) && __BORLANDC__ < 0x550
if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) )
{
string_free( filespec );
PROFILE_EXIT(FILE_DIRSCAN);
PROFILE_EXIT( FILE_DIRSCAN );
return;
}
string_new( filename );
while( !ret )
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 );
@@ -132,15 +143,15 @@ file_dirscan(
# else
handle = _findfirst( filespec->value, finfo );
if( ret = ( handle < 0L ) )
if ( ret = ( handle < 0L ) )
{
string_free( filespec );
PROFILE_EXIT(FILE_DIRSCAN);
PROFILE_EXIT( FILE_DIRSCAN );
return;
}
string_new( filename );
while( !ret )
while ( !ret )
{
file_info_t * ff = 0;
@@ -150,7 +161,7 @@ file_dirscan(
string_truncate( filename, 0 );
path_build( &f, filename, 0 );
files = list_new( files, newstr(filename->value) );
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;
@@ -164,16 +175,16 @@ file_dirscan(
# 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] == '\\' )
if ( len == 1 && d->name[0] == '\\' )
(*func)( closure, d->name, 1 /* stat()'ed */, d->time );
else if( len == 3 && d->name[1] == ':' )
else if ( len == 3 && d->name[1] == ':' )
(*func)( closure, d->name, 1 /* stat()'ed */, d->time );
}
@@ -188,8 +199,8 @@ file_dirscan(
files = list_next( files );
}
}
PROFILE_EXIT(FILE_DIRSCAN);
PROFILE_EXIT( FILE_DIRSCAN );
}
file_info_t * file_query( char * filename )
@@ -199,7 +210,7 @@ file_info_t * file_query( char * filename )
{
struct stat statbuf;
if( stat( *filename ? filename : ".", &statbuf ) < 0 )
if ( stat( *filename ? filename : ".", &statbuf ) < 0 )
return 0;
ff->is_file = statbuf.st_mode & S_IFREG ? 1 : 0;
@@ -216,8 +227,8 @@ file_info_t * file_query( char * filename )
int
file_time(
char *filename,
time_t *time )
char *filename,
time_t *time )
{
file_info_t * ff = file_query( filename );
if ( !ff ) return -1;
@@ -239,19 +250,19 @@ int file_is_file(char* filename)
/* Straight from SunOS */
#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"
#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];
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
@@ -259,98 +270,98 @@ struct ar_hdr {
void
file_archscan(
char *archive,
scanback func,
void *closure )
char *archive,
scanback func,
void *closure )
{
struct ar_hdr ar_hdr;
char *string_table = 0;
char buf[ MAXJPATH ];
long offset;
int fd;
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 ( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 )
return;
if( read( fd, buf, SARMAG ) != SARMAG ||
strncmp( ARMAG, buf, SARMAG ) )
{
close( fd );
return;
}
if ( read( fd, buf, SARMAG ) != SARMAG ||
strncmp( ARMAG, buf, SARMAG ) )
{
close( fd );
return;
}
offset = SARMAG;
offset = SARMAG;
if( DEBUG_BINDSCAN )
printf( "scan archive %s\n", archive );
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;
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 );
sscanf( ar_hdr.ar_date, "%ld", &lar_date );
sscanf( ar_hdr.ar_size, "%ld", &lar_size );
lar_size = ( lar_size + 1 ) & ~1;
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
*/
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.
*/
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 );
}
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 */
/* strip trailing white-space, slashes, and backslashes */
while( endname-- > name )
if( !isspace(*endname) && *endname != '\\' && *endname != '/' )
break;
*++endname = 0;
while ( endname-- > name )
if ( !isspace(*endname) && ( *endname != '\\' ) && ( *endname != '/' ) )
break;
*++endname = 0;
/* strip leading directory names, an NT specialty */
/* strip leading directory names, an NT specialty */
if( c = strrchr( name, '/' ) )
name = c + 1;
if( c = strrchr( name, '\\' ) )
name = c + 1;
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 );
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 );
}
offset += SARHDR + lar_size;
lseek( fd, offset, 0 );
}
close( fd );
close( fd );
}
# endif /* NT */

View File

@@ -25,9 +25,9 @@
*
* 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() - 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()
@@ -45,10 +45,10 @@
*/
void
file_dirscan(
char *dir,
scanback func,
void *closure )
file_dirscan(
char *dir,
scanback func,
void *closure )
{
PATHNAME f;
string filespec[1];
@@ -68,10 +68,10 @@ file_dirscan(
/* 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 );
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, '/' );
@@ -79,20 +79,19 @@ file_dirscan(
/* Now enter contents of directory */
if( DEBUG_BINDSCAN )
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 ) )
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 );
@@ -100,7 +99,7 @@ file_dirscan(
path_build( &f, filename, 0 );
(*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 );
}
while( !_dos_findnext( finfo ) );
while ( !_dos_findnext( finfo ) );
string_free( filename );
}
}
@@ -111,27 +110,27 @@ file_dirscan(
int
file_time(
char *filename,
time_t *time )
char *filename,
time_t *time )
{
/* This is called on OS2, not NT. */
/* NT fills in the time in the dirscan. */
/* This is called on OS2, not NT. */
/* NT fills in the time in the dirscan. */
struct stat statbuf;
struct stat statbuf;
if( stat( filename, &statbuf ) < 0 )
return -1;
if ( stat( filename, &statbuf ) < 0 )
return -1;
*time = statbuf.st_mtime;
*time = statbuf.st_mtime;
return 0;
return 0;
}
void
file_archscan(
char *archive,
scanback func,
void *closure )
char *archive,
scanback func,
void *closure )
{
}

View File

@@ -5,57 +5,56 @@
# include "filesys.h"
# include "lists.h"
void
file_build1(
PATHNAME *f,
string* file)
void file_build1( PATHNAME * f, string * file )
{
if( DEBUG_SEARCH )
if ( DEBUG_SEARCH )
{
printf("build file: ");
if( f->f_root.len )
printf("build file: ");
if ( f->f_root.len )
printf( "root = '%.*s' ", f->f_root.len, f->f_root.ptr );
if( f->f_dir.len )
if ( f->f_dir.len )
printf( "dir = '%.*s' ", f->f_dir.len, f->f_dir.ptr );
if( f->f_base.len )
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.len )
{
if( f->f_grist.ptr[0] != '<' )
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] != '>' )
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_, *finfo = &finfo_;
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 );
finfo->is_file = 0;
finfo->is_dir = 0;
finfo->size = 0;
finfo->time = 0;
finfo->files = 0;
}
return finfo;
}

View File

@@ -11,7 +11,7 @@
*/
/*
* filesys.h - OS specific file routines
* filesys.h - OS specific file routines
*/
#ifndef FILESYS_DWA20011025_H
@@ -31,24 +31,29 @@ int file_time( char *filename, time_t *time );
void file_build1(PATHNAME *f, string* file) ;
int file_is_file(char* filename);
struct file_info_t {
char * name;
short is_file;
short is_dir;
unsigned long size;
time_t time;
LIST * files;
} ;
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;
};
file_info_t * file_info(char * filename);
file_info_t * file_query(char * filename);
/* 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.
*/
/* Marks a path/file to be removed when jam exits. */
void file_remove_atexit( const char * path );
#endif

View File

@@ -31,7 +31,7 @@
# if defined( OS_SEQUENT ) || \
defined( OS_DGUX ) || \
defined( OS_SCO ) || \
defined( OS_ISC )
defined( OS_ISC )
# define PORTAR 1
# endif
@@ -46,10 +46,10 @@
/* need unistd for rhapsody's proper lseek */
# include <sys/dir.h>
# include <unistd.h>
# define STRUCT_DIRENT struct direct
# define STRUCT_DIRENT struct direct
# else
# include <dirent.h>
# define STRUCT_DIRENT struct dirent
# define STRUCT_DIRENT struct dirent
# endif
# ifdef OS_COHERENT
@@ -58,21 +58,21 @@
# endif
# if defined( OS_MVS ) || \
defined( OS_INTERIX )
defined( OS_INTERIX )
#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"
#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"
struct ar_hdr /* archive file member header - printable ascii */
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 */
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
@@ -90,21 +90,21 @@ struct ar_hdr /* archive file member header - printable ascii */
# 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__
# define __AR_SMALL__
# define __AR_BIG__
# endif
# include <ar.h>
# endif
# 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() - 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()
@@ -119,25 +119,22 @@ struct ar_hdr /* archive file member header - printable ascii */
* 11/21/96 (peterk) - BEOS does not have Unix-style archives
*/
/*
* file_dirscan() - scan a directory for files
* file_dirscan() - scan a directory for files.
*/
void
file_dirscan(
char *dir,
scanback func,
void *closure )
void file_dirscan( char * dir, scanback func, void * closure )
{
PROFILE_ENTER(FILE_DIRSCAN);
PROFILE_ENTER( FILE_DIRSCAN );
file_info_t * d = 0;
d = file_query( dir );
if ( ! d || ! d->is_dir )
if ( !d || !d->is_dir )
{
PROFILE_EXIT(FILE_DIRSCAN);
PROFILE_EXIT( FILE_DIRSCAN );
return;
}
@@ -158,22 +155,20 @@ file_dirscan(
dir = *dir ? dir : ".";
/* Now enter contents of directory */
/* Now enter contents of directory. */
if( !( dd = opendir( dir ) ) )
if ( !( dd = opendir( dir ) ) )
{
PROFILE_EXIT(FILE_DIRSCAN);
PROFILE_EXIT( FILE_DIRSCAN );
return;
}
if( DEBUG_BINDSCAN )
if ( DEBUG_BINDSCAN )
printf( "scan directory %s\n", dir );
string_new( filename );
while( dirent = readdir( dd ) )
while ( ( dirent = readdir( dd ) ) )
{
file_info_t * ff = 0;
# ifdef old_sinix
/* Broken structure definition on sinix. */
f.f_base.ptr = dirent->d_name - 2;
@@ -191,14 +186,14 @@ file_dirscan(
string_free( filename );
closedir( dd );
d->files = files;
}
/* Special case / : enter it */
{
unsigned long len = strlen(d->name);
if( len == 1 && d->name[0] == '/' )
if ( ( len == 1 ) && ( d->name[0] == '/' ) )
(*func)( closure, d->name, 1 /* stat()'ed */, d->time );
}
@@ -213,10 +208,11 @@ file_dirscan(
files = list_next( files );
}
}
PROFILE_EXIT(FILE_DIRSCAN);
PROFILE_EXIT( FILE_DIRSCAN );
}
file_info_t * file_query( char * filename )
{
file_info_t * ff = file_info( filename );
@@ -224,7 +220,7 @@ file_info_t * file_query( char * filename )
{
struct stat statbuf;
if( stat( *filename ? filename : ".", &statbuf ) < 0 )
if ( stat( *filename ? filename : ".", &statbuf ) < 0 )
return 0;
ff->is_file = statbuf.st_mode & S_IFREG ? 1 : 0;
@@ -241,8 +237,8 @@ file_info_t * file_query( char * filename )
int
file_time(
char *filename,
time_t *time )
char *filename,
time_t *time )
{
file_info_t * ff = file_query( filename );
if ( !ff ) return -1;
@@ -262,109 +258,109 @@ int file_is_file(char* filename)
* file_archscan() - scan an archive for files
*/
# ifndef AIAMAG /* God-fearing UNIX */
# ifndef AIAMAG /* God-fearing UNIX */
# define SARFMAG 2
# define SARHDR sizeof( struct ar_hdr )
void
file_archscan(
char *archive,
scanback func,
void *closure )
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;
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 ( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 )
return;
if( read( fd, buf, SARMAG ) != SARMAG ||
strncmp( ARMAG, buf, SARMAG ) )
{
close( fd );
return;
}
if ( read( fd, buf, SARMAG ) != SARMAG ||
strncmp( ARMAG, buf, SARMAG ) )
{
close( fd );
return;
}
offset = SARMAG;
offset = SARMAG;
if( DEBUG_BINDSCAN )
printf( "scan archive %s\n", archive );
if ( DEBUG_BINDSCAN )
printf( "scan archive %s\n", archive );
while( read( fd, &ar_hdr, SARHDR ) == SARHDR
&& ! ( memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG )
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 )
/* 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, *dest;
) )
{
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) );
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 );
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
*/
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 = '/';
}
}
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';
c = lar_name - 1;
while ( ( *++c != ' ' ) && ( *c != '/' ) ) ;
*c = '\0';
if ( DEBUG_BINDSCAN )
printf( "archive name %s found\n", lar_name );
if ( DEBUG_BINDSCAN )
printf( "archive name %s found\n", lar_name );
sprintf( buf, "%s(%s)", archive, lar_name );
sprintf( buf, "%s(%s)", archive, lar_name );
(*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
(*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
offset += SARHDR + ( ( lar_size + 1 ) & ~1 );
lseek( fd, offset, 0 );
}
offset += SARHDR + ( ( lar_size + 1 ) & ~1 );
lseek( fd, offset, 0 );
}
if (string_table)
BJAM_FREE(string_table);
if (string_table)
BJAM_FREE(string_table);
close( fd );
close( fd );
# endif /* NO_AR */
@@ -385,28 +381,28 @@ static void file_archscan_small(
char buf[ MAXJPATH ];
long offset;
if( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ)
if ( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ)
return;
sscanf( fl_hdr.fl_fstmoff, "%ld", &offset );
if( DEBUG_BINDSCAN )
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 ) )
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 )
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 );
@@ -431,26 +427,26 @@ static void file_archscan_big(
char buf[ MAXJPATH ];
long long offset;
if( read( fd, (char *)&fl_hdr, FL_HSZ_BIG) != FL_HSZ_BIG)
if ( read( fd, (char *)&fl_hdr, FL_HSZ_BIG) != FL_HSZ_BIG)
return;
sscanf( fl_hdr.fl_fstmoff, "%lld", &offset );
if( DEBUG_BINDSCAN )
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 ) )
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;
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 );
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 )
if ( !lar_namlen )
continue;
ar_hdr.hdr._ar_name.ar_name[ lar_namlen ] = '\0';
@@ -469,10 +465,10 @@ void file_archscan(char *archive, scanback func, void *closure)
int fd;
char fl_magic[SAIAMAG];
if(( fd = open(archive, O_RDONLY, 0)) < 0)
if (( fd = open(archive, O_RDONLY, 0)) < 0)
return;
if(read( fd, fl_magic, SAIAMAG) != SAIAMAG
if (read( fd, fl_magic, SAIAMAG) != SAIAMAG
|| lseek(fd, 0, SEEK_SET) == -1)
{
close(fd);
@@ -491,7 +487,7 @@ void file_archscan(char *archive, scanback func, void *closure)
file_archscan_big(fd, archive, func, closure);
}
#endif
close( fd );
}

View File

@@ -21,9 +21,9 @@
*
* 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() - 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()
@@ -53,45 +53,45 @@
/* Supply missing prototypes for lbr$-routines*/
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif /* __cplusplus */
int lbr$set_module(
void **,
unsigned long *,
struct dsc$descriptor_s *,
unsigned short *,
void * );
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 * );
struct dsc$descriptor_s *,
void *,
void *,
void *,
void *,
void * );
int lbr$ini_control(
void **,
unsigned long *,
unsigned long *,
void * );
void **,
unsigned long *,
unsigned long *,
void * );
int lbr$get_index(
void **,
unsigned long *,
int (*func)( struct dsc$descriptor_s *, unsigned long *),
void * );
void **,
unsigned long *,
int (*func)( struct dsc$descriptor_s *, unsigned long *),
void * );
int lbr$close(
void ** );
void ** );
#ifdef __cplusplus
}
#endif /* __cplusplus */
static void
file_cvttime(
file_cvttime(
unsigned int *curtime,
time_t *unixtime )
{
@@ -108,10 +108,10 @@ file_cvttime(
# define min( a,b ) ((a)<(b)?(a):(b))
void
file_dirscan(
char *dir,
scanback func,
void *closure )
file_dirscan(
char *dir,
scanback func,
void *closure )
{
struct FAB xfab;
@@ -129,8 +129,8 @@ file_dirscan(
f.f_root.ptr = dir;
f.f_root.len = strlen( dir );
/* get the input file specification
*/
/* get the input file specification
*/
xnam = cc$rms_nam;
xnam.nam$l_esa = esa;
xnam.nam$b_ess = sizeof( esa ) - 1;
@@ -138,111 +138,111 @@ file_dirscan(
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$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_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 ( DEBUG_BINDSCAN )
printf( "scan directory %s\n", dir );
if ( !( status & 1 ) )
return;
return;
/* Add bogus directory for [000000] */
if( !strcmp( dir, "[000000]" ) )
if ( !strcmp( dir, "[000000]" ) )
{
(*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ );
(*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ );
}
/* Add bogus directory for [] */
if( !strcmp( dir, "[]" ) )
if ( !strcmp( dir, "[]" ) )
{
(*func)( closure, "[]", 1 /* time valid */, 1 /* old but true */ );
(*func)( closure, "[-]", 1 /* time valid */, 1 /* old but true */ );
(*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;
char *s;
time_t time;
/* "I think that might work" - eml */
/* "I think that might work" - eml */
sys$open( &xfab );
sys$close( &xfab );
sys$open( &xfab );
sys$close( &xfab );
file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time );
file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time );
filename[xnam.nam$b_rsl] = '\0';
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 */
/* 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;
}
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 );
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);
*/
/*
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 );
(*func)( closure, filename2->value, 1 /* time valid */, time );
}
string_free( filename2 );
}
}
int
file_time(
char *filename,
time_t *time )
char *filename,
time_t *time )
{
/* This should never be called, as all files are */
/* timestampped in file_dirscan() and file_archscan() */
return -1;
/* This should never be called, as all files are */
/* timestampped in file_dirscan() and file_archscan() */
return -1;
}
static char *VMS_archive = 0;
@@ -251,12 +251,12 @@ static void *VMS_closure;
static void *context;
static int
file_archmember(
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};
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
struct mhddef *mhd;
char filename[128];
@@ -271,19 +271,19 @@ file_archmember(
bufdsc.dsc$a_pointer = filename;
bufdsc.dsc$w_length = sizeof( filename );
status = lbr$set_module( &context, rfa, &bufdsc,
&bufdsc.dsc$w_length, NULL );
&bufdsc.dsc$w_length, NULL );
if ( !(status & 1) )
return ( 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;
for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; ++i, ++p )
filename[ i ] = *p;
filename[i] = '\0';
filename[ i ] = '\0';
sprintf( buf, "%s(%s.obj)", VMS_archive, filename );
@@ -292,14 +292,11 @@ file_archmember(
return ( 1 );
}
void
file_archscan(
char *archive,
scanback func,
void *closure )
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};
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
unsigned long lfunc = LBR$C_READ;
unsigned long typ = LBR$C_TYP_UNK;
@@ -313,14 +310,14 @@ file_archscan(
status = lbr$ini_control( &context, &lfunc, &typ, NULL );
if ( !( status & 1 ) )
return;
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;
return;
(void) lbr$get_index( &context, &index, file_archmember, NULL );
@@ -328,4 +325,3 @@ file_archscan(
}
# endif /* VMS */

View File

@@ -1,4 +1,4 @@
/*
/*
* 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)

View File

@@ -1,39 +1,37 @@
/*
/*
* 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
#define FRAMES_DWA20011021_H
# include "lists.h"
# include "modules.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;
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 */
/* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 1994 Christopher Seiwald. All rights reserved.
* Copyright 1994 Christopher Seiwald. All rights reserved.
*
* This file is part of Jam - see jam.c for Copyright information.
*/
@@ -9,149 +9,144 @@
*
* 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
*
* * 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
* glob() - match a string against a simple pattern
*
* Internal functions:
*
* globchars() - build a bitlist to check for character group match
* 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 */
# define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */
static void globchars( char * s, char * e, char * b );
static void globchars( char *s, char *e, char *b );
/*
* glob() - match a string against a simple pattern
* glob() - match a string against a simple pattern.
*/
int
glob(
register char *c,
register char *s )
int glob( char * c, char * s )
{
char bitlist[ BITLISTSIZE ];
char *here;
char bitlist[ BITLISTSIZE ];
char * here;
for( ;; )
switch( *c++ )
{
case '\0':
return *s ? -1 : 0;
for ( ; ; )
switch ( *c++ )
{
case '\0':
return *s ? -1 : 0;
case '?':
if( !*s++ )
return 1;
break;
case '?':
if ( !*s++ )
return 1;
break;
case '[':
/* scan for matching ] */
case '[':
/* Scan for matching ]. */
here = c;
do if( !*c++ )
return 1;
while( here == c || *c != ']' );
c++;
here = c;
do if ( !*c++ ) return 1;
while ( ( here == c ) || ( *c != ']' ) );
++c;
/* build character class bitlist */
/* Build character class bitlist. */
globchars( here, c, bitlist );
globchars( here, c, bitlist );
if( !CHECK_BIT( bitlist, *(unsigned char *)s ) )
return 1;
s++;
break;
if ( !CHECK_BIT( bitlist, *(unsigned char *)s ) )
return 1;
++s;
break;
case '*':
here = s;
case '*':
here = s;
while( *s )
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. */
/* 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;
while ( s != here )
{
int r;
/* A fast path for the last token in a pattern */
/* A fast path for the last token in a pattern. */
r = *c ? glob( c, s ) : *s ? -1 : 0;
r = *c ? glob( c, s ) : *s ? -1 : 0;
if ( !r )
return 0;
if ( r < 0 )
return 1;
--s;
}
break;
if( !r )
return 0;
else if( r < 0 )
return 1;
case '\\':
/* Force literal match of next char. */
if ( !*c || ( *s++ != *c++ ) )
return 1;
break;
--s;
}
break;
case '\\':
/* Force literal match of next char. */
if( !*c || *s++ != *c++ )
return 1;
break;
default:
if( *s++ != c[-1] )
return 1;
break;
}
default:
if ( *s++ != c[ -1 ] )
return 1;
break;
}
}
/*
* globchars() - build a bitlist to check for character group match
* globchars() - build a bitlist to check for character group match.
*/
static void
globchars(
char *s,
char *e,
char *b )
static void globchars( char * s, char * e, char * b )
{
int neg = 0;
int neg = 0;
memset( b, '\0', BITLISTSIZE );
memset( b, '\0', BITLISTSIZE );
if( *s == '^')
neg++, s++;
if ( *s == '^' )
{
++neg;
++s;
}
while( s < e )
{
int c;
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;
}
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 ) );
}
}
/* Don't include \0 in either $[chars] or $[^chars] */
if ( neg )
{
int i;
for ( i = 0; i < BITLISTSIZE; ++i )
b[ i ] ^= 0377;
}
b[0] &= 0376;
/* Do not include \0 in either $[chars] or $[^chars]. */
b[0] &= 0376;
}

View File

@@ -9,8 +9,8 @@
# include "compile.h"
# include <assert.h>
/*
* hash.c - simple in-memory hashing routines
/*
* hash.c - simple in-memory hashing routines
*
* External routines:
*
@@ -29,64 +29,68 @@
#define HASH_DEBUG_PROFILE 1
/* */
char *hashsccssid="@(#)hash.c 1.14 () 6/20/88";
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 */
} ;
struct hashhdr
{
struct item * next;
unsigned int keyval; /* for quick comparisons */
};
/* This structure overlays the one handed to hashenter(). */
/* It's actual size is given to hashinit(). */
/* This structure overlays the one handed to hashenter(). Its actual size is
* given to hashinit().
*/
struct hashdata {
char *key;
/* rest of user data */
} ;
struct hashdata
{
char * key;
/* rest of user data */
};
typedef struct item {
struct hashhdr hdr;
struct hashdata data;
typedef struct item
{
struct hashhdr hdr;
struct hashdata data;
} ITEM ;
# define MAX_LISTS 32
struct hash
struct hash
{
/*
* the hash table, just an array of item pointers
*/
struct {
int nel;
ITEM **base;
} tab;
/*
* 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 */
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 ] */
/*
* 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[] */
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;
struct {
int nel; /* total ITEMs held by this list */
char *base; /* base of ITEMs array */
} lists[ MAX_LISTS ];
} items;
char *name; /* just for hashstats() */
} ;
char * name; /* just for hashstats() */
};
static void hashrehash( struct hash *hp );
static void hashstat( struct hash *hp );
@@ -96,14 +100,40 @@ static void hash_mem_free(size_t datalen, void * data);
static void hash_mem_finalizer(char * key, struct hash * hp);
#endif
static unsigned int hash_keyval( const char * key_ )
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)
{
const unsigned char * key = (const unsigned char *)key_;
unsigned int keyval = *key;
while( *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 ))
@@ -116,14 +146,14 @@ static ITEM * hash_search(
struct hash *hp,
unsigned int keyval,
const char * keydata,
ITEM ** previous )
ITEM * * previous )
{
ITEM * i = *hash_bucket(hp,keyval);
ITEM * p = 0;
for ( ; i; i = i->hdr.next )
{
if( keyval == i->hdr.keyval &&
if ( ( keyval == i->hdr.keyval ) &&
!strcmp( i->data.key, keydata ) )
{
if (previous)
@@ -134,7 +164,7 @@ static ITEM * hash_search(
}
p = i;
}
return 0;
}
@@ -152,7 +182,7 @@ hash_free(
ITEM * i = 0;
ITEM * prev = 0;
unsigned int keyval = hash_keyval(data->key);
i = hash_search( hp, keyval, data->key, &prev );
if (i)
{
@@ -166,7 +196,7 @@ hash_free(
hp->items.free = i;
/* we have another item */
hp->items.more++;
return 1;
}
return 0;
@@ -178,32 +208,32 @@ hash_free(
int
hashitem(
register struct hash *hp,
HASHDATA **data,
int enter )
register struct hash *hp,
HASHDATA **data,
int enter )
{
register ITEM *i;
char *b = (*data)->key;
unsigned int keyval = hash_keyval(b);
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.more )
hashrehash( hp );
if( !enter && !hp->items.nel )
if ( !enter && !hp->items.nel )
{
#ifdef HASH_DEBUG_PROFILE
if ( DEBUG_PROFILE )
profile_exit( prof );
#endif
return 0;
return 0;
}
i = hash_search( hp, keyval, (*data)->key, 0 );
if (i)
{
@@ -214,10 +244,10 @@ hashitem(
return !0;
}
if( enter )
if ( enter )
{
ITEM **base = hash_bucket(hp,keyval);
ITEM * * base = hash_bucket(hp,keyval);
/* try to grab one from the free list */
if ( hp->items.free )
{
@@ -248,7 +278,7 @@ hashitem(
if ( DEBUG_PROFILE )
profile_exit( prof );
#endif
return 0;
return 0;
}
/*
@@ -257,57 +287,56 @@ hashitem(
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 );
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->items.lists[i].nel = hp->items.more;
hp->items.lists[i].base = hp->items.next;
hp->items.nel += hp->items.more;
hp->tab.nel = hp->items.nel * hp->bloat;
hp->tab.base = (ITEM **)hash_mem_alloc( hp->items.datalen, hp->tab.nel * sizeof(ITEM **) );
if ( hp->tab.base )
hash_mem_free( hp->items.datalen, (char *)hp->tab.base );
memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) );
hp->tab.nel = hp->items.nel * hp->bloat;
hp->tab.base = (ITEM **)hash_mem_alloc( hp->items.datalen, 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;
memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) );
for( ; nel--; next += hp->items.size )
{
register ITEM *i = (ITEM *)next;
ITEM **ip = hp->tab.base + i->hdr.keyval % hp->tab.nel;
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;
}
}
assert( i->data.key != 0 );
i->hdr.next = *ip;
*ip = i;
}
}
}
void hashenumerate( struct hash *hp, void (*f)(void*,void*), void* data )
void hashenumerate( struct hash * hp, void (* f)( void *, void * ), void * data )
{
int i;
for( i = 0; i <= hp->items.list; i++ )
for ( i = 0; i <= hp->items.list; ++i )
{
char *next = hp->items.lists[i].base;
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 )
for ( ; nel--; next += hp->items.size )
{
register ITEM *i = (ITEM *)next;
if ( i->data.key != 0 ) /* don't enumerate freed items */
f(&i->data, data);
ITEM * i = (ITEM *)next;
if ( i->data.key != 0 ) /* DO not enumerate freed items. */
f( &i->data, data );
}
}
}
@@ -321,25 +350,25 @@ void hashenumerate( struct hash *hp, void (*f)(void*,void*), void* data )
*/
struct hash *
hashinit(
int datalen,
char *name )
hashinit(
int datalen,
char *name )
{
struct hash *hp = (struct hash *)hash_mem_alloc( datalen, sizeof( *hp ) );
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->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;
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;
return hp;
}
/*
@@ -349,19 +378,19 @@ hashinit(
void
hashdone( struct hash *hp )
{
int i;
int i;
if( !hp )
return;
if ( !hp )
return;
if( DEBUG_MEM || DEBUG_PROFILE )
hashstat( hp );
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 );
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)
@@ -400,31 +429,31 @@ static void hash_mem_finalizer(char * key, struct hash * hp)
/* ---- */
static void
hashstat( struct hash *hp )
static void hashstat( struct hash * hp )
{
ITEM **tab = hp->tab.base;
int nel = hp->tab.nel;
int count = 0;
int sets = 0;
int run = ( tab[ nel - 1 ] != (ITEM *)0 );
int i, here;
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;
}
for ( i = nel; i > 0; --i )
{
if ( ( here = ( *tab++ != (ITEM *)0 ) ) )
count++;
if ( here && !run )
sets++;
run = here;
}
printf( "%s table: %d+%d+%d (%dK+%dK) items+table+hash, %f density\n",
hp->name,
count,
hp->items.nel,
hp->tab.nel,
hp->items.nel * hp->items.size / 1024,
hp->tab.nel * sizeof( ITEM ** ) / 1024,
(float)count / (float)sets );
printf( "%s table: %d+%d+%d (%dK+%ldK) items+table+hash, %f density\n",
hp->name,
count,
hp->items.nel,
hp->tab.nel,
hp->items.nel * hp->items.size / 1024,
hp->tab.nel * sizeof( ITEM ** ) / 1024,
(float)count / (float)sets );
}

View File

@@ -5,21 +5,21 @@
*/
/*
* hash.h - simple in-memory hashing routines
* 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);
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 )
#define hashenter( hp, data ) ( !hashitem( hp, data, !0 ) )
#define hashcheck( hp, data ) hashitem( hp, data, 0 )
#endif

View File

@@ -19,41 +19,41 @@
/*
* Craig W. McPheeters, Alias|Wavefront.
*
* hcache.c hcache.h - handle cacheing of #includes in source files
* 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
* 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:
* 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
* */
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 */
struct hcachedata *next;
} ;
*/
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 struct hash * hcachehash = 0;
static HCACHEDATA * hcachelist = 0;
static int queries = 0;
static int hits = 0;
@@ -62,294 +62,305 @@ static int hits = 0;
#define CACHE_RECORD_HEADER "header"
#define CACHE_RECORD_END "end"
/*
* Return the name of the header cache file. May return NULL.
* 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't change the cache file during
* header scanning.
* 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 * cache_name( void )
{
static char* name = 0;
if (!name) {
LIST *hcachevar = var_get("HCACHEFILE");
static char * name = 0;
if ( !name )
{
LIST * hcachevar = var_get( "HCACHEFILE" );
if (hcachevar) {
TARGET *t = bindtarget( hcachevar->string );
if ( hcachevar )
{
TARGET * t = bindtarget( hcachevar->string );
pushsettings( t->settings );
/* Don't expect cache file to be generated, so pass 0
as third argument to search. */
t->boundname = search( t->name, &t->time, 0 );
popsettings( t->settings );
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);
}
}
if ( hcachevar )
name = copystr( t->boundname );
}
}
return name;
}
/*
* Return the maximum age a cache entry can have before it is purged
* from the cache.
* Return the maximum age a cache entry can have before it is purged ftom the
* cache.
*/
static int
cache_maxage(void)
static int cache_maxage( void )
{
int age = 100;
LIST *var = var_get("HCACHEMAXAGE");
if (var) {
age = atoi(var->string);
if (age < 0)
age = 0;
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't contain
* ASCII 0. The returned value is as returned by newstr(), so it need
* not be freed.
* 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)
char * read_netstring( FILE * f )
{
unsigned long len;
static char* buf = NULL;
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 ( fscanf( f, " %9lu", &len ) != 1 )
return NULL;
if ( fgetc( f ) != (int)'\t' )
return NULL;
if (len > 1024 * 64)
return NULL; /* sanity check */
if ( len > 1024 * 64 )
return NULL; /* sanity check */
if (len > buf_len)
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;
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 ( !buf )
return NULL;
if (fread(buf, 1, len, f) != len)
return NULL;
if (fgetc(f) != (int)'\n')
return NULL;
if ( fread( buf, 1, len, f ) != len )
return NULL;
if ( fgetc( f ) != (int)'\n' )
return NULL;
buf[len] = 0;
return newstr(buf);
buf[ len ] = 0;
return newstr( buf );
}
/*
* Write a netstring.
*/
void
write_netstring(FILE* f, const char* s)
void write_netstring( FILE * f, char const * s )
{
if (!s)
s = "";
fprintf(f, "%lu\t%s\n", strlen(s), s);
if ( !s )
s = "";
fprintf( f, "%lu\t%s\n", strlen( s ), s );
}
void
hcache_init()
void hcache_init()
{
HCACHEDATA cachedata, *c;
FILE *f;
char *version;
int header_count = 0;
char* hcachename;
HCACHEDATA cachedata;
HCACHEDATA * c;
FILE * f;
char * version;
int header_count = 0;
char * hcachename;
hcachehash = hashinit (sizeof (HCACHEDATA), "hcache");
hcachehash = hashinit( sizeof( HCACHEDATA ), "hcache" );
if (! (hcachename = cache_name()))
return;
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;
}
if ( !( f = fopen( hcachename, "rb" ) ) )
return;
while (1)
version = read_netstring( f );
if ( !version || strcmp( version, CACHE_FILE_VERSION ) )
{
char* record_type;
char *time_str;
char *age_str;
char *includes_count_str;
char *hdrscan_count_str;
int i, 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++;
fclose( f );
return;
}
if (DEBUG_HEADER) {
printf("hcache read from file %s\n", hcachename);
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);
fclose( f );
}
void
hcache_done()
void hcache_done()
{
FILE *f;
HCACHEDATA *c;
int header_count = 0;
char* hcachename;
int maxage;
if (!hcachehash)
return;
FILE * f;
HCACHEDATA * c;
int header_count = 0;
char * hcachename;
int maxage;
if (! (hcachename = cache_name()))
return;
if ( !hcachehash )
return;
if (! (f = fopen (hcachename, "wb" )))
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);
/* 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];
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;
if ( maxage == 0 )
c->age = 0;
else if ( c->age > maxage )
continue;
sprintf(includes_count_str, "%lu", list_length(c->includes));
sprintf(hdrscan_count_str, "%lu", list_length(c->hdrscan));
sprintf(time_str, "%lu", c->time);
sprintf(age_str, "%lu", c->age);
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_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);
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);
}
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);
fclose ( f );
}
LIST *
hcache (TARGET *t, int rec, regexp *re[], LIST *hdrscan)
LIST * hcache( TARGET * t, int rec, regexp * re[], LIST * hdrscan )
{
HCACHEDATA cachedata, *c = &cachedata;
LIST *l = 0;
HCACHEDATA cachedata;
HCACHEDATA * c = &cachedata;
LIST * l = 0;
++queries;
@@ -357,58 +368,58 @@ hcache (TARGET *t, int rec, regexp *re[], LIST *hdrscan)
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);
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");
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;
}
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 (hashenter (hcachehash, (HASHDATA **)&c)) {
c->boundname = newstr (c->boundname);
c->next = hcachelist;
hcachelist = c;
}
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. */
/* 'c' points at the cache entry. Its out of date. */
l = headers1 (0, t->boundname, rec, re);

View File

@@ -27,11 +27,11 @@
* #include statements.
*
* we look for lines like "#define MACRO <....>" or '#define MACRO " "'
* in the target file. When found, we
* in the target file. When found, we
*
* we then phony up a rule invocation like:
*
* $(HDRRULE) <target> : <resolved included files> ;
* $(HDRRULE) <target> : <resolved included files> ;
*
* External routines:
* headers1() - scan a target for "#include MACRO" lines and try
@@ -42,21 +42,19 @@
*
* 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.
* so that headers() doesn't have to mock up a parse structure
* just to invoke a rule.
*/
static LIST *header_macros1( LIST *l, char *file, int rec, regexp *re[] );
/* this type is used to store a dictionary of file header macros */
typedef struct header_macro
{
char* symbol;
char* filename; /* we could maybe use a LIST here ?? */
char * symbol;
char * filename; /* we could maybe use a LIST here ?? */
} HEADER_MACRO;
static struct hash* header_macros_hash = 0;
static struct hash * header_macros_hash = 0;
/*
* headers() - scan a target for include files and call HDRRULE
@@ -68,9 +66,9 @@ void
macro_headers( TARGET *t )
{
static regexp *re = 0;
FILE *f;
char buf[ 1024 ];
FILE *f;
char buf[ 1024 ];
if ( DEBUG_HEADER )
printf( "macro header scan for %s\n", t->name );
@@ -80,23 +78,24 @@ macro_headers( TARGET *t )
if ( re == 0 )
{
re = regex_compile(
"^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*"
"^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*"
"[<\"]([^\">]*)[\">].*$" );
}
if( !( f = fopen( t->boundname, "r" ) ) )
if ( !( f = fopen( t->boundname, "r" ) ) )
return;
while( fgets( buf, sizeof( buf ), f ) )
while ( fgets( buf, sizeof( buf ), f ) )
{
HEADER_MACRO var, *v = &var;
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 );
@@ -121,19 +120,18 @@ macro_headers( TARGET *t )
}
char*
macro_header_get( const char* macro_name )
char * macro_header_get( const char * macro_name )
{
HEADER_MACRO var, *v = &var;
HEADER_MACRO var;
HEADER_MACRO * v = &var;
v->symbol = (char*)macro_name;
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;
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;
}

View File

@@ -27,11 +27,11 @@
/*
* headers.c - handle #includes in source files
*
* Using regular expressions provided as the variable $(HDRSCAN),
* 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> ;
*
* $(HDRRULE) <target> : <include files> ;
*
* External routines:
* headers() - scan a target for include files and call HDRRULE
@@ -41,8 +41,8 @@
*
* 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.
* so that headers() doesn't have to mock up a parse structure
* just to invoke a rule.
*/
#ifndef OPT_HEADER_CACHE_EXT
@@ -58,31 +58,32 @@ static LIST *headers1( LIST *l, char *file, int rec, regexp *re[]);
void
headers( TARGET *t )
{
LIST *hdrscan;
LIST *hdrrule;
LIST *headlist = 0;
regexp *re[ MAXINC ];
int rec = 0;
if( !( hdrscan = var_get( "HDRSCAN" ) ) ||
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 )
if ( DEBUG_HEADER )
printf( "header scan %s\n", t->name );
/* Compile all regular expressions in HDRSCAN */
while( rec < MAXINC && hdrscan )
while ( ( rec < MAXINC ) && hdrscan )
{
re[rec++] = regex_compile( hdrscan->string );
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 frame[1];
frame_init( frame );
lol_add( frame->args, list_new( L0, t->name ) );
#ifdef OPT_HEADER_CACHE_EXT
@@ -91,7 +92,7 @@ headers( TARGET *t )
lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) );
#endif
if( lol_get( frame->args, 1 ) )
if ( lol_get( frame->args, 1 ) )
{
/* The third argument to HDRRULE is the bound name of
* $(<) */
@@ -100,14 +101,14 @@ headers( TARGET *t )
list_free( evaluate_rule( hdrrule->string, frame ) );
}
/* Clean up */
/* Clean up. */
frame_free( frame );
}
}
/*
* headers1() - using regexp, scan a file and build include LIST
* headers1() - using regexp, scan a file and build include LIST.
*/
#ifdef OPT_HEADER_CACHE_EXT
@@ -115,91 +116,88 @@ LIST *
#else
static LIST *
#endif
headers1(
LIST *l,
char *file,
int rec,
regexp *re[] )
headers1(
LIST * l,
char * file,
int rec,
regexp * re[] )
{
FILE *f;
char buf[ 1024 ];
int i;
static regexp *re_macros = 0;
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");
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 )
/* 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' ) )
{
re_macros = regex_compile(
"^[ ]*#[ ]*include[ ]*([A-Za-z][A-Za-z0-9_]*).*$" );
buf[ size - 1 ] = '\0';
--size;
}
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'))
for ( i = 0; i < rec; ++i )
if ( regexec( re[i], buf ) && re[i]->startp[1] )
{
buf[size-1] = '\0';
--size;
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] ) );
}
for( i = 0; i < rec; i++ )
if( regexec( re[i], buf ) && re[i]->startp[1] )
{
re[i]->endp[1][0] = '\0';
/* special treatment for #include MACRO */
if ( regexec( re_macros, buf ) && re_macros->startp[1] )
{
char* header_filename;
if( DEBUG_HEADER )
printf( "header found: %s\n", re[i]->startp[1] );
re_macros->endp[1][0] = '\0';
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 )
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 );
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" );
}
}
}
else
{
if ( DEBUG_HEADER )
printf( " ignored !!\n" );
}
}
}
fclose( f );
fclose( f );
return l;
return l;
}
void
regerror( char *s )
void regerror( char * s )
{
printf( "re error %s\n", s );
printf( "re error %s\n", s );
}

View File

@@ -1,12 +1,12 @@
/*
* /+\
* +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
* +\ 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
* freely, as long as this copyright notice is retained and modifications
* are clearly marked.
*
* ALL WARRANTIES ARE HEREBY DISCLAIMED.
@@ -27,11 +27,11 @@
*
* The top half of the code is structured such:
*
* jam
* / | \
* jam
* / | \
* +---+ | \
* / | \
* jamgram option \
* / | \
* jamgram option \
* / | \ \
* / | \ \
* / | \ |
@@ -69,32 +69,32 @@
*
* 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
* 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
* 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.
@@ -103,132 +103,122 @@
* 01/10/01 (seiwald) - pathsys.h split from filesys.h
*/
# include "jam.h"
# include "option.h"
# include "patchlevel.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"
#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;
#ifdef OS_MAC
#include <QuickDraw.h>
#endif
# ifndef use_environ
# define use_environ environ
# if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT )
extern char **environ;
# endif
# endif
/* And UNIX for this. */
#ifdef unix
#include <sys/utsname.h>
#include <signal.h>
#endif
# if YYDEBUG != 0
extern int yydebug;
# 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 )
#if defined( USE_EXECNT )
extern void execnt_unit_test();
execnt_unit_test();
# endif
#endif
string_unit_test();
var_expand_unit_test();
}
#endif
#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_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 );
#endif
int main( int argc, char **argv, char **arg_environ )
int main( int argc, char * * argv, char * * arg_environ )
{
int n;
char *s;
struct option optv[N_OPTS];
const char *all = "all";
int anyhow = 0;
int status;
int arg_c = argc;
char ** arg_v = argv;
const char *progname = argv[0];
int n;
char * s;
struct option optv[N_OPTS];
char const * all = "all";
int anyhow = 0;
int status;
int arg_c = argc;
char * * arg_v = argv;
char const * progname = argv[0];
BJAM_MEM_INIT();
@@ -236,9 +226,10 @@ int main( int argc, char **argv, char **arg_environ )
InitGraf(&qd.thePort);
# endif
argc--, argv++;
--argc;
++argv;
if( getoptions( argc, argv, "-:l:d:j:p:f:gs:t:ano:qv", optv ) < 0 )
if ( getoptions( argc, argv, "-:l:d:j:p:f:gs:t:ano:qv", optv ) < 0 )
{
printf( "\nusage: %s [ options ] targets...\n\n", progname );
@@ -261,291 +252,276 @@ int main( int argc, char **argv, char **arg_environ )
}
/* Version info. */
if( ( s = getoptval( optv, 'v', 0 ) ) )
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-2005 Rene Rivera.\n" );
printf( " Copyright 2003-2005 Vladimir Prus.\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 ) ) )
/* Pick up interesting options. */
if ( ( s = getoptval( optv, 'n', 0 ) ) )
globs.noexec++, globs.debug[2] = 1;
if( ( s = getoptval( optv, 'p', 0 ) ) )
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)
/* 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);
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, 'q', 0 ) ) )
globs.quitquick = 1;
if( ( s = getoptval( optv, 'a', 0 ) ) )
if ( ( s = getoptval( optv, 'a', 0 ) ) )
anyhow++;
if( ( s = getoptval( optv, 'j', 0 ) ) )
if ( ( s = getoptval( optv, 'j', 0 ) ) )
globs.jobs = atoi( s );
if( ( s = getoptval( optv, 'g', 0 ) ) )
if ( ( s = getoptval( optv, 'g', 0 ) ) )
globs.newestfirst = 1;
if( ( s = getoptval( optv, 'l', 0 ) ) )
if ( ( s = getoptval( optv, 'l', 0 ) ) )
globs.timeout = atoi( s );
/* Turn on/off debugging */
for( n = 0; s = getoptval( optv, 'd', n ); n++ )
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++ )
if ( !n )
for ( i = 0; i < DEBUG_MAX; ++i )
globs.debug[i] = 0;
i = atoi( s );
if( i < 0 || i >= DEBUG_MAX )
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 == '+' )
/* n turns on levels 1-n. */
/* +n turns on level n. */
if ( *s == '+' )
globs.debug[i] = 1;
else while( i )
else while ( i )
globs.debug[i--] = 1;
}
{ PROFILE_ENTER(MAIN);
#ifdef HAVE_PYTHON
{
PROFILE_ENTER(MAIN_PYTHON);
Py_Initialize();
PROFILE_ENTER( MAIN );
#ifdef HAVE_PYTHON
{
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."},
{NULL, NULL, 0, NULL}
};
Py_InitModule("bjam", BjamMethods);
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."},
{NULL, NULL, 0, NULL}
};
Py_InitModule( "bjam", BjamMethods );
}
PROFILE_EXIT( MAIN_PYTHON );
}
PROFILE_EXIT(MAIN_PYTHON);
}
#endif
#endif
#ifndef NDEBUG
run_unit_tests();
run_unit_tests();
#endif
#if YYDEBUG != 0
if ( DEBUG_PARSE )
yydebug = 1;
if ( DEBUG_PARSE )
yydebug = 1;
#endif
/* Set JAMDATE first */
/* Set JAMDATE. */
var_set( "JAMDATE", list_new( L0, outf_time(time(0)) ), VAR_SET );
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 );
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 );
/* And JAMUNAME */
# ifdef unix
{
struct utsname u;
if( uname( &u ) >= 0 )
/* Set JAMUNAME. */
#ifdef unix
{
var_set( "JAMUNAME",
list_new(
struct utsname u;
if ( uname( &u ) >= 0 )
{
var_set( "JAMUNAME",
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 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 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 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]);
}
}
/* 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++ )
touchtarget( 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++;
}
/* Now make target */
{
PROFILE_ENTER(MAIN_MAKE);
LIST* targets = targets_to_update();
if ( !targets )
{
status |= make( 1, &all, anyhow );
}
else
{
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;
list_new(
list_new( L0,
newstr( u.sysname ) ),
newstr( u.nodename ) ),
newstr( u.release ) ),
newstr( u.version ) ),
newstr( u.machine ) ), VAR_SET );
}
status |= make( targets_count, targets2, anyhow );
free(targets);
}
PROFILE_EXIT(MAIN_MAKE);
#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 ] );
}
}
/* 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;
}
/* Now make target. */
{
PROFILE_ENTER( MAIN_MAKE );
LIST * targets = targets_to_update();
if ( !targets )
{
status |= make( 1, &all, anyhow );
}
else
{
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 );
}
PROFILE_EXIT( MAIN_MAKE );
}
PROFILE_EXIT( MAIN );
}
PROFILE_EXIT(MAIN); }
if ( DEBUG_PROFILE )
profile_dump();
/* Widely scattered cleanup */
/* Widely scattered cleanup. */
var_done();
file_done();
donerules();
donestamps();
donestr();
rules_done();
stamps_done();
str_done();
/* close cmdout */
if( globs.cmdout )
/* Close cmdout. */
if ( globs.cmdout )
fclose( globs.cmdout );
#ifdef HAVE_PYTHON
Py_Finalize();
#endif
BJAM_MEM_CLOSE();
BJAM_MEM_CLOSE();
return status ? EXITBAD : EXITOK;
}

View File

@@ -49,80 +49,81 @@
* VMS, OPENVMS
*/
# ifdef VMS
#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>
#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
#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
/* This may be inaccurate. */
#ifndef __DECC
#define OSPLAT "OSPLAT=VAX"
#endif
# endif
#endif
/*
* Windows NT
*/
# ifdef NT
#ifdef NT
# include <fcntl.h>
# include <stdlib.h>
# include <stdio.h>
# include <ctype.h>
# include <malloc.h>
# ifndef __MWERKS__
# include <memory.h>
#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>
#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 problem in "execnt.c". */
# define MAXLINE (maxline()) /* longest 'together' actions */
# define USE_EXECNT
# define USE_PATHUNIX
# define PATH_DELIM '\\'
# define DOWNSHIFT_PATHS
#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 */
/* AS400 cross-compile from NT. */
# ifdef AS400
# undef OSMINOR
# undef OSMAJOR
# define OSMAJOR "AS400=true"
# define OSMINOR "OS=AS400"
# define OS_AS400
# endif
#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
#ifdef __MSL__
#undef HAVE_POPEN
#endif
# endif
@@ -131,435 +132,440 @@
* Windows MingW32
*/
# ifdef MINGW
#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>
#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
#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
#endif
/*
* OS2
*/
# ifdef __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>
#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
#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
#ifdef __EMX__
#define USE_FILEUNIX
#endif
# endif
#endif
/*
* Macintosh MPW
*/
# ifdef macintosh
#ifdef macintosh
# include <time.h>
# include <stdlib.h>
# include <string.h>
# include <stdio.h>
#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 ','
#define OSMAJOR "MAC=true"
#define OSMINOR "OS=MAC"
#define OS_MAC
#define SPLITPATH ','
# endif
#endif
/*
* God fearing UNIX
* God fearing UNIX.
*/
# ifndef OSMINOR
#ifndef OSMINOR
# define OSMAJOR "UNIX=true"
# define USE_EXECUNIX
# define USE_FILEUNIX
# define USE_PATHUNIX
# define PATH_DELIM '/'
#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
#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>
#include <sys/types.h>
#include <sys/stat.h>
# ifndef OS_MPEIX
# include <sys/file.h>
# endif
#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 <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <string.h>
#include <time.h>
# ifndef OS_QNX
# include <memory.h>
# endif
#ifndef OS_QNX
#include <memory.h>
#endif
# ifndef OS_ULTRIX
# include <stdlib.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
#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
#endif
/*
* OSPLAT definitions - suppressed when it's a one-of-a-kind
/*
* 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( _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( _ALPHA_ ) || \
defined( __alpha__ )
#define OSPLAT "OSPLAT=AXP"
#endif
# if defined( _i386_ ) || \
defined( __i386__ ) || \
defined( _M_IX86 )
# define OSPLAT "OSPLAT=X86"
# endif
#if 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( __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( __x86_64__ ) || \
defined( __amd64__ ) || \
defined( _M_AMD64 )
#define OSPLAT "OSPLAT=X86_64"
#endif
# ifdef __sparc__
# define OSPLAT "OSPLAT=SPARC"
# endif
#ifdef __sparc__
#define OSPLAT "OSPLAT=SPARC"
#endif
# ifdef __mips__
# define OSPLAT "OSPLAT=MIPS"
# endif
#ifdef __mips__
#define OSPLAT "OSPLAT=MIPS"
#endif
# ifdef __arm__
# define OSPLAT "OSPLAT=ARM"
# endif
#ifdef __arm__
#define OSPLAT "OSPLAT=ARM"
#endif
# ifdef __s390__
# define OSPLAT "OSPLAT=390"
# endif
#ifdef __s390__
#define OSPLAT "OSPLAT=390"
#endif
# ifdef __hppa
# define OSPLAT "OSPLAT=PARISC"
# endif
#ifdef __hppa
#define OSPLAT "OSPLAT=PARISC"
#endif
# ifndef OSPLAT
# define OSPLAT ""
# endif
#ifndef OSPLAT
#define OSPLAT ""
#endif
/*
* Jam implementation misc.
*/
# ifndef MAXLINE
# define MAXLINE 102400 /* longest 'together' actions' */
# endif
#ifndef MAXLINE
#define MAXLINE 102400 /* longest 'together' actions' */
#endif
# ifndef EXITOK
# define EXITOK 0
# define EXITBAD 1
# endif
#ifndef EXITOK
#define EXITOK 0
#define EXITBAD 1
#endif
# ifndef SPLITPATH
# define SPLITPATH ':'
# endif
#ifndef SPLITPATH
#define SPLITPATH ':'
#endif
/* You probably don't need to muck with these. */
/* You probably do not need to muck with these. */
# define MAXSYM 1024 /* longest symbol in the environment */
# define MAXJPATH 1024 /* longest filename */
#define MAXSYM 1024 /* longest symbol in the environment */
#define MAXJPATH 1024 /* longest filename */
# define MAXJOBS 64 /* silently enforce -j limit */
# define MAXARGC 32 /* words in $(JAMSHELL) */
#define MAXJOBS 64 /* silently enforced -j limit */
#define MAXARGC 32 /* words in $(JAMSHELL) */
/* Jam private definitions below. */
# define DEBUG_MAX 14
#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 */
} ;
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_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_EXECCMD ( globs.debug[ 4 ] ) /* show execcmds()'s work */
# define DEBUG_COMPILE ( globs.debug[ 5 ] ) /* show rule invocations */
#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_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_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() */
#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"

View File

@@ -34,7 +34,7 @@ char *jambase[] = {
"{\n",
"if $(.bootstrap-file)\n",
"{\n",
"EXIT \"Error: Illegal attempt to re-bootstrap the build system by invoking\" ;\n",
"ECHO \"Error: Illegal attempt to re-bootstrap the build system by invoking\" ;\n",
"ECHO ;\n",
"ECHO \" 'boost-build\" $(dir) \";'\" ;\n",
"ECHO ;\n",
@@ -42,8 +42,7 @@ char *jambase[] = {
"}\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 =\n",
"[ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;\n",
"local bootstrap-file = [ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;\n",
".bootstrap-file = $(bootstrap-file[1]) ;\n",
"if ! $(.bootstrap-file)\n",
"{\n",
@@ -60,13 +59,13 @@ char *jambase[] = {
"}\n",
"if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n",
"{\n",
"ECHO \"notice: loading Boost.Build from\" \n",
"ECHO \"notice: loading Boost.Build from\"\n",
"[ NORMALIZE_PATH $(.bootstrap-file:D) ] ;\n",
"}\n",
"include $(.bootstrap-file) ;\n",
"}\n",
"if [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]\n",
"|| $(BOOST_ROOT) # A temporary measure so Jam works with Boost.Build v1\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 boost-build-files =\n",
@@ -88,9 +87,9 @@ char *jambase[] = {
"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",
"if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n",
"{\n",
"ECHO \"notice: found boost-build.jam at\" \n",
"ECHO \"notice: found boost-build.jam at\"\n",
"[ NORMALIZE_PATH $(.boost-build-file) ] ;\n",
"}\n",
"include $(.boost-build-file) ;\n",
@@ -217,7 +216,7 @@ char *jambase[] = {
"C++FLAGS ?= $(CCFLAGS) ;\n",
"LINK ?= $(CC) ;\n",
"LINKFLAGS ?= $(CCFLAGS) ;\n",
"LINKLIBS ?= \n",
"LINKLIBS ?=\n",
"\\\"$(VISUALC16)\\\\lib\\\\mlibce.lib\\\"\n",
"\\\"$(VISUALC16)\\\\lib\\\\oldnames.lib\\\"\n",
";\n",
@@ -478,7 +477,7 @@ char *jambase[] = {
"SUFEXE ?= .exe ;\n",
"SUFLIB ?= .olb ;\n",
"SUFOBJ ?= .obj ;\n",
"switch $(OS) \n",
"switch $(OS)\n",
"{\n",
"case OPENVMS : CCFLAGS ?= /stand=vaxc ;\n",
"case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;\n",
@@ -495,16 +494,16 @@ char *jambase[] = {
"MACLIBS ?=\n",
"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib\"\n",
"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib\" ;\n",
"MPWLIBS ?= \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",
"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",
"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 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",
@@ -515,15 +514,15 @@ char *jambase[] = {
"DOTDOT ?= \"::\" ;\n",
"HDRS ?= $(MACHDRS) $(MPWHDRS) ;\n",
"LINK ?= mwlinkppc ;\n",
"LINKFLAGS ?= -mpwtool -warn ; \n",
"LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ; \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",
"STDHDRS ?= ;\n",
"SUFLIB ?= .lib ;\n",
"SUFOBJ ?= .o ;\n",
"}\n",
@@ -543,7 +542,7 @@ char *jambase[] = {
"NOARSCAN ?= true ;\n",
"STDHDRS ?= /boot/develop/headers/posix ;\n",
"}\n",
"else if $(OS) = BEOS \n",
"else if $(OS) = BEOS\n",
"{\n",
"BINDIR ?= /boot/apps ;\n",
"CC ?= gcc ;\n",
@@ -564,7 +563,7 @@ char *jambase[] = {
"case AMIGA :\n",
"CC ?= gcc ;\n",
"YACC ?= \"bison -y\" ;\n",
"case CYGWIN : \n",
"case CYGWIN :\n",
"CC ?= gcc ;\n",
"CCFLAGS += -D__cygwin__ ;\n",
"LEX ?= flex ;\n",
@@ -589,11 +588,11 @@ char *jambase[] = {
"C++ ?= gcc ;\n",
"CCFLAGS += -D_POSIX_SOURCE ;\n",
"HDRS += /usr/include ;\n",
"RANLIB ?= \"\" ; \n",
"RANLIB ?= \"\" ;\n",
"NOARSCAN ?= true ;\n",
"NOARUPDATE ?= true ;\n",
"case MVS :\n",
"RANLIB ?= \"\" ; \n",
"RANLIB ?= \"\" ;\n",
"case NEXT :\n",
"AR ?= libtool -o ;\n",
"RANLIB ?= \"\" ;\n",
@@ -691,7 +690,7 @@ char *jambase[] = {
"YACC ?= ;\n",
"YACCFILES ?= ;\n",
"YACCFLAGS ?= ;\n",
"HDRPATTERN = \n",
"HDRPATTERN =\n",
"\"^[ ]*#[ ]*include[ ]*[<\\\"]([^\\\">]*)[\\\">].*$\" ;\n",
"OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;\n",
"DEPENDS all : shell files lib exe obj ;\n",
@@ -777,7 +776,7 @@ char *jambase[] = {
"{\n",
"DEPENDS $(<) : $(>) ;\n",
"}\n",
"rule GenFile \n",
"rule GenFile\n",
"{\n",
"local _t = [ FGristSourceFiles $(<) ] ;\n",
"local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;\n",
@@ -803,11 +802,11 @@ char *jambase[] = {
"rule HdrRule\n",
"{\n",
"local s ;\n",
"if $(HDRGRIST) \n",
"{ \n",
"if $(HDRGRIST)\n",
"{\n",
"s = $(>:G=$(HDRGRIST)) ;\n",
"} else { \n",
"s = $(>) ; \n",
"} else {\n",
"s = $(>) ;\n",
"}\n",
"INCLUDES $(<) : $(s) ;\n",
"SEARCH on $(s) = $(HDRSEARCH) ;\n",
@@ -831,13 +830,13 @@ char *jambase[] = {
"Depends $(tt) : $(i) ;\n",
"Install $(tt) : $(i) ;\n",
"Chmod $(tt) ;\n",
"if $(OWNER) && $(CHOWN) \n",
"{ \n",
"if $(OWNER) && $(CHOWN)\n",
"{\n",
"Chown $(tt) ;\n",
"OWNER on $(tt) = $(OWNER) ;\n",
"}\n",
"if $(GROUP) && $(CHGRP) \n",
"{ \n",
"if $(GROUP) && $(CHGRP)\n",
"{\n",
"Chgrp $(tt) ;\n",
"GROUP on $(tt) = $(GROUP) ;\n",
"}\n",
@@ -910,8 +909,8 @@ char *jambase[] = {
"{\n",
"MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;\n",
"}\n",
"if $(NOARSCAN) \n",
"{ \n",
"if $(NOARSCAN)\n",
"{\n",
"DEPENDS $(_l) : $(_s) ;\n",
"}\n",
"else\n",
@@ -972,7 +971,7 @@ char *jambase[] = {
"rule MkDir\n",
"{\n",
"NOUPDATE $(<) ;\n",
"if $(<) != $(DOT) && ! $($(<)-mkdir) \n",
"if $(<) != $(DOT) && ! $($(<)-mkdir)\n",
"{\n",
"local s ;\n",
"$(<)-mkdir = true ;\n",
@@ -1157,13 +1156,13 @@ char *jambase[] = {
"}\n",
"return $(_g) ;\n",
"}\n",
"rule FGristFiles \n",
"rule FGristFiles\n",
"{\n",
"if ! $(SOURCE_GRIST)\n",
"{\n",
"return $(<) ;\n",
"}\n",
"else \n",
"else\n",
"{\n",
"return $(<:G=$(SOURCE_GRIST)) ;\n",
"}\n",
@@ -1174,7 +1173,7 @@ char *jambase[] = {
"{\n",
"return $(<) ;\n",
"}\n",
"else \n",
"else\n",
"{\n",
"local _i _o ;\n",
"for _i in $(<)\n",
@@ -1201,10 +1200,10 @@ char *jambase[] = {
"rule FSubDir\n",
"{\n",
"local _i _d ;\n",
"if ! $(<[1]) \n",
"if ! $(<[1])\n",
"{\n",
"_d = $(DOT) ;\n",
"} \n",
"}\n",
"else\n",
"{\n",
"_d = $(DOTDOT) ;\n",
@@ -1245,7 +1244,7 @@ char *jambase[] = {
"}\n",
"else\n",
"{\n",
"_s = $(<[1]) ; \n",
"_s = $(<[1]) ;\n",
"for _i in $(<[2-])\n",
"{\n",
"_s = $(_i:R=$(_s)) ;\n",
@@ -1301,7 +1300,7 @@ char *jambase[] = {
"}\n",
"rule unmakeDir\n",
"{\n",
"if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\\\\\ \n",
"if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\\\\\\n",
"{\n",
"unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;\n",
"}\n",
@@ -1314,7 +1313,7 @@ char *jambase[] = {
"{\n",
"local _d, _s, _i ;\n",
"unmakeDir _d : $(<) ;\n",
"_s = $(_d[1]) ; \n",
"_s = $(_d[1]) ;\n",
"for _i in $(_d[2-])\n",
"{\n",
"_s = $(_s)/$(_i) ;\n",
@@ -1371,7 +1370,7 @@ char *jambase[] = {
"}\n",
"actions Install\n",
"{\n",
"$(CP) $(>) $(<) \n",
"$(CP) $(>) $(<)\n",
"}\n",
"actions Lex\n",
"{\n",
@@ -1383,7 +1382,7 @@ char *jambase[] = {
"}\n",
"actions Link bind NEEDLIBS\n",
"{\n",
"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) \n",
"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n",
"}\n",
"actions MkDir1\n",
"{\n",
@@ -1520,7 +1519,7 @@ char *jambase[] = {
"{\n",
"actions together piecemeal Archive\n",
"{\n",
"$(AR) $(<) +-$(>) \n",
"$(AR) $(<) +-$(>)\n",
"}\n",
"actions Cc\n",
"{\n",
@@ -1543,7 +1542,7 @@ char *jambase[] = {
"{\n",
"actions together piecemeal Archive\n",
"{\n",
"$(AR) /out:$(<) $(>) \n",
"$(AR) /out:$(<) $(>)\n",
"}\n",
"actions Cc\n",
"{\n",
@@ -1559,13 +1558,13 @@ char *jambase[] = {
"}\n",
"}\n",
"}\n",
"else if $(OS2) \n",
"else if $(OS2)\n",
"{\n",
"if $(TOOLSET) = WATCOM\n",
"{\n",
"actions together piecemeal Archive\n",
"{\n",
"$(AR) $(<) +-$(>) \n",
"$(AR) $(<) +-$(>)\n",
"}\n",
"actions Cc\n",
"{\n",
@@ -1602,17 +1601,17 @@ char *jambase[] = {
"}\n",
"else if $(VMS)\n",
"{\n",
"actions updated together piecemeal Archive \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",
"$(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>)\n",
"}\n",
"actions C++\n",
"{ \n",
"$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>) \n",
"{\n",
"$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>)\n",
"}\n",
"actions piecemeal together existing Clean\n",
"{\n",
@@ -1641,19 +1640,19 @@ char *jambase[] = {
"}\n",
"else if $(MAC)\n",
"{\n",
"actions together Archive \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",
"$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>)\n",
"}\n",
"actions C++\n",
"{ \n",
"{\n",
"set -e MWCincludes $(MACINC)\n",
"$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>) \n",
"$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>)\n",
"}\n",
"actions Link bind NEEDLIBS\n",
"{\n",

View File

@@ -8,7 +8,7 @@
* 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
* so that it can be built in to the executable. This is the
* declaration for that array.
*/

View File

@@ -438,17 +438,17 @@ static const unsigned short yyrline[] =
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",
"$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
@@ -1007,7 +1007,7 @@ yyparse ()
#endif
#endif
{
register int yystate;
register int yyn;
int yyresult;

View File

@@ -73,7 +73,7 @@
*
* New "[ rule ]" syntax evals rule into a LIST.
*
* Lists are now generated by compile_list() and
* 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.
@@ -81,7 +81,7 @@
* New 'return' rule sets the return value, though
* other statements also may have return values.
*
* 'run' production split from 'block' production so
* 'run' production split from 'block' production so
* that empty blocks can be handled separately.
*/
@@ -201,13 +201,13 @@ rule : _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
| IF_t expr _LBRACE_t block _RBRACE_t
{ $$.parse = pif( $2.parse, $4.parse, pnull() ); }
| MODULE_t list _LBRACE_t block _RBRACE_t
| MODULE_t list _LBRACE_t block _RBRACE_t
{ $$.parse = pmodule( $2.parse, $4.parse ); }
| CLASS_t lol _LBRACE_t block _RBRACE_t
| CLASS_t lol _LBRACE_t block _RBRACE_t
{ $$.parse = pclass( $2.parse, $4.parse ); }
| WHILE_t expr _LBRACE_t block _RBRACE_t
| 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 ); }
@@ -217,7 +217,7 @@ rule : _LBRACE_t block _RBRACE_t
{ $$.parse = pon( $2.parse, $3.parse ); }
| ACTIONS_t eflags ARG bindlist _LBRACE_t
{ yymode( SCAN_STRING ); }
STRING
STRING
{ yymode( SCAN_NORMAL ); }
_RBRACE_t
{ $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); }
@@ -240,23 +240,23 @@ assign : _EQUALS_t
/*
* expr - an expression for if
*/
expr : arg
expr : arg
{ $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); }
| expr _EQUALS_t expr
| 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
| expr _LANGLE_EQUALS_t expr
{ $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); }
| expr _RANGLE_t expr
| expr _RANGLE_t expr
{ $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); }
| expr _RANGLE_EQUALS_t expr
| expr _RANGLE_EQUALS_t expr
{ $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); }
| expr _AMPER_t expr
| expr _AMPER_t expr
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
| expr _AMPERAMPER_t expr
| expr _AMPERAMPER_t expr
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
| expr _BAR_t expr
{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
@@ -314,7 +314,7 @@ listp : /* empty */
{ $$.parse = pappend( $1.parse, $2.parse ); }
;
arg : ARG
arg : ARG
{ $$.parse = plist( $1.string ); }
| _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t
{ $$.parse = $3.parse; }
@@ -329,7 +329,7 @@ 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
| ON_t arg RETURN_t list
{ $$.parse = pon( $2.parse, $4.parse ); }
;
@@ -369,5 +369,3 @@ bindlist : /* empty */
| BIND_t list
{ $$.parse = $2.parse; }
;

View File

@@ -29,7 +29,7 @@
*
* New "[ rule ]" syntax evals rule into a LIST.
*
* Lists are now generated by compile_list() and
* 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.
@@ -37,7 +37,7 @@
* New 'return' rule sets the return value, though
* other statements also may have return values.
*
* 'run' production split from 'block' production so
* 'run' production split from 'block' production so
* that empty blocks can be handled separately.
*/
@@ -157,13 +157,13 @@ rule : `{` block `}`
{ $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); }
| `switch` list `{` cases `}`
{ $$.parse = pswitch( $2.parse, $4.parse ); }
| `if` expr `{` block `}`
| `if` expr `{` block `}`
{ $$.parse = pif( $2.parse, $4.parse, pnull() ); }
| `module` list `{` block `}`
| `module` list `{` block `}`
{ $$.parse = pmodule( $2.parse, $4.parse ); }
| `class` lol `{` block `}`
| `class` lol `{` block `}`
{ $$.parse = pclass( $2.parse, $4.parse ); }
| `while` expr `{` block `}`
| `while` expr `{` block `}`
{ $$.parse = pwhile( $2.parse, $4.parse ); }
| `if` expr `{` block `}` `else` rule
{ $$.parse = pif( $2.parse, $4.parse, $7.parse ); }
@@ -173,7 +173,7 @@ rule : `{` block `}`
{ $$.parse = pon( $2.parse, $3.parse ); }
| `actions` eflags ARG bindlist `{`
{ yymode( SCAN_STRING ); }
STRING
STRING
{ yymode( SCAN_NORMAL ); }
`}`
{ $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); }
@@ -196,23 +196,23 @@ assign : `=`
/*
* expr - an expression for if
*/
expr : arg
expr : arg
{ $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); }
| expr `=` expr
| 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
| expr `<=` expr
{ $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); }
| expr `>` expr
| expr `>` expr
{ $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); }
| expr `>=` expr
| expr `>=` expr
{ $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); }
| expr `&` expr
| expr `&` expr
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
| expr `&&` expr
| expr `&&` expr
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
| expr `|` expr
{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
@@ -270,7 +270,7 @@ listp : /* empty */
{ $$.parse = pappend( $1.parse, $2.parse ); }
;
arg : ARG
arg : ARG
{ $$.parse = plist( $1.string ); }
| `[` { yymode( SCAN_NORMAL ); } func `]`
{ $$.parse = $3.parse; }
@@ -285,7 +285,7 @@ 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
| `on` arg `return` list
{ $$.parse = pon( $2.parse, $4.parse ); }
;

View File

@@ -13,228 +13,174 @@
*
* 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
* 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
* 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() */
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 )
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;
}
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;
return l;
}
/*
* list_new() - tack a string onto the end of a list of strings
*/
LIST *
list_new(
LIST *head,
char *string )
LIST * list_new( LIST * head, char * string )
{
LIST *l;
LIST * l;
if( DEBUG_LISTS )
printf( "list > %s <\n", string );
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 */
/* 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
{
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 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;
if ( !head ) head = l;
else head->tail->next = l;
head->tail = l;
l->next = 0;
l->string = string;
l->string = string;
return head;
return head;
}
/*
* list_copy() - copy a whole list of strings (nl) onto end of another (l)
* list_copy() - copy a whole list of strings (nl) onto end of another (l).
*/
LIST *
list_copy(
LIST *l,
LIST *nl )
LIST * list_copy( LIST * l, LIST * nl )
{
for( ; nl; nl = list_next( nl ) )
l = list_new( l, copystr( nl->string ) );
return l;
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_sublist() - copy a subset of a list of strings.
*/
LIST *
list_sublist(
LIST *l,
int start,
int count )
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;
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;
}
LIST *
list_sort(
LIST *l)
static int str_ptr_compare( void const * va, void const * vb )
{
char * a = *( (char * *)va );
char * b = *( (char * *)vb );
return strcmp(a, b);
}
LIST* first = 0;
LIST* second = 0;
LIST* merged = l;
LIST* result;
if (!l)
LIST * list_sort( LIST * l )
{
int len;
int ii;
char * * strings;
LIST * listp;
LIST * result = 0;
if ( !l )
return L0;
for(;;) {
/* Split the list in two */
LIST** dst = &first;
LIST* src = merged;
for(;;) {
*dst = list_append(*dst, list_new(0, src->string));
if (!src->next)
break;
len = list_length( l );
strings = (char * *)BJAM_MALLOC( len * sizeof(char*) );
if (strcmp(src->string, src->next->string) > 0)
{
if (dst == &first)
dst = &second;
else
dst = &first;
}
src = src->next;
}
if (merged != l)
list_free( merged );
merged = 0;
if (second == 0) {
result = first;
break;
}
/* Merge lists 'first' and 'second' into 'merged' and free
'first'/'second'. */
{
LIST* f = first;
LIST* s = second;
while(f && s)
{
if (strcmp(f->string, s->string) < 0)
{
merged = list_append( merged, list_new(0, f->string ));
f = f->next;
}
else
{
merged = list_append( merged, list_new(0, s->string ));
s = s->next;
}
}
merged = list_copy( merged, f );
merged = list_copy( merged, s );
list_free( first );
list_free( second );
first = 0;
second = 0;
}
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 )
void list_free( LIST * head )
{
/* Just tack onto freelist. */
if( head )
{
head->tail->next = freelist;
freelist = 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 * list_pop_front( LIST * l )
{
LIST * result = l->next;
if( result )
if ( result )
{
result->tail = l->tail;
l->next = L0;
@@ -244,126 +190,116 @@ LIST * list_pop_front( LIST *l )
return result;
}
/*
* list_print() - print a list of strings to stdout
*/
void
list_print( LIST *l )
void list_print( LIST * l )
{
LIST *p = 0;
for( ; l; p = l, l = list_next( l ) )
if ( p )
printf( "%s ", p->string );
LIST * p = 0;
for ( ; l; p = l, l = list_next( l ) )
if ( p )
printf( "%s", p->string );
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 list_length( LIST * l )
{
int n = 0;
for( ; l; l = list_next( l ), ++n )
;
return n;
int n = 0;
for ( ; l; l = list_next( l ), ++n );
return n;
}
int
list_in(LIST* l, char* value)
int list_in( LIST * l, char * value )
{
for(; l; l = l->next)
if (strcmp(l->string, value) == 0)
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)
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)
if ( !last_added || strcmp( sorted_list->string, last_added->string ) != 0 )
{
result = list_new(result, sorted_list->string);
result = list_new( result, sorted_list->string );
last_added = sorted_list;
}
}
return result;
return result;
}
/*
* lol_init() - initialize a LOL (list of lists)
* lol_init() - initialize a LOL (list of lists).
*/
void
lol_init( LOL *lol )
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
* lol_add() - append a LIST onto an LOL.
*/
void
lol_free( LOL *lol )
void lol_add( LOL * lol, LIST * l )
{
int i;
for( i = 0; i < lol->count; i++ )
list_free( lol->list[i] );
lol->count = 0;
if ( lol->count < LOL_MAX )
lol->list[ lol->count++ ] = l;
}
/*
* lol_get() - return one of the LISTs in the LOL
* lol_free() - free the LOL and its LISTs.
*/
LIST *
lol_get(
LOL *lol,
int i )
void lol_free( LOL * lol )
{
return i < lol->count ? lol->list[i] : 0;
int i;
for ( i = 0; i < lol->count; ++i )
list_free( lol->list[ i ] );
lol->count = 0;
}
/*
* lol_print() - debug print LISTS separated by ":"
* lol_get() - return one of the LISTs in the LOL.
*/
void
lol_print( LOL *lol )
LIST * lol_get( LOL * lol, int i )
{
int i;
for( i = 0; i < lol->count; i++ )
{
if( i )
printf( " : " );
list_print( lol->list[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 ] );
}
}

View File

@@ -19,24 +19,24 @@
*
* Structures defined:
*
* LIST - list of strings
* LOL - list of LISTs
* 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
* 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 ":"
* 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()
@@ -52,10 +52,10 @@
typedef struct _list LIST;
struct _list {
LIST *next;
LIST *tail; /* only valid in head node */
char *string; /* private copy */
} ;
LIST *next;
LIST *tail; /* only valid in head node */
char *string; /* private copy */
};
/*
* LOL - list of LISTs
@@ -66,17 +66,17 @@ typedef struct _lol LOL;
# define LOL_MAX 9
struct _lol {
int count;
LIST *list[ LOL_MAX ];
} ;
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_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);
@@ -86,11 +86,11 @@ int list_in(LIST* l, char* value);
# 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_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 );
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -14,16 +14,16 @@ 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;
int temp;
int updating;
int cantfind;
int cantmake;
int targets;
int made;
} COUNTS ;
void make0( TARGET *t, TARGET *p, int depth,
void make0( TARGET *t, TARGET *p, int depth,
COUNTS *counts, int anyhow );
@@ -31,7 +31,7 @@ void make0( TARGET *t, TARGET *p, int depth,
* 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();

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define ATOMIC_UNCOLLECTABLE
#define NO_EXECUTE_PERMISSION
#define ALL_INTERIOR_POINTERS
#define LARGE_CONFIG
/*
#define NO_SIGNALS
@@ -25,11 +25,11 @@ http://www.boost.org/LICENSE_1_0.txt)
#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"
@@ -60,7 +60,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#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"

View File

@@ -25,7 +25,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#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
@@ -54,7 +54,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#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

View File

@@ -17,115 +17,107 @@
*
* Results look like this:
*
* char *jambase[] = {
* "...\n",
* ...
* 0 };
* char *jambase[] = {
* "...\n",
* ...
* 0 };
*
* Handles \'s and "'s specially; knows to delete blank and comment lines.
*
*/
# include <stdio.h>
# include <string.h>
#include <stdio.h>
#include <string.h>
int main( int argc, char **argv, char **envp )
int main( int argc, char * * argv, char * * envp )
{
char buf[ 1024 ];
FILE *fin;
FILE *fout;
char *p;
int doDotC = 0;
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 ( 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 ( !( fout = fopen( argv[1], "w" ) ) )
{
perror( argv[ 1 ] );
return -1;
}
/* If the file ends in .c generate a C source file */
/* If the file ends in .c generate a C source file. */
if ( ( p = strrchr( argv[1], '.' ) ) && !strcmp( p, ".c" ) )
doDotC++;
if( ( p = strrchr( argv[1], '.' ) ) && !strcmp( p, ".c" ) )
doDotC++;
/* Now process the files. */
/* Now process the files */
argc -= 2;
argv += 2;
argc -= 2, argv += 2;
if ( doDotC )
{
fprintf( fout, "/* Generated by mkjambase from Jambase */\n" );
fprintf( fout, "char *jambase[] = {\n" );
}
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;
}
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 );
if( doDotC )
{
fprintf( fout, "/* %s */\n", *argv );
}
else
{
fprintf( fout, "### %s ###\n", *argv );
}
while ( fgets( buf, sizeof( buf ), fin ) )
{
if ( doDotC )
{
char * p = buf;
while( fgets( buf, sizeof( buf ), fin ) )
{
if( doDotC )
{
char *p = buf;
/* Strip leading whitespace. */
while ( ( *p == ' ' ) || ( *p == '\t' ) || ( *p == '\n' ) )
++p;
/* Strip leading whitespace. */
/* Drop comments and empty lines. */
if ( ( *p == '#' ) || !*p )
continue;
while( *p == ' ' || *p == '\t' || *p == '\n' )
p++;
/* 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;
}
/* Drop comments and empty lines. */
fprintf( fout, "\\n\",\n" );
}
else
{
fprintf( fout, "%s", buf );
}
}
if( *p == '#' || !*p )
continue;
fclose( fin );
}
/* Copy */
if ( doDotC )
fprintf( fout, "0 };\n" );
putc( '"', fout );
fclose( 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;
return 0;
}

View File

@@ -16,11 +16,12 @@
#include "strings.h"
#include <assert.h>
static struct hash* module_hash = 0;
static struct hash * module_hash = 0;
static char* new_module_str( module_t* m, char* suffix )
static char * new_module_str( module_t * m, char * suffix )
{
char* result;
char * result;
string s;
string_copy( &s, m->name );
string_append( &s, suffix );
@@ -29,26 +30,28 @@ static char* new_module_str( module_t* m, char* suffix )
return result;
}
module_t* bindmodule( char* name )
{
PROFILE_ENTER(BINDMODULE);
string s;
module_t m_, *m = &m_;
if( !module_hash )
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)
if ( name )
{
string_append( &s, name );
string_push_back( &s, '.' );
}
m->name = s.value;
if ( hashenter( module_hash, (HASHDATA **)&m ) )
if ( hashenter( module_hash, (HASHDATA * *)&m ) )
{
m->name = newstr( m->name );
m->variables = 0;
@@ -60,35 +63,38 @@ module_t* bindmodule( char* name )
}
string_free( &s );
PROFILE_EXIT(BINDMODULE);
PROFILE_EXIT( BINDMODULE );
return m;
}
/*
* demand_rules() - Get the module's "rules" hash on demand
* demand_rules() - Get the module's "rules" hash on demand.
*/
struct hash* demand_rules( module_t* m )
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
* delete_module() - wipe out the module's rules and variables.
*/
static void delete_rule_( void* xrule, void* data )
static void delete_rule_( void * xrule, void * data )
{
rule_free( (RULE*)xrule );
rule_free( (RULE *)xrule );
}
void delete_module( module_t* m )
void delete_module( module_t * m )
{
/* clear out all the rules */
/* Clear out all the rules. */
if ( m->rules )
{
hashenumerate( m->rules, delete_rule_, (void*)0 );
hashenumerate( m->rules, delete_rule_, (void *)0 );
hashdone( m->rules );
m->rules = 0;
}
@@ -102,59 +108,61 @@ void delete_module( module_t* m )
}
}
module_t* root_module()
module_t * root_module()
{
static module_t* root = 0;
static module_t * root = 0;
if ( !root )
root = bindmodule(0);
root = bindmodule( 0 );
return root;
}
void enter_module( module_t* m )
void enter_module( module_t * m )
{
var_hash_swap( &m->variables );
}
void exit_module( module_t* m )
void exit_module( module_t * m )
{
var_hash_swap( &m->variables );
}
void import_module(LIST* module_names, module_t* target_module)
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");
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);
for ( ; module_names; module_names = module_names->next )
{
char * s = module_names->string;
char * * ss = &s;
hashenter( h, (HASHDATA * *)&ss );
}
PROFILE_EXIT(IMPORT_MODULE);
PROFILE_EXIT( IMPORT_MODULE );
}
static void add_module_name( void* r_, void* result_ )
static void add_module_name( void * r_, void * result_ )
{
char** r = (char**)r_;
LIST** result = (LIST**)result_;
char * * r = (char * *)r_;
LIST * * result = (LIST * *)result_;
*result = list_new( *result, copystr( *r ) );
}
LIST* imported_modules(module_t* module)
{
LIST *result = L0;
LIST * imported_modules( module_t * module )
{
LIST * result = L0;
if ( module->imported_modules )
hashenumerate( module->imported_modules, add_module_name, &result );
return result;
}

View File

@@ -77,7 +77,7 @@ LIST *order( PARSE *parse, FRAME *frame )
LIST* arg = lol_get( frame->args, 0 );
LIST* tmp;
LIST* result = 0;
int src, dst;
int src;
/* We need to create a graph of order dependencies between
the passed objects. We assume that there are no duplicates

View File

@@ -15,12 +15,12 @@ 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;
}
@@ -28,24 +28,26 @@ LIST* get_grist(char* f)
/*
rule create ( raw-properties * )
{
raw-properties = [ sequence.unique
raw-properties = [ sequence.unique
[ sequence.insertion-sort $(raw-properties) ] ] ;
local key = $(raw-properties:J=-:E=) ;
if ! $(.ps.$(key))
if ! $(.ps.$(key))
{
.ps.$(key) = [ new property-set $(raw-properties) ] ;
}
return $(.ps.$(key)) ;
return $(.ps.$(key)) ;
}
*/
LIST *property_set_create( PARSE *parse, FRAME *frame )
{
LIST* properties = lol_get( frame->args, 0 );
LIST* properties = lol_get( frame->args, 0 );
LIST* sorted = 0;
#if 0
LIST* order_sensitive = 0;
#endif
LIST* unique;
LIST* tmp;
LIST* val;
@@ -63,7 +65,7 @@ LIST *property_set_create( PARSE *parse, FRAME *frame )
}
list_free(att);
}
sorted = list_sort(sorted);
sorted = list_append(sorted, order_sensitive);
unique = list_unique(sorted);
@@ -73,24 +75,24 @@ LIST *property_set_create( PARSE *parse, FRAME *frame )
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);
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);
@@ -105,5 +107,4 @@ void init_property_set()
char* args[] = { "raw-properties", "*", 0 };
declare_native_rule("property-set", "create", args, property_set_create, 1);
}
}

View File

@@ -9,15 +9,14 @@
# define C0 (char *)0
void declare_native_rule(char* module, char* rule, char** args,
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;
@@ -25,14 +24,13 @@ void declare_native_rule(char* module, char* rule, char** 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.procedure = parse_make( f, P0, P0, P0, C0, C0, 0 );
n.version = version;
hashenter(m->native_rules, (HASHDATA**)&np);
}
}

View File

@@ -24,9 +24,9 @@ struct native_rule_t
};
/* MSVC debugger gets confused unless this is provided */
typedef struct native_rule_t native_rule_t ;
typedef struct native_rule_t native_rule_t ;
void declare_native_rule(char* module, char* rule, char** args,
void declare_native_rule(char* module, char* rule, char** args,
LIST*(*f)(PARSE*, FRAME*), int version);

View File

@@ -22,71 +22,74 @@
* 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()
* donestr() - free string tables
* 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
* 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;
typedef char * STRING;
static struct hash * strhash = 0;
static int strtotal = 0;
static int strcount_in = 0;
static int strcount_out = 0;
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
* 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];
struct strblock * next;
char data[STRING_BLOCK];
} strblock;
static strblock* strblock_chain = 0;
static strblock * strblock_chain = 0;
/* Storage remaining in the current strblock */
static char* storage_start = 0;
static char* storage_finish = 0;
static char * storage_start = 0;
static char * storage_finish = 0;
/*
* allocate() - Allocate n bytes of immortal string storage
* allocate() - Allocate n bytes of immortal string storage.
*/
static char* allocate(size_t n)
static char * allocate( size_t const n )
{
#ifdef BJAM_NEWSTR_NO_ALLOCATE
#ifdef BJAM_NEWSTR_NO_ALLOCATE
return (char*)BJAM_MALLOC_ATOMIC(n);
#else
/* See if we can grab storage from an existing block */
#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;
char * result = storage_start;
storage_start += n;
return result;
}
else /* Must allocate a new block */
else /* Must allocate a new block. */
{
strblock* 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]) );
/* 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 */
/* Take future allocations out of the larger remaining space. */
if ( remaining < nalloc - n )
{
storage_start = new_block->data + n;
@@ -94,77 +97,78 @@ static char* allocate(size_t n)
}
return new_block->data;
}
#endif
#endif
}
/*
* newstr() - return a dynamically allocated copy of a string
* newstr() - return a dynamically allocated copy of a string.
*/
char *
newstr( char *string )
char * newstr( char * string )
{
STRING str, *s = &str;
STRING str;
STRING * s = &str;
if( !strhash )
strhash = hashinit( sizeof( STRING ), "strings" );
if ( !strhash )
strhash = hashinit( sizeof( STRING ), "strings" );
*s = string;
*s = string;
if( hashenter( strhash, (HASHDATA **)&s ) )
{
int l = strlen( string );
char *m = (char *)allocate( l + 1 );
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;
}
strtotal += l + 1;
memcpy( m, string, l + 1 );
*s = m;
}
strcount_in += 1;
return *s;
return *s;
}
/*
* copystr() - return a copy of a string previously returned by newstr()
*/
char *
copystr( char *s )
char * copystr( char * s )
{
strcount_in += 1;
return s;
return s;
}
/*
* freestr() - free a string returned by newstr() or copystr()
*/
void
freestr( char *s )
void freestr( char * s )
{
strcount_out += 1;
}
/*
* donestr() - free string tables
* str_done() - free string tables.
*/
void
donestr()
void str_done()
{
/* Reclaim string blocks */
/* Reclaim string blocks. */
while ( strblock_chain != 0 )
{
strblock* n = strblock_chain->next;
strblock * n = strblock_chain->next;
BJAM_FREE(strblock_chain);
strblock_chain = n;
}
hashdone( strhash );
if( DEBUG_MEM )
if ( DEBUG_MEM )
printf( "%dK in strings\n", strtotal / 1024 );
/* printf( "--- %d strings of %d dangling\n", strcount_in-strcount_out, strcount_in ); */
}

View File

@@ -8,7 +8,7 @@
* newstr.h - string manipulation routines
*/
char *newstr( char *string );
char *copystr( char *s );
void freestr( char *s );
void donestr();
char * copystr ( char * );
void freestr ( char * );
char * newstr ( char * );
void str_done();

View File

@@ -12,92 +12,83 @@
*
* {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."
* 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,
option *optv )
int getoptions( int argc, char * * argv, char * opts, option * optv )
{
int i;
int optc = N_OPTS;
memset( (char *)optv, '\0', sizeof( *optv ) * N_OPTS );
for( i = 0; i < argc; i++ )
for ( i = 0; i < argc; ++i )
{
char *arg;
char *arg;
if( argv[i][0] != '-' || ( argv[i][1] != '-' && !isalpha( argv[i][1] ) ) )
continue;
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;
}
if ( !optc-- )
{
printf( "too many options (%d max)\n", N_OPTS );
return -1;
}
for( arg = &argv[i][1]; *arg; arg++ )
{
char *f;
for ( arg = &argv[ i ][ 1 ]; *arg; ++arg )
{
char * f;
for( f = opts; *f; f++ )
if( *f == *arg )
break;
for ( f = opts; *f; ++f )
if ( *f == *arg )
break;
if( !*f )
{
printf( "Invalid option: -%c\n", *arg );
return -1;
}
if ( !*f )
{
printf( "Invalid option: -%c\n", *arg );
return -1;
}
optv->flag = *f;
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;
}
}
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
* Name: getoptval() - find an option given its character.
*/
char *
getoptval(
option *optv,
char opt,
int subopt )
char * getoptval( option * optv, char opt, int subopt )
{
int i;
for( i = 0; i < N_OPTS; i++, optv++ )
if( optv->flag == opt && !subopt-- )
return optv->val;
return 0;
int i;
for ( i = 0; i < N_OPTS; ++i, ++optv )
if ( ( optv->flag == opt ) && !subopt-- )
return optv->val;
return 0;
}

View File

@@ -13,11 +13,11 @@
typedef struct option
{
char flag; /* filled in by getoption() */
char *val; /* set to random address if true */
char flag; /* filled in by getoption() */
char *val; /* set to random address if true */
} option;
# define N_OPTS 256
int getoptions( int argc, char **argv, char *opts, option *optv );
char * getoptval( option *optv, char opt, int subopt );
int getoptions( int argc, char **argv, char *opts, option *optv );
char * getoptval( option *optv, char opt, int subopt );

View File

@@ -1,4 +1,4 @@
/*
/*
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)
@@ -12,50 +12,53 @@
#define bjam_out (stdout)
#define bjam_err (stderr)
static void out_(
const char * data,
FILE * io
)
static void out_
(
char const * data,
FILE * io
)
{
while ( *data )
{
size_t len = strcspn(data,"\r");
fwrite(data,len,1,io);
data += len;
data += fwrite(data,1,len,io);
if ( *data == '\r' ) ++data;
}
}
void out_action(
const char * action,
const char * target,
const char * command,
const char * out_data,
const char * err_data,
int exit_reason
)
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. */
/* 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);
fprintf( bjam_out, "%s %s\n", action, target );
}
switch (exit_reason)
/* 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;
@@ -63,59 +66,60 @@ void out_action(
break;
case EXIT_TIMEOUT:
{
/* process expired, make user aware with explicit message */
/* Process expired, make user aware with explicit message. */
if ( action )
{
/* but only output for non-quietly actions */
fprintf(bjam_out, "%d second time limit exceeded\n", globs.timeout);
/* 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 */
/* Print out the command output, if requested. */
if ( action )
{
/* but only output for non-quietly actions */
if (0 != out_data &&
( globs.pipe_action & 1 /* STDOUT_FILENO */ ||
globs.pipe_action == 0))
/* 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);
out_( out_data, bjam_out );
}
if (0 != err_data &&
globs.pipe_action & 2 /* STDERR_FILENO */)
if ( ( 0 != err_data ) &&
( globs.pipe_action & 2 /* STDERR_FILENO */ ) )
{
out_(err_data,bjam_err);
out_( err_data, bjam_err );
}
}
fflush(bjam_out);
fflush(bjam_err);
fflush(globs.cmdout);
fflush( bjam_out );
fflush( bjam_err );
fflush( globs.cmdout );
}
char * outf_int( int value )
{
char buffer[50];
sprintf(buffer, "%i", value);
return newstr(buffer);
sprintf( buffer, "%i", value );
return newstr( buffer );
}
char * outf_double( double value )
{
char buffer[50];
sprintf(buffer, "%f", value);
return newstr(buffer);
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);
strftime( buffer, 49, "%Y-%m-%d %H:%M:%SZ", gmtime( &value ) );
return newstr( buffer );
}

View File

@@ -1,4 +1,4 @@
/*
/*
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)

View File

@@ -10,128 +10,123 @@
* (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"
#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.
* as per Matt Armstrong.
* 09/11/00 (seiwald) - structure reworked to reflect that (*func)()
* returns a LIST *.
* returns a LIST *.
*/
static PARSE *yypsave;
static PARSE * yypsave;
void
parse_file( char *f, FRAME* frame )
void parse_file( char * f, FRAME * frame )
{
/* Suspend scan of current file */
/* and push this new file in the stream */
/* Suspend scan of current file and push this new file in the stream. */
yyfparse( f );
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).
*/
/* 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;
for(;;)
{
PARSE *p;
/* Filled by yyparse() calling parse_save(). */
yypsave = 0;
/* Filled by yyparse() calling parse_save() */
/* If parse error or empty parse, outta here. */
if ( yyparse() || !( p = yypsave ) )
break;
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 );
}
/* Run the parse tree. */
parse_evaluate( p, frame );
parse_free( p );
}
}
void
parse_save( PARSE *p )
void parse_save( PARSE * p )
{
yypsave = p;
yypsave = p;
}
PARSE *
parse_make(
LIST *(*func)( PARSE *p, FRAME *args ),
PARSE *left,
PARSE *right,
PARSE *third,
char *string,
char *string1,
int num )
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 ) );
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 );
}
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;
return p;
if ( left )
{
p->file = left->file;
p->line = left->line;
}
else
{
yyinput_stream( &p->file, &p->line );
}
return p;
}
void
parse_refer( PARSE *p )
void parse_refer( PARSE * p )
{
++p->refs;
++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 );
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 )
LIST * parse_evaluate( PARSE * p, FRAME * frame )
{
frame->procedure = p;
return (*p->func)(p, frame);
return (*p->func)( p, frame );
}

View File

@@ -4,56 +4,56 @@
* 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)
/* 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"
#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.h - make and destroy parse trees as driven by the parser.
*/
/*
* parse tree node
* Parse tree node.
*/
struct _PARSE {
LIST *(*func)( PARSE *p, FRAME *frame );
PARSE *left;
PARSE *right;
PARSE *third;
char *string;
char *string1;
LIST * (* func)( PARSE *, FRAME * );
PARSE * left;
PARSE * right;
PARSE * third;
char * string;
char * string1;
int num;
int refs;
/* module* module; */
char* rulename;
char* file;
/* module * module; */
char * rulename;
char * file;
int line;
} ;
};
void parse_file( char *f, FRAME* frame );
void parse_save( PARSE *p );
void parse_file( char *, FRAME * );
void parse_save( PARSE * );
PARSE * parse_make(
LIST *(*func)( PARSE *p, FRAME* frame ),
PARSE *left,
PARSE *right,
PARSE *third,
char *string,
char *string1,
int num );
PARSE * parse_make(
LIST * (* func)( PARSE *, FRAME * ),
PARSE * left,
PARSE * right,
PARSE * third,
char * string,
char * string1,
int num );
void parse_refer( PARSE *p );
void parse_free( PARSE *p );
LIST* parse_evaluate( PARSE *p, FRAME* frame );
void parse_refer ( PARSE * );
void parse_free ( PARSE * );
LIST * parse_evaluate( PARSE *, FRAME * );
#endif

View File

@@ -9,9 +9,9 @@
#define VERSION_MAJOR 3
#define VERSION_MINOR 1
#define VERSION_PATCH 16
#define VERSION_PATCH 17
#define VERSION_MAJOR_SYM "03"
#define VERSION_MINOR_SYM "1"
#define VERSION_PATCH_SYM "16"
#define VERSION "3.1.16"
#define VERSION_PATCH_SYM "17"
#define VERSION "3.1.17"
#define JAMVERSYM "JAMVERSION=3.1"

View File

@@ -22,9 +22,9 @@
*
* 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
* 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.
@@ -41,10 +41,10 @@
* 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.
* 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.
* directory name, unless the directory name is all
* :'s, so that $(d:P) works.
*/
/*
@@ -52,132 +52,127 @@
*/
void
path_parse(
char *file,
PATHNAME *f )
path_parse(
char *file,
PATHNAME *f )
{
char *p, *q;
char *end;
memset( (char *)f, 0, sizeof( *f ) );
char *p, *q;
char *end;
/* Look for <grist> */
memset( (char *)f, 0, sizeof( *f ) );
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
{
f->f_grist.ptr = file;
f->f_grist.len = p - file;
file = p + 1;
}
/* Look for <grist> */
/* Look for dir: */
if ( file[0] == '<' && ( p = strchr( file, '>' ) ) )
{
f->f_grist.ptr = file;
f->f_grist.len = p - file;
file = p + 1;
}
if( p = strrchr( file, DELIM ) )
{
f->f_dir.ptr = file;
f->f_dir.len = p - file;
file = p + 1;
/* Look for dir: */
/* All :'s? Include last : as part of directory name */
if ( p = strrchr( file, DELIM ) )
{
f->f_dir.ptr = file;
f->f_dir.len = p - file;
file = p + 1;
while( p > f->f_dir.ptr && *--p == DELIM )
;
if( p == f->f_dir.ptr )
f->f_dir.len++;
}
/* All :'s? Include last : as part of directory name */
end = file + strlen( file );
while ( ( p > f->f_dir.ptr ) && ( *--p == DELIM ) );
/* Look for (member) */
if ( p == f->f_dir.ptr )
++f->f_dir.len;
}
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
{
f->f_member.ptr = p + 1;
f->f_member.len = end - p - 2;
end = p;
}
end = file + strlen( file );
/* Look for .suffix */
/* This would be memrchr() */
/* Look for (member). */
p = 0;
q = file;
if ( ( p = strchr( file, '(' ) ) && ( end[-1] == ')' ) )
{
f->f_member.ptr = p + 1;
f->f_member.len = end - p - 2;
end = p;
}
while( q = memchr( q, '.', end - q ) )
p = q++;
/* Look for .suffix */
/* This would be memrchr() */
if( p )
{
f->f_suffix.ptr = p;
f->f_suffix.len = end - p;
end = p;
}
p = 0;
q = file;
/* Leaves base */
while ( q = memchr( q, '.', end - q ) )
p = q++;
f->f_base.ptr = file;
f->f_base.len = end - file;
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
* 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 */
# 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 }
} ;
/* 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 )
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;
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 )
void path_build( PATHNAME * f, string * file, int binding )
{
int dflag, rflag, act;
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 ] )
switch ( act = grid[ rflag ][ dflag ] )
{
case G_DTDR:
{
@@ -185,77 +180,73 @@ path_build(
string_push_back( file, DELIM );
}
/* fall through */
case G_DIR:
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:
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:
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 )
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:
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 &&
/* 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 )
{
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 )
{
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 )
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);
if ( DEBUG_SEARCH )
printf( " -> '%s'\n", file->value );
}
/*
* path_parent() - make a PATHNAME point to its parent dir
* path_parent() - make a PATHNAME point to its parent dir
*/
void
path_parent( PATHNAME *f )
void path_parent( PATHNAME * f )
{
/* just set everything else to nothing */
/* Just set everything else to nothing. */
f->f_base.ptr =
f->f_suffix.ptr =
f->f_member.ptr = "";
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;
f->f_base.len =
f->f_suffix.len =
f->f_member.len = 0;
}
# endif /* OS_MAC */

View File

@@ -5,7 +5,7 @@
*/
/*
* pathsys.h - PATHNAME struct
* pathsys.h - PATHNAME struct
*/
/*
@@ -13,7 +13,7 @@
*
* <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
* (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
@@ -28,38 +28,39 @@
typedef struct _pathname PATHNAME;
typedef struct _pathpart PATHPART;
struct _pathpart {
char *ptr;
int len;
struct _pathpart
{
char * ptr;
int len;
};
struct _pathname {
PATHPART part[6];
# ifdef OS_VMS
int parent;
# endif
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]
#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_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 );
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);
char * short_path_to_long_path( char * short_path );
#endif
@@ -67,15 +68,15 @@ char* short_path_to_long_path(char* short_path);
/** Returns a static pointer to the system dependent path to the temporary
directory. NOTE: *without* a trailing path separator.
*/
const char * path_tmpdir(void);
const char * path_tmpdir( void );
/** Returns a new temporary name.
*/
const char * path_tmpnam(void);
const char * path_tmpnam( void );
/** Returns a new temporary path.
*/
const char * path_tmpfile(void);
const char * path_tmpfile( void );
#endif
#endif

View File

@@ -29,9 +29,9 @@
*
* 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
* 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.
@@ -48,7 +48,7 @@
* 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.
* don't include the archive member name.
* 01/13/01 (seiwald) - turn on \ handling on UNIX, on by accident
*/
@@ -56,88 +56,86 @@
* path_parse() - split a file name into dir/base/suffix/member
*/
void
path_parse(
char *file,
PATHNAME *f )
void path_parse( char * file, PATHNAME * f )
{
char *p, *q;
char *end;
memset( (char *)f, 0, sizeof( *f ) );
char * p;
char * q;
char * end;
/* Look for <grist> */
memset( (char *)f, 0, sizeof( *f ) );
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
{
f->f_grist.ptr = file;
f->f_grist.len = p - file;
file = p + 1;
}
/* Look for <grist> */
/* Look for dir/ */
if ( ( file[0] == '<' ) && ( p = strchr( file, '>' ) ) )
{
f->f_grist.ptr = file;
f->f_grist.len = p - file;
file = p + 1;
}
p = strrchr( file, '/' );
/* 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;
}
/* 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 ( p )
{
f->f_dir.ptr = file;
f->f_dir.len = p - file;
if( !f->f_dir.len )
f->f_dir.len = 1;
/* 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:" */
/* Special case for D:/ - dirname is D:/, not "D:" */
if( f->f_dir.len == 2 && file[1] == ':' )
f->f_dir.len = 3;
if ( f->f_dir.len == 2 && file[1] == ':' )
f->f_dir.len = 3;
# endif
file = p + 1;
}
file = p + 1;
}
end = file + strlen( file );
end = file + strlen( file );
/* Look for (member) */
/* Look for (member) */
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
{
f->f_member.ptr = p + 1;
f->f_member.len = end - p - 2;
end = p;
}
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() */
/* Look for .suffix */
/* This would be memrchr() */
p = 0;
q = file;
p = 0;
q = file;
while( q = (char *)memchr( q, '.', end - q ) )
p = q++;
while ( ( q = (char *)memchr( q, '.', end - q ) ) )
p = q++;
if( p )
{
f->f_suffix.ptr = p;
f->f_suffix.len = end - p;
end = p;
}
if ( p )
{
f->f_suffix.ptr = p;
f->f_suffix.len = end - p;
end = p;
}
/* Leaves base */
/* Leaves base */
f->f_base.ptr = file;
f->f_base.len = end - file;
f->f_base.ptr = file;
f->f_base.len = end - file;
}
/*
@@ -188,22 +186,22 @@ static char as_path_delim( char c )
void
path_build(
PATHNAME *f,
string *file,
int binding )
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
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
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] == '\\' )
@@ -213,43 +211,41 @@ path_build(
{
string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len );
/* If 'root' already ends with path delimeter,
/* 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] ) )
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 )
{
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 ) )
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] == ':' ) )
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] ) ) )
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 )
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 )
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 )
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 );
@@ -258,21 +254,21 @@ path_build(
}
/*
* path_parent() - make a PATHNAME point to its parent dir
* path_parent() - make a PATHNAME point to its parent dir
*/
void
path_parent( PATHNAME *f )
{
/* just set everything else to nothing */
/* just set everything else to nothing */
f->f_base.ptr =
f->f_suffix.ptr =
f->f_member.ptr = "";
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;
f->f_base.len =
f->f_suffix.len =
f->f_member.len = 0;
}
#ifdef NT
@@ -296,7 +292,7 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
/* Is the string valid? */
if (!lpszShortPath) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
return 0;
}
/* Is the path valid? */
@@ -305,7 +301,7 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
/* Convert "/" to "\" */
for (i=0;i<len;++i) {
if (lpszShortPath[i]==_T('/'))
if (lpszShortPath[i]==_T('/'))
path[i]=_T('\\');
else
path[i]=lpszShortPath[i];
@@ -331,7 +327,7 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
}
_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') &&
@@ -356,9 +352,9 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
/* 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[0] == _T('.') && new_element[1] == _T('.')
&& new_element[2] == _T('\0'))
{
_tcscat(ret, new_element);
@@ -378,21 +374,21 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
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);
return newstr(buffer2);
else
return newstr(short_path);
}
@@ -446,14 +442,14 @@ const char * path_tmpnam(void)
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;
}

View File

@@ -22,14 +22,14 @@
*
* 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
* 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
* 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.
*
@@ -38,258 +38,244 @@
*/
/*
* path_parse() - split a file name into dir/base/suffix/member
* path_parse() - split a file name into dir/base/suffix/member.
*/
void
path_parse(
char *file,
PATHNAME *f )
void path_parse( char * file, PATHNAME * f )
{
char *p, *q;
char *end;
memset( (char *)f, 0, sizeof( *f ) );
char * p;
char * q;
char * end;
/* Look for <grist> */
memset( (char *)f, 0, sizeof( *f ) );
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
{
f->f_grist.ptr = file;
f->f_grist.len = p - file;
file = p + 1;
}
/* Look for <grist> */
/* Look for dev:[dir] or dev: */
if ( ( file[0] == '<' ) && ( p = strchr( file, '>' ) ) )
{
f->f_grist.ptr = file;
f->f_grist.len = p - file;
file = p + 1;
}
if( ( p = strchr( file, ']' ) ) || ( p = strchr( file, ':' ) ) )
{
f->f_dir.ptr = file;
f->f_dir.len = p + 1 - file;
file = p + 1;
}
/* Look for dev:[dir] or dev: */
end = file + strlen( file );
if ( ( p = strchr( file, ']' ) ) || ( p = strchr( file, ':' ) ) )
{
f->f_dir.ptr = file;
f->f_dir.len = p + 1 - file;
file = p + 1;
}
/* Look for (member) */
end = file + strlen( file );
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
{
f->f_member.ptr = p + 1;
f->f_member.len = end - p - 2;
end = p;
}
/* Look for (member). */
/* Look for .suffix */
/* This would be memrchr() */
if ( ( p = strchr( file, '(' ) ) && ( end[ -1 ] == ')' ) )
{
f->f_member.ptr = p + 1;
f->f_member.len = end - p - 2;
end = p;
}
p = 0;
q = file;
/* Look for .suffix */
/* This would be memrchr(). */
while( q = (char *)memchr( q, '.', end - q ) )
p = q++;
p = 0;
q = file;
if( p )
{
f->f_suffix.ptr = p;
f->f_suffix.len = end - p;
end = p;
}
while ( q = (char *)memchr( q, '.', end - q ) )
p = q++;
/* Leaves base */
if ( p )
{
f->f_suffix.ptr = p;
f->f_suffix.len = end - p;
end = p;
}
f->f_base.ptr = file;
f->f_base.len = end - file;
/* Leaves base. */
f->f_base.ptr = file;
f->f_base.len = end - file;
/* Is this a directory without a file spec? */
f->parent = 0;
/* Is this a directory without a file spec? */
f->parent = 0;
}
/*
* dir mods result
* --- --- ------
* 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=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=[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]
* (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 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] */
# 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,
/* 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 )
struct dirinf
{
while( len-- )
if( *buf && *buf++ == c )
return buf - 1;
int flags;
return 0;
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 )
static void dir_flags( char * buf, int len, struct dirinf * i )
{
char *p;
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 || !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;
}
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 */
/* But if its rooted in any way. */
if( i->dir.len == 8 && !strncmp( i->dir.ptr, "[000000]", 8 ) )
i->flags = DIR_ROOT;
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 )
void path_build( PATHNAME * f, string * file, int binding )
{
struct dirinf root, dir;
struct dirinf root;
struct dirinf dir;
int g;
file_build1( f, file );
/* Get info on root and dir for combining. */
/* 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 ] )
/* Combine. */
switch ( g = grid[ root.flags ][ dir.flags ] )
{
case G_DIR:
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:
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:
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_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] == ']' )
if ( file->value[file->size - 1] == ']' )
string_pop_back( file );
/* Add . if separating two -'s */
if( g == G_DDD )
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:
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, '[' );
@@ -299,51 +285,52 @@ path_build(
}
# ifdef DEBUG
if( DEBUG_SEARCH && ( root.flags || dir.flags ) )
{
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
# endif
/*
/*
* Now do the special :P modifier when no file was present.
* (none) (none)
* [dir1.dir2] [dir1]
* [dir] [000000]
* [.dir] (none)
* [] []
* (none) (none)
* [dir1.dir2] [dir1]
* [dir] [000000]
* [.dir] (none)
* [] []
*/
if( file->value[file->size - 1] == ']' && f->parent )
if ( ( file->value[ file->size - 1 ] == ']' ) && f->parent )
{
char* p = file->value + file->size;
while( p-- > file->value )
char * p = file->value + file->size;
while ( p-- > file->value )
{
if( *p == '.' )
if ( *p == '.' )
{
/* If we've truncated everything and left with '[',
return empty string. */
if (p == file->value + 1)
if ( p == file->value + 1 )
string_truncate( file, 0 );
else {
else
{
string_truncate( file, p - file->value );
string_push_back( file, ']' );
}
break;
}
else if( *p == '-' )
if ( *p == '-' )
{
/* handle .- or - */
if( p > file->value && p[-1] == '.' )
if ( ( p > file->value ) && ( p[ -1 ] == '.' ) )
--p;
*p++ = ']';
break;
}
else if( *p == '[' )
if ( *p == '[' )
{
if( p[1] == ']' )
if ( p[ 1 ] == ']' )
{
/* CONSIDER: I don't see any use of this code. We immediately
break, and 'p' is a local variable. */
@@ -360,26 +347,21 @@ path_build(
}
/* Now copy the file pieces. */
if( f->f_base.len )
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 )
{
/* 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 )
{
else if ( binding && f->f_base.len )
string_push_back( file, '.' );
}
if( f->f_member.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 );
@@ -387,8 +369,8 @@ path_build(
}
# ifdef DEBUG
if( DEBUG_SEARCH )
printf("built %.*s + %.*s / %.*s suf %.*s mem %.*s -> %s\n",
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,
@@ -398,27 +380,27 @@ path_build(
# endif
}
/*
* path_parent() - make a PATHNAME point to its parent dir
* path_parent() - make a PATHNAME point to its parent dir
*/
void
path_parent( PATHNAME *f )
void path_parent( PATHNAME * f )
{
if( f->f_base.len )
{
f->f_base.ptr =
f->f_suffix.ptr =
f->f_member.ptr = "";
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;
}
f->f_base.len =
f->f_suffix.len =
f->f_member.len = 0;
}
else
{
f->parent = 1;
}
}
# endif /* VMS */

View File

@@ -6,25 +6,29 @@
#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 <limits.h>
#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_buffer[PATH_MAX];
static char * pwd_result = NULL;
@@ -33,20 +37,30 @@ pwd(void)
{
if (!pwd_result)
{
if (getcwd(pwd_buffer, sizeof(pwd_buffer)) == NULL)
{
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;
}
else
{
#ifdef NT
pwd_result = short_path_to_long_path(pwd_buffer);
#else
pwd_result = newstr(pwd_buffer);
#endif
}
}
return list_new(L0, pwd_result);
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,13 +9,13 @@
#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. */
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 );
@@ -26,7 +26,7 @@ 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
#define MAGIC 0234
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -11,11 +11,12 @@
*/
#ifndef RULES_DWA_20011020_H
# define RULES_DWA_20011020_H
#define RULES_DWA_20011020_H
#include "modules.h"
#include "jam.h"
#include "parse.h"
# include "modules.h"
# include "jam.h"
# include "parse.h"
/*
* rules.h - targets, rules, and related information
@@ -26,12 +27,12 @@
*
* The following are defined:
*
* RULE - a generic jam rule, the product of RULE and ACTIONS
* ACTIONS - a chain of ACTIONs
* ACTION - a RULE instance with targets and sources
* SETTINGS - variables to set when executing a TARGET's ACTIONS
* TARGETS - a chain of TARGETs
* TARGET - a file or "thing" that can be built
* 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.
@@ -49,217 +50,228 @@ typedef struct _action ACTION;
typedef struct _actions ACTIONS;
typedef struct _settings SETTINGS ;
/* RULE - a generic jam rule, the product of RULE and ACTIONS */
/* RULE - a generic jam rule, the product of RULE and ACTIONS. */
/* A rule's argument list */
/* A rule's argument list. */
struct argument_list
{
int reference_count;
LOL data[1];
};
/* The build actions corresponding to a rule */
/* 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 */
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 /* don't mention it unless verbose */
# define RULE_PIECEMEAL 0x10 /* split exec so each $(>) is small */
# define RULE_EXISTING 0x20 /* $(>) is pre-exisitng sources only */
#define RULE_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
*/
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
PyObject * python_function;
#endif
};
/* ACTIONS - a chain of ACTIONs */
/* ACTIONS - a chain of ACTIONs. */
struct _actions
{
ACTIONS * next;
ACTIONS * tail; /* valid only for head */
ACTION * action;
};
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 */
};
/* ACTION - a RULE instance with targets and sources */
/* 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() */
};
struct _action {
RULE *rule;
TARGETS *targets;
TARGETS *sources; /* aka $(>) */
char running; /* has been started */
char status; /* see TARGET status */
} ;
/* TARGETS - a chain of TARGETs. */
struct _targets
{
TARGETS * next;
TARGETS * tail; /* valid only for head */
TARGET * target;
};
/* SETTINGS - variables to set when executing a TARGET's ACTIONS */
/* 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 */
struct _settings {
SETTINGS *next;
char *symbol; /* symbol name for var_set() */
LIST *value; /* symbol value for var_set() */
} ;
short flags; /* status info */
/* TARGETS - a chain of TARGETs */
#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 */
struct _targets {
TARGETS *next;
TARGETS *tail; /* valid only for head */
TARGET *target;
} ;
/* 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 */
/* TARGET - a file or "thing" that can be built */
/* 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 */
struct _target {
char *name;
char *boundname; /* if search() relocates target */
ACTIONS *actions; /* rules to execute, if any */
SETTINGS *settings; /* variables to define */
#define T_FLAG_INTERNAL 0x0200 /* internal INCLUDES node */
short flags; /* status info */
/* 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_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 */
char binding; /* how target relates to a real file or
* folder
*/
/* this flag was added to support a new builtin rule named "RMBAD" */
/* it is used to force removal of outdated targets whose dependencies
* fail to build */
# define T_FLAG_RMOLD 0x0080 /* RMBAD applied */
#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 */
/* this flag was added to support a new builting rule named "FAIL_EXPECTED" */
/* it is used to indicate that the result of running a given action should */
/* be inverted (i.e. ok <=> fail). This is useful to launch certain test */
/* runs from a Jamfile.. */
/* */
# define T_FLAG_FAIL_EXPECTED 0x0100 /* FAIL_EXPECTED applied */
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;
# define T_FLAG_INTERNAL 0x0200 /* internal INCLUDES node */
time_t time; /* update time */
time_t leaf; /* update time of leaf sources */
/* 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
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 */
#define T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */
#endif
char binding; /* how target relates to real file */
# define T_BIND_UNBOUND 0 /* a disembodied name */
# define T_BIND_MISSING 1 /* couldn't find real file */
#ifdef OPT_SEMAPHORE
TARGET *semaphore; /* used in serialization */
#endif
# define T_BIND_PARENTS 2 /* using parent's timestamp */
# define T_BIND_EXISTS 3 /* real file, timestamp valid */
TARGETS *depends; /* dependencies */
TARGETS *dependents;/* the inverse of dependencies */
TARGETS *rebuilds; /* targets that should be force-rebuilt whenever this one is */
TARGET *includes; /* includes */
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 didn't need updating */
# define T_FATE_NEWER 3 /* target newer than parent */
# define T_FATE_SPOIL 4 /* >= SPOIL rebuilds parents */
# define T_FATE_ISTMP 4 /* unneeded temp target oddly present */
# define T_FATE_BUILD 5 /* >= BUILD rebuilds target */
# define T_FATE_TOUCHED 5 /* manually touched with -t */
# define T_FATE_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't find dependents */
char progress; /* tracks make1() progress */
# define T_MAKE_INIT 0 /* make1(target) not yet called */
# define T_MAKE_ONSTACK 1 /* make1(target) on stack */
# define T_MAKE_ACTIVE 2 /* make1(target) in make1b() */
# define T_MAKE_RUNNING 3 /* make1(target) running commands */
# define T_MAKE_DONE 4 /* make1(target) done */
char status; /* execcmd() result */
int asynccnt; /* child deps outstanding */
TARGETS *parents; /* used by make1() for completion */
char *cmds; /* type-punned command list */
char* failed;
} ;
RULE *bindrule( char *rulename, module_t* );
RULE* import_rule( RULE* source, module_t* m, char* name );
RULE* new_rule_body( module_t* m, char* rulename, argument_list* args, PARSE* procedure, int exprt );
RULE* new_rule_actions( module_t* m, char* rulename, char* command, LIST* bindlist, int flags );
TARGET *bindtarget( const char *targetname );
TARGET *copytarget( const TARGET *t );
void bind_explicitly_located_targets();
TARGET* search_for_target( char * name, LIST* search_path );
void touchtarget( char *t );
TARGETS *targetlist( TARGETS *chain, LIST *targets );
TARGETS *targetentry( TARGETS *chain, TARGET *target );
TARGETS *targetchain( TARGETS *chain, TARGETS *targets );
void freetargets( TARGETS *chain );
ACTIONS *actionlist( ACTIONS *chain, ACTION *action );
void freeactions( ACTIONS *chain );
SETTINGS *addsettings( SETTINGS *head, int flag, char *symbol, LIST *value );
void pushsettings( SETTINGS *v );
void popsettings( SETTINGS *v );
SETTINGS *copysettings( SETTINGS *v );
void freesettings( SETTINGS *v );
void rule_free( RULE *r );
void donerules();
argument_list* args_new();
void args_refer( argument_list* );
void args_free( argument_list* );
void actions_refer(rule_actions*);
void actions_free(rule_actions*);
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

View File

@@ -4,414 +4,406 @@
* 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"
#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().
* 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.
* defined before Linux's yacc tries to redefine it.
*/
struct keyword {
char *word;
int type;
} keywords[] = {
# include "jamgramtab.h"
{ 0, 0 }
} ;
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 */
} ;
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 struct include * incp = 0; /* current file; head of chain */
static int scanmode = SCAN_NORMAL;
static int anyerrors = 0;
static char *symdump( YYSTYPE *s );
# define BIGGEST_TOKEN 10240 /* no single token can be larger */
/*
* Set parser mode: normal, string, or keyword
*/
static char * symdump( YYSTYPE * );
void
yymode( int n )
{
scanmode = n;
}
#define BIGGEST_TOKEN 10240 /* no single token can be larger */
void
yyerror( char *s )
{
if( incp )
printf( "%s:%d: ", incp->fname, incp->line );
printf( "%s at %s\n", 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
* 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.
* Fabricates a continuous stream of characters across include files, returning
* EOF at the bitter end.
*/
int
yyline()
int yyline()
{
struct include *i = incp;
struct include * i = incp;
if( !incp )
return EOF;
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. */
/* 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 there is more data in this line, return it. */
if ( *i->string )
return *i->string++;
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 we're reading from an internal string list, go to the */
/* next string. */
/* 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++;
}
}
if( i->strings )
{
if( !*i->strings )
goto next;
/* This include is done. Free it up and return EOF so yyparse() returns to
* parse_file().
*/
i->line++;
i->string = *(i->strings++);
return *i->string++;
}
incp = i->next;
/* If necessary, open the file */
/* Close file, free name. */
if ( i->file && ( i->file != stdin ) )
fclose( i->file );
freestr( i->fname );
BJAM_FREE( (char *)i );
if( !i->file )
{
FILE *f = stdin;
if( strcmp( i->fname, "-" ) && !( f = fopen( i->fname, "r" ) ) )
perror( i->fname );
i->file = f;
}
/* If there's another line in this file, start it. */
if( i->file && fgets( i->buf, sizeof( i->buf ), i->file ) )
{
i->line++;
i->string = i->buf;
return *i->string++;
}
next:
/* This include is done. */
/* Free it up and return EOF so yyparse() returns to parse_file(). */
incp = i->next;
/* Close file, free name */
if( i->file && i->file != stdin )
fclose( i->file );
freestr( i->fname );
BJAM_FREE( (char *)i );
return EOF;
return EOF;
}
/*
* yylex() - set yylval to current token; return its type
* 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() - 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.
* 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-- )
#define yychar() ( *incp->string ? *incp->string++ : yyline() )
#define yyprev() ( incp->string-- )
int
yylex()
int yylex()
{
int c;
char buf[BIGGEST_TOKEN];
char *b = buf;
int c;
char buf[ BIGGEST_TOKEN ];
char * b = buf;
if( !incp )
goto eof;
if ( !incp )
goto eof;
/* Get first character (whitespace or of token) */
/* Get first character (whitespace or of token). */
c = yychar();
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.
*/
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;
int nest = 1;
while ( ( c != EOF ) && ( b < buf + sizeof( buf ) ) )
{
if ( c == '{' )
++nest;
while( c != EOF && b < buf + sizeof( buf ) )
{
if( c == '{' )
nest++;
if ( ( c == '}' ) && !--nest )
break;
if( c == '}' && !--nest )
break;
*b++ = c;
*b++ = c;
c = yychar();
c = yychar();
/* Turn trailing "\r\n" sequences into plain "\n" for Cygwin. */
if ( ( c == '\n' ) && ( b[ -1 ] == '\r' ) )
--b;
}
/* 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();
/* We ate the ending brace -- regurgitate it. */
/* Check for obvious errors. */
if ( b == buf + sizeof( buf ) )
{
yyerror( "action block too big" );
goto eof;
}
if( c != EOF )
yyprev();
if ( nest )
{
yyerror( "unmatched {} in action block" );
goto eof;
}
/* Check obvious errors. */
if( b == buf + sizeof( buf ) )
{
yyerror( "action block too big" );
goto eof;
}
if( nest )
{
yyerror( "unmatched {} in action block" );
goto eof;
}
*b = 0;
yylval.type = STRING;
yylval.string = newstr( buf );
*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 */
}
else
{
char * b = buf;
struct keyword * k;
int inquote = 0;
int notkeyword;
for( ;; )
{
/* Skip past white space */
while( c != EOF && isspace( c ) )
/* Eat white space. */
for ( ;; )
{
/* Skip past white space. */
while ( ( c != EOF ) && isspace( c ) )
c = yychar();
/* Not a comment? Swallow up comment line. */
if( c != '#' )
/* Not a comment? */
if ( c != '#' )
break;
while( ( c = yychar() ) != EOF && c != '\n' )
;
}
/* c now points to the first character of a token. */
/* Swallow up comment line. */
while ( ( ( c = yychar() ) != EOF ) && ( c != '\n' ) ) ;
}
if( c == EOF )
goto eof;
/* 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 == '$';
/* 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 */
/* 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';
*b++ = c;
notkeyword = 1;
}
else
{
/* \EOF */
break;
}
while(
c != EOF &&
b < buf + sizeof( buf ) &&
( inquote || !isspace( c ) ) )
{
if( c == '"' )
{
/* begin or end " */
inquote = !inquote;
notkeyword = 1;
}
else if( c != '\\' )
{
/* normal char */
*b++ = c;
}
else if( ( c = yychar()) != EOF )
{
/* \c */
*b++ = c;
notkeyword = 1;
}
else
{
/* \EOF */
break;
}
c = yychar();
}
c = yychar();
}
/* Check obvious errors. */
if ( b == buf + sizeof( buf ) )
{
yyerror( "string too big" );
goto eof;
}
/* Check obvious errors. */
if ( inquote )
{
yyerror( "unmatched \" in string" );
goto eof;
}
if( b == buf + sizeof( buf ) )
{
yyerror( "string too big" );
goto eof;
}
/* We looked ahead a character - back up. */
if ( c != EOF )
yyprev();
if( inquote )
{
yyerror( "unmatched \" in string" );
goto eof;
}
/* Scan token table. Do not scan if it is obviously not a keyword or if
* it is an alphabetic when were looking for punctuation.
*/
/* We looked ahead a character - back up. */
*b = 0;
yylval.type = ARG;
if( c != EOF )
yyprev();
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;
}
/* scan token table */
/* don't scan if it's obviously not a keyword or if its */
/* an alphabetic when were looking for punctuation */
if ( yylval.type == ARG )
yylval.string = newstr( buf );
}
*b = 0;
yylval.type = ARG;
if ( DEBUG_SCAN )
printf( "scan %s\n", symdump( &yylval ) );
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;
return yylval.type;
eof:
yylval.file = "end-of-input"; /* just in case */
yylval.line = 0;
yylval.type = EOF;
return yylval.type;
/* 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 * 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;
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
/*
* Get information about the current file and line, for those epsilon
* transitions that produce a parse.
*/
void yyinput_stream( char** name, int* line )
void yyinput_stream( char * * name, int * line )
{
if (incp)
if ( incp )
{
*name = incp->fname;
*line = incp->line;

View File

@@ -9,47 +9,48 @@
*
* 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
* 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.
* 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
#define YYSTYPE YYSYMBOL
typedef struct _YYSTYPE {
typedef struct _YYSTYPE
{
int type;
char *string;
PARSE *parse;
LIST *list;
char * string;
PARSE * parse;
LIST * list;
int number;
char *file;
char * file;
int line;
} YYSTYPE;
extern YYSTYPE yylval;
void yymode( int n );
void yyerror( char *s );
void yyerror( char * s );
int yyanyerrors();
void yyfparse( char *s );
void yyfparse( char * s );
int yyline();
int yylex();
int yyparse();
void yyinput_stream( char** name, int* line );
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 */
# define SCAN_NORMAL 0 /* normal parsing */
# define SCAN_STRING 1 /* look only for matching } */
# define SCAN_PUNCT 2 /* only punctuation keywords */

View File

@@ -10,74 +10,82 @@
* (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 <string.h>
#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;
typedef struct _binding
{
char * binding;
char * target;
} BINDING;
static struct hash *explicit_bindings = 0;
void call_bind_rule(
char* target_,
char* boundname_ )
void call_bind_rule
(
char * target_,
char * boundname_
)
{
LIST* bind_rule = var_get( "BINDRULE" );
if( bind_rule )
LIST * bind_rule = var_get( "BINDRULE" );
if ( bind_rule )
{
/* No guarantee that target is an allocated string, so be on the
* safe side */
char* target = copystr( target_ );
/* Likewise, don't rely on implementation details of newstr.c: allocate
* a copy of boundname */
char* boundname = copystr( boundname_ );
if( boundname && target )
/* 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 */
/* Prepare the argument list. */
FRAME frame[1];
frame_init( frame );
/* First argument is the target name */
/* 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 ) )
if ( lol_get( frame->args, 1 ) )
evaluate_rule( bind_rule->string, frame );
/* Clean up */
frame_free( frame );
}
else
{
if( boundname )
if ( boundname )
freestr( boundname );
if( target )
if ( target )
freestr( target );
}
}
}
/*
* search.c - find a target along $(SEARCH) or $(LOCATE)
* 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.
* 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
@@ -86,13 +94,14 @@ void call_bind_rule(
*/
char *
search(
search(
char *target,
time_t *time,
char **another_target
char **another_target,
int file
)
{
PATHNAME f[1];
PATHNAME f[1];
LIST *varlist;
string buf[1];
int found = 0;
@@ -100,29 +109,29 @@ search(
int explicitly_located = 0;
char *boundname = 0;
if( another_target )
if ( another_target )
*another_target = 0;
if (! explicit_bindings )
explicit_bindings = hashinit( sizeof(BINDING),
explicit_bindings = hashinit( sizeof(BINDING),
"explicitly specified locations");
string_new( buf );
/* Parse the filename */
path_parse( target, f );
path_parse( target, f );
f->f_grist.ptr = 0;
f->f_grist.len = 0;
if( varlist = var_get( "LOCATE" ) )
if ( ( varlist = var_get( "LOCATE" ) ) )
{
f->f_root.ptr = varlist->string;
f->f_root.len = strlen( varlist->string );
path_build( f, buf, 1 );
path_build( f, buf, 1 );
if( DEBUG_SEARCH )
if ( DEBUG_SEARCH )
printf( "locate %s: %s\n", target, buf->value );
explicitly_located = 1;
@@ -130,11 +139,12 @@ search(
timestamp( buf->value, time );
found = 1;
}
else if( varlist = var_get( "SEARCH" ) )
else if ( ( varlist = var_get( "SEARCH" ) ) )
{
while( varlist )
while ( varlist )
{
BINDING b, *ba = &b;
file_info_t *ff;
f->f_root.ptr = varlist->string;
f->f_root.len = strlen( varlist->string );
@@ -142,34 +152,38 @@ search(
string_truncate( buf, 0 );
path_build( f, buf, 1 );
if( DEBUG_SEARCH )
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 ( hashcheck( explicit_bindings, (HASHDATA**)&ba ) )
{
if( DEBUG_SEARCH )
printf(" search %s: found explicitly located target %s\n",
if ( DEBUG_SEARCH )
printf(" search %s: found explicitly located target %s\n",
target, ba->target);
if( another_target )
if ( another_target )
*another_target = ba->target;
found = 1;
break;
}
else if( *time )
{
found = 1;
break;
}
else if ( ff && ff->time )
{
if ( !file || ff->is_file )
{
found = 1;
break;
}
}
varlist = list_next( varlist );
}
}
if (!found)
if ( !found )
{
/* Look for the obvious */
/* This is a questionable move. Should we look in the */
@@ -181,7 +195,7 @@ search(
string_truncate( buf, 0 );
path_build( f, buf, 1 );
if( DEBUG_SEARCH )
if ( DEBUG_SEARCH )
printf( "search %s: %s\n", target, buf->value );
timestamp( buf->value, time );
@@ -190,17 +204,18 @@ search(
boundname = newstr( buf->value );
string_free( buf );
if (explicitly_located)
if ( explicitly_located )
{
BINDING b, *ba = &b;
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);
hashenter( explicit_bindings, (HASHDATA * *)&ba );
}
/* prepare a call to BINDRULE if the variable is set */
call_bind_rule( target, boundname );

View File

@@ -5,7 +5,7 @@
*/
/*
* search.h - find a target along $(SEARCH) or $(LOCATE)
* search.h - find a target along $(SEARCH) or $(LOCATE)
*/
char *search( char *target, time_t *time, char **another_target );
char *search( char *target, time_t *time, char **another_target, int file );

View File

@@ -24,7 +24,7 @@ static void assert_invariants( string* self )
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 );
@@ -106,10 +106,10 @@ 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;
@@ -127,10 +127,10 @@ 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;
@@ -182,7 +182,7 @@ void string_unit_test()
int limit = sizeof(buffer) > 254 ? 254 : sizeof(buffer);
string_new(s);
for (i = 0; i < limit; ++i)
{
string_push_back( s, (char)(i + 1) );
@@ -195,7 +195,7 @@ void string_unit_test()
}
string_free(s);
}
#endif

View File

@@ -22,13 +22,13 @@ 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;
}
@@ -36,13 +36,13 @@ 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 );
@@ -50,7 +50,7 @@ builtin_subst(
if ( regexec( repat, (char*)source) )
{
LIST* subst = list_next(arg1);
while ((subst = list_next(subst)) != L0)
{
# define BUFLEN 4096
@@ -88,7 +88,7 @@ builtin_subst(
}
}
}
return result;
}

View File

@@ -32,201 +32,195 @@
typedef struct _binding BINDING;
struct _binding {
char *name;
short flags;
char *name;
short flags;
# define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
# define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
short progress;
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 */
# 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 */
} ;
time_t time; /* update time - 0 if not exist */
};
static struct hash *bindhash = 0;
static void time_enter( void *, char *, int , time_t );
static struct hash * bindhash = 0;
static void time_enter( void *, char *, int, time_t );
static char *time_progress[] =
static char * time_progress[] =
{
"INIT",
"NOENTRY",
"SPOTTED",
"MISSING",
"FOUND"
} ;
"INIT",
"NOENTRY",
"SPOTTED",
"MISSING",
"FOUND"
};
/*
* timestamp() - return timestamp on a file, if present
* timestamp() - return timestamp on a file, if present.
*/
void
timestamp(
char *target,
time_t *time )
void timestamp( char * target, time_t * time )
{
PROFILE_ENTER(timestamp);
PATHNAME f1, f2;
BINDING binding, *b = &binding;
string buf[1];
string path;
char *p;
PROFILE_ENTER( timestamp );
# ifdef DOWNSHIFT_PATHS
PATHNAME f1;
PATHNAME f2;
BINDING binding;
BINDING * b = &binding;
string buf[ 1 ];
#ifdef DOWNSHIFT_PATHS
string path;
char * p;
#endif
string_copy( &path, target );
p = path.value;
#ifdef DOWNSHIFT_PATHS
string_copy( &path, target );
p = path.value;
do
do
{
*p = tolower( *p );
# ifdef NT
/* On NT, we must use backslashes or the file won't be found. */
if (*p == '/')
#ifdef NT
/* On NT, we must use backslashes or the file will not be found. */
if ( *p == '/' )
*p = PATH_DELIM;
# endif
#endif
}
while( *p++ );
while ( *p++ );
target = path.value;
# endif
string_new( buf );
target = path.value;
#endif /* #ifdef DOWNSHIFT_PATHS */
string_new( buf );
if( !bindhash )
bindhash = hashinit( sizeof( BINDING ), "bindings" );
if ( !bindhash )
bindhash = hashinit( sizeof( BINDING ), "bindings" );
/* Quick path - is it there? */
/* Quick path - is it there? */
b->name = target;
b->time = b->flags = 0;
b->progress = BIND_INIT;
b->name = target;
b->time = b->flags = 0;
b->progress = BIND_INIT;
if ( hashenter( bindhash, (HASHDATA * *)&b ) )
b->name = newstr( target ); /* never freed */
if( hashenter( bindhash, (HASHDATA **)&b ) )
b->name = newstr( target ); /* never freed */
if ( b->progress != BIND_INIT )
goto afterscanning;
if( b->progress != BIND_INIT )
goto afterscanning;
b->progress = BIND_NOENTRY;
b->progress = BIND_NOENTRY;
/* Not found - have to scan for it. */
path_parse( target, &f1 );
/* Not found - have to scan for it */
/* Scan directory if not already done so. */
{
BINDING binding;
BINDING * b = &binding;
path_parse( target, &f1 );
f2 = f1;
f2.f_grist.len = 0;
path_parent( &f2 );
path_build( &f2, buf, 0 );
/* Scan directory if not already done so */
b->name = buf->value;
b->time = b->flags = 0;
b->progress = BIND_INIT;
{
BINDING binding, *b = &binding;
if ( hashenter( bindhash, (HASHDATA * *)&b ) )
b->name = newstr( buf->value ); /* never freed */
f2 = f1;
f2.f_grist.len = 0;
path_parent( &f2 );
path_build( &f2, buf, 0 );
if ( !( b->flags & BIND_SCANNED ) )
{
file_dirscan( buf->value, time_enter, bindhash );
b->flags |= BIND_SCANNED;
}
}
b->name = buf->value;
b->time = b->flags = 0;
b->progress = BIND_INIT;
/* Scan archive if not already done so. */
if ( f1.f_member.len )
{
BINDING binding;
BINDING * b = &binding;
if( hashenter( bindhash, (HASHDATA **)&b ) )
b->name = newstr( buf->value ); /* never freed */
f2 = f1;
f2.f_grist.len = 0;
f2.f_member.len = 0;
string_truncate( buf, 0 );
path_build( &f2, buf, 0 );
if( !( b->flags & BIND_SCANNED ) )
{
file_dirscan( buf->value, time_enter, bindhash );
b->flags |= BIND_SCANNED;
}
}
b->name = buf->value;
b->time = b->flags = 0;
b->progress = BIND_INIT;
/* Scan archive if not already done so */
if ( hashenter( bindhash, (HASHDATA * *)&b ) )
b->name = newstr( buf->value ); /* never freed */
if( f1.f_member.len )
{
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;
}
}
if ( !( b->flags & BIND_SCANNED ) )
{
file_archscan( buf->value, time_enter, bindhash );
b->flags |= BIND_SCANNED;
}
}
afterscanning:
if( b->progress == BIND_SPOTTED )
{
if( file_time( b->name, &b->time ) < 0 )
b->progress = BIND_MISSING;
else
b->progress = BIND_FOUND;
}
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;
*time = b->progress == BIND_FOUND ? b->time : 0;
string_free( buf );
# ifdef DOWNSHIFT_PATHS
string_free( &path );
#ifdef DOWNSHIFT_PATHS
string_free( &path );
#endif
PROFILE_EXIT(timestamp);
PROFILE_EXIT( timestamp );
}
static void
time_enter(
void *closure,
char *target,
int found,
time_t time )
static void time_enter( void * closure, char * target, int found, time_t time )
{
BINDING binding, *b = &binding;
struct hash *bindhash = (struct hash *)closure;
BINDING binding;
BINDING * b = &binding;
struct hash * bindhash = (struct hash *)closure;
# ifdef DOWNSHIFT_PATHS
char path[ MAXJPATH ];
char *p = path;
#ifdef DOWNSHIFT_PATHS
char path[ MAXJPATH ];
char * p = path;
do *p++ = tolower( *target );
while( *target++ );
do *p++ = tolower( *target );
while ( *target++ );
target = path;
# endif
target = path;
#endif
b->name = target;
b->flags = 0;
b->name = target;
b->flags = 0;
if( hashenter( bindhash, (HASHDATA **)&b ) )
b->name = newstr( target ); /* never freed */
if ( hashenter( bindhash, (HASHDATA * *)&b ) )
b->name = newstr( target ); /* never freed */
b->time = time;
b->progress = found ? BIND_FOUND : BIND_SPOTTED;
b->time = time;
b->progress = found ? BIND_FOUND : BIND_SPOTTED;
if( DEBUG_BINDSCAN )
printf( "time ( %s ) : %s\n", target, time_progress[b->progress] );
if ( DEBUG_BINDSCAN )
printf( "time ( %s ) : %s\n", target, time_progress[ b->progress ] );
}
/*
* donestamps() - free timestamp tables
* stamps_done() - free timestamp tables.
*/
void
donestamps()
void stamps_done()
{
hashdone( bindhash );
hashdone( bindhash );
}

View File

@@ -8,5 +8,5 @@
* timestamp.h - get the timestamp of a file or archive member
*/
void timestamp( char *target, time_t *time );
void donestamps();
void timestamp( char * target, time_t * time );
void stamps_done();

View File

@@ -12,35 +12,35 @@
* (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>
#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
* 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
* 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
* 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)
@@ -57,28 +57,30 @@ static struct hash *varhash = 0;
typedef struct _variable VARIABLE ;
struct _variable {
char *symbol;
LIST *value;
} ;
struct _variable
{
char * symbol;
LIST * value;
};
static VARIABLE *var_enter( char *symbol );
static void var_dump( char *symbol, LIST *value, char *what );
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 )
void var_hash_swap( struct hash * * new_vars )
{
struct hash* old = varhash;
struct hash * old = varhash;
varhash = *new_vars;
*new_vars = old;
}
/*
* var_defines() - load a bunch of variable=value settings
*
@@ -92,224 +94,214 @@ void var_hash_swap( struct hash** new_vars )
* Otherwise, split the value at blanks.
*/
void
var_defines( char *const* e, int preprocess )
void var_defines( char * const * e, int preprocess )
{
string buf[1];
string_new( buf );
for( ; *e; e++ )
{
char *val;
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 ) ) )
/* 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, '=' ) )
if ( ( val = strchr( *e, '=' ) ) )
# endif
{
LIST *l = L0;
char *pp, *p;
{
LIST * l = L0;
char * pp;
char * p;
# ifdef OPT_NO_EXTERNAL_VARIABLE_SPLIT
char split = '\0';
char split = '\0';
# else
# ifdef OS_MAC
char split = ',';
# else
char split = ' ';
# ifdef OS_MAC
char split = ',';
# else
char split = ' ';
# endif
# endif
# endif
size_t len = strlen(val + 1);
size_t len = strlen( val + 1 );
int quoted = val[1] == '"' && val[len] == '"' && len > 1;
if ( quoted && preprocess )
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 )
{
string_append_range( buf, val + 2, val + len );
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 );
}
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;
}
l = list_new( l, newstr( pp ) );
}
/* 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 );
/* 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 )
int var_string( char * in, char * out, int outsize, LOL * lol )
{
char *out0 = out;
char *oute = out + outsize - 1;
char * out0 = out;
char * oute = out + outsize - 1;
while( *in )
while ( *in )
{
char *lastword;
int dollar = 0;
char * lastword;
int dollar = 0;
/* Copy white space */
while( isspace( *in ) )
/* Copy white space. */
while ( isspace( *in ) )
{
if( out >= oute )
if ( out >= oute )
return -1;
*out++ = *in++;
}
lastword = out;
/* Copy non-white space, watching for variables */
while( *in && !isspace( *in ) )
/* Copy non-white space, watching for variables. */
while ( *in && !isspace( *in ) )
{
if( out >= oute )
if ( out >= oute )
return -1;
if( in[0] == '$' && in[1] == '(' )
if ( ( in[ 0 ] == '$' ) && ( in[ 1 ] == '(' ) )
{
dollar++;
++dollar;
*out++ = *in++;
}
#ifdef OPT_AT_FILES
else if ( in[0] == '@' && in[1] == '(' )
else if ( ( in[ 0 ] == '@' ) && ( in[ 1 ] == '(' ) )
{
int depth = 1;
char *ine = in + 2;
char *split = 0;
char * ine = in + 2;
char * split = 0;
/* Scan the content of the response file @() section. */
while( *ine && depth > 0 )
while ( *ine && ( depth > 0 ) )
{
switch( *ine )
switch ( *ine )
{
case '(':
++depth;
break;
case ')':
--depth;
break;
case '(': ++depth; break;
case ')': --depth; break;
case ':':
if( depth == 1 && ine[1] == 'E' && ine[2] == '=' )
{
if ( ( depth == 1 ) && ( ine[ 1 ] == 'E' ) && ( ine[ 2 ] == '=' ) )
split = ine;
}
break;
}
++ine;
}
if (!split)
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 ( 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++) = ')';
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 */
/* 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,')');
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);
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);
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 )
/* 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';
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,
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,
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. */
/* 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);
/* 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 */
/* And continue with the parsing just past the @() reference. */
in = ine;
}
#endif
@@ -320,19 +312,17 @@ var_string(
}
/* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */
if (out >= oute)
if ( out >= oute )
return -1;
/* Don't increment, intentionally. */
*out= '\0';
/* If a variable encountered, expand it and and embed the */
/* space-separated members of the list in the output. */
/* Do not increment, intentionally. */
*out = '\0';
if( dollar )
/* If a variable encountered, expand it and and embed the
* space-separated members of the list in the output.
*/
if ( dollar )
{
LIST *l;
l = var_expand( L0, lastword, out, lol, 0 );
LIST * l = var_expand( L0, lastword, out, lol, 0 );
out = lastword;
@@ -340,8 +330,8 @@ var_string(
{
int so = strlen( l->string );
if( out + so >= oute )
return -1;
if ( out + so >= oute )
return -1;
strcpy( out, l->string );
out += so;
@@ -353,7 +343,7 @@ var_string(
}
}
if( out >= oute )
if ( out >= oute )
return -1;
*out++ = '\0';
@@ -361,9 +351,10 @@ var_string(
return out - out0;
}
void var_string_to_file( const char * in, int insize, const char * out, LOL * lol )
{
const char * ine = in+insize;
char const * ine = in + insize;
FILE * out_file = 0;
int out_debug = DEBUG_EXEC ? 1 : 0;
if ( globs.noexec )
@@ -382,64 +373,57 @@ void var_string_to_file( const char * in, int insize, const char * out, LOL * lo
{
/* Handle "path to file" filenames. */
string out_name;
if ( out[0] == '"' && out[strlen(out) - 1] == '"' )
if ( ( out[ 0 ] == '"' ) && ( out[ strlen( out ) - 1 ] == '"' ) )
{
string_copy(&out_name,out+1);
string_truncate(&out_name,out_name.size-1);
string_copy( &out_name, out + 1 );
string_truncate( &out_name, out_name.size - 1 );
}
else
{
string_copy(&out_name,out);
string_copy( &out_name,out );
}
out_file = fopen( out_name.value, "w" );
if (!out_file)
if ( !out_file )
{
printf( "failed to write output file '%s'!\n", out_name.value );
exit( EXITBAD );
}
string_free(&out_name);
string_free( &out_name );
}
if ( out_debug ) printf("\nfile %s\n",out);
if ( out_debug ) printf( "\nfile %s\n", out );
while( *in && in < ine )
while ( *in && ( in < ine ) )
{
int dollar = 0;
const char * output_0 = in;
const char * output_1 = in;
/* Copy white space */
while ( output_1 < ine && *output_1 && isspace( *output_1 ) )
{
/* 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);
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 ) )
/* Copy non-white space, watching for variables. */
while ( ( output_1 < ine ) && *output_1 && !isspace( *output_1 ) )
{
if( output_1[0] == '$' && output_1[1] && output_1[1] == '(' )
{
dollar++;
}
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 )
/* If a variable encountered, expand it and embed the space-separated
* members of the list in the output.
*/
if ( dollar )
{
LIST *l;
l = var_expand( L0, (char*)output_0, (char*)output_1, lol, 0 );
LIST * l = var_expand( L0, (char *)output_0, (char *)output_1, lol, 0 );
while ( l )
{
@@ -457,45 +441,59 @@ void var_string_to_file( const char * in, int insize, const char * out, LOL * lo
}
else 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);
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 )
if ( out_file && ( out_file != stdout ) && ( out_file != stderr ) )
{
fflush( out_file );
fclose( out_file );
}
if ( out_debug ) fputc('\n',stdout);
if ( out_debug ) fputc( '\n', stdout );
}
/*
* var_get() - get value of a user defined symbol
* var_get() - get value of a user defined symbol.
*
* Returns NULL if symbol unset.
*/
LIST *
var_get( char *symbol )
LIST * var_get( char * symbol )
{
LIST * result = 0;
#ifdef OPT_AT_FILES
#ifdef OPT_AT_FILES
/* Some "fixed" variables... */
if ( strcmp( "TMPDIR", symbol ) == 0 )
{
result = list_new( L0, newstr( (char*)path_tmpdir() ) );
result = list_new( L0, newstr( (char *)path_tmpdir() ) );
}
else if ( strcmp( "TMPNAME", symbol ) == 0 )
{
result = list_new( L0, newstr( (char*)path_tmpnam() ) );
result = list_new( L0, newstr( (char *)path_tmpnam() ) );
}
else if ( strcmp( "TMPFILE", symbol ) == 0 )
{
result = list_new( L0, newstr( (char*)path_tmpfile() ) );
result = list_new( L0, newstr( (char *)path_tmpfile() ) );
}
else if ( strcmp( "STDOUT", symbol ) == 0 )
{
@@ -506,15 +504,16 @@ var_get( char *symbol )
result = list_new( L0, newstr( "STDERR" ) );
}
else
#endif
#endif
{
VARIABLE var, *v = &var;
VARIABLE var;
VARIABLE * v = &var;
v->symbol = symbol;
if( varhash && hashcheck( varhash, (HASHDATA **)&v ) )
if ( varhash && hashcheck( varhash, (HASHDATA * *)&v ) )
{
if( DEBUG_VARGET )
if ( DEBUG_VARGET )
var_dump( v->symbol, v->value, "get" );
result = v->value;
}
@@ -522,122 +521,111 @@ var_get( char *symbol )
return result;
}
/*
* var_set() - set a variable in jam's user defined symbol table
* 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.
* '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.
* Copies symbol. Takes ownership of value.
*/
void
var_set(
char *symbol,
LIST *value,
int flag )
void var_set( char * symbol, LIST * value, int flag )
{
VARIABLE *v = var_enter( symbol );
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;
if ( DEBUG_VARSET )
var_dump( symbol, value, "set" );
case VAR_APPEND:
/* Append value */
v->value = list_append( v->value, value );
break;
switch ( flag )
{
case VAR_SET:
/* Replace value */
list_free( v->value );
v->value = value;
break;
case VAR_DEFAULT:
/* Set only if unset */
if( !v->value )
v->value = value;
else
list_free( 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
* var_swap() - swap a variable's value with the given one.
*/
LIST *
var_swap(
char *symbol,
LIST *value )
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;
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
* var_enter() - make new var symbol table entry, returning var ptr.
*/
static VARIABLE *
var_enter( char *symbol )
static VARIABLE * var_enter( char * symbol )
{
VARIABLE var, *v = &var;
VARIABLE var;
VARIABLE * v = &var;
if( !varhash )
varhash = hashinit( sizeof( VARIABLE ), "variables" );
if ( !varhash )
varhash = hashinit( sizeof( VARIABLE ), "variables" );
v->symbol = symbol;
v->value = 0;
v->symbol = symbol;
v->value = 0;
if( hashenter( varhash, (HASHDATA **)&v ) )
v->symbol = newstr( symbol ); /* never freed */
if ( hashenter( varhash, (HASHDATA * *)&v ) )
v->symbol = newstr( symbol ); /* never freed */
return v;
return v;
}
/*
* var_dump() - dump a variable to stdout
* var_dump() - dump a variable to stdout.
*/
static void
var_dump(
char *symbol,
LIST *value,
char *what )
static void var_dump( char * symbol, LIST * value, char * what )
{
printf( "%s %s = ", what, symbol );
list_print( value );
printf( "\n" );
printf( "%s %s = ", what, symbol );
list_print( value );
printf( "\n" );
}
/*
* var_done() - free variable tables
* var_done() - free variable tables.
*/
static void delete_var_( void* xvar, void* data )
static void delete_var_( void * xvar, void * data )
{
VARIABLE *v = (VARIABLE*)xvar;
VARIABLE * v = (VARIABLE *)xvar;
freestr( v->symbol );
list_free( v-> value );
}
void
var_done()
void var_done()
{
hashenumerate( varhash, delete_var_, (void*)0 );
hashdone( varhash );
hashenumerate( varhash, delete_var_, (void *)0 );
hashdone( varhash );
}

View File

@@ -10,12 +10,12 @@
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_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.
@@ -29,7 +29,7 @@ void var_string_to_file( const char * in, int insize, const char * out, LOL * lo
* 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 */
# 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 */

View File

@@ -65,23 +65,23 @@ builtin_system_registry(
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)
&& 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;
@@ -101,7 +101,7 @@ builtin_system_registry(
string_free( expanded );
}
break;
case REG_MULTI_SZ:
{
char* s;
@@ -111,7 +111,7 @@ builtin_system_registry(
}
break;
case REG_DWORD:
{
char buf[100];
@@ -133,9 +133,9 @@ builtin_system_registry(
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)
if ( ERROR_SUCCESS ==
RegOpenKeyEx(key, path, 0, KEY_ENUMERATE_SUB_KEYS, &key)
)
{
char name[MAX_REGISTRY_KEYNAME_LENGTH];
@@ -143,47 +143,47 @@ static LIST* get_subkey_names(HKEY key, char const* path)
DWORD index;
FILETIME last_write_time;
for ( index = 0;
for ( index = 0;
ERROR_SUCCESS == RegEnumKeyEx(
key, index, name, &name_size, 0, 0, 0, &last_write_time);
++index,
++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;
for ( index = 0;
ERROR_SUCCESS == RegEnumValue(
key, index, name, &name_size, 0, 0, 0, 0);
++index,
++index,
name_size = sizeof(name)
)
{
name[name_size] = 0;
result = list_append(result, list_new(0, newstr(name)));
}
RegCloseKey(key);
}
return result;
}
@@ -194,7 +194,7 @@ builtin_system_registry_names(
{
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") )

View File

@@ -11,11 +11,11 @@
/*
# yyacc - yacc wrapper
#
# Allows tokens to be written as `literal` and then automatically
# Allows tokens to be written as `literal` and then automatically
# substituted with #defined tokens.
#
# Usage:
# yyacc file.y filetab.h file.yy
# yyacc file.y filetab.h file.yy
#
# inputs:
# file.yy yacc grammar with ` literals
@@ -59,7 +59,7 @@ int main(int argc, char ** argv)
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)
@@ -223,7 +223,7 @@ char * tokenize_string(char * s)
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";