From 707a00af04500b408fe4914f69e1a90ca5bb3de1 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 5 Feb 2004 00:06:33 +0000 Subject: [PATCH] Merged in the jam2.5rc3 changes and fixed conflicts with patches. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6502 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tools/jam/Jambase | 439 ++++++++++++++++------ src/tools/jam/Jamfile | 2 +- src/tools/jam/Makefile | 11 +- src/tools/jam/compile.c | 374 ++++++++++++------- src/tools/jam/compile.h | 59 +-- src/tools/jam/hcache.c | 8 +- src/tools/jam/hcache.h | 2 +- src/tools/jam/headers.c | 104 +++--- src/tools/jam/headers.h | 3 +- src/tools/jam/jam.c | 88 +++-- src/tools/jam/jam.h | 27 +- src/tools/jam/jambase.c | 175 ++++++--- src/tools/jam/jamgram.c | 736 +++++++++++++++++++------------------ src/tools/jam/jamgram.h | 55 +-- src/tools/jam/jamgram.y | 74 ++-- src/tools/jam/jamgram.yy | 71 ++-- src/tools/jam/jamgramtab.h | 3 + src/tools/jam/jcache.c | 4 +- src/tools/jam/make.c | 237 +++++++----- src/tools/jam/parse.c | 54 ++- src/tools/jam/parse.h | 37 +- src/tools/jam/scan.c | 42 ++- 22 files changed, 1569 insertions(+), 1036 deletions(-) diff --git a/src/tools/jam/Jambase b/src/tools/jam/Jambase index 93ca0064ee..e11ded1027 100644 --- a/src/tools/jam/Jambase +++ b/src/tools/jam/Jambase @@ -7,7 +7,7 @@ # # -# JAMBASE - jam 2.3 ruleset providing make(1)-like functionality +# JAMBASE - jam 2.5 ruleset providing make(1)-like functionality # # Supports UNIX, NT, and VMS. # @@ -104,6 +104,8 @@ # FGristFiles value ; return $(value:G=$(SOURCE_GRIST)) # FGristSourceFiles value ; return $(value:G=$(SOURCE_GRIST)) # FIsPrefix a : b ; return whether or not a is a prefix of b +# FStripCommon v1 : v2 ; strip common initial parts of v1 v2 +# FReverse a1 a2 ... ; return ... a2 a1 # FRelPath d1 : d2 ; return rel path from d1 to d2 # FSubDir d1 d2 ... ; return path to root # @@ -141,7 +143,7 @@ # $(>) - sources of a rule (to the right of the :) # $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC) # $(OS) - name of OS - varies wildly -# $(JAMVERSION) - version number (2.3) +# $(JAMVERSION) - version number (2.5) # # Special variables used by jam: # SEARCH - where to find something (used during binding and actions) @@ -153,6 +155,10 @@ # all - default if none given on command line # +# for perforce use -- jambase version + +JAMBASEDATE = 2002.05.09 ; + # Initialize variables # @@ -165,6 +171,7 @@ if $(NT) MV ?= move /y ; CP ?= copy ; RM ?= del /f/q ; + RMDIR ?= rmdir /s/q ; SLASH ?= \\ ; SUFLIB ?= .lib ; SUFOBJ ?= .obj ; @@ -172,8 +179,6 @@ if $(NT) if $(BCCROOT) { - Echo "Compiler is Borland C++" ; - AR ?= tlib /C /P64 ; CC ?= bcc32 ; CCFLAGS ?= -v -w- -q -DWIN -tWR -tWM -tWC ; @@ -187,8 +192,6 @@ if $(NT) } else if $(MSVC) { - Echo "Compiler is Microsoft Visual C++ 16 bit" ; - AR ?= lib /nologo ; CC ?= cl /nologo ; CCFLAGS ?= /D \"WIN\" ; @@ -197,12 +200,8 @@ if $(NT) LINK ?= $(CC) ; LINKFLAGS ?= $(CCFLAGS) ; LINKLIBS ?= - #$(MSVC)\\lib\\advapi32.lib - #$(MSVC)\\lib\\libcmt.lib $(MSVC)\\lib\\mlibce.lib - #$(MSVC)\\lib\\slibce.lib $(MSVC)\\lib\\oldnames.lib - #$(MSVC)\\lib\\kernel32.lib ; LINKLIBS ?= ; NOARSCAN ?= true ; @@ -210,9 +209,15 @@ if $(NT) STDHDRS ?= $(MSVC)\\include ; UNDEFFLAG ?= "/u _" ; } - else if $(MSVCNT) + else if $(MSVCNT) || $(MSVCDIR) { - Echo "Compiler is Microsoft Visual C++" ; + # Visual C++ 6.0 uses MSVCDIR + + MSVCNT ?= $(MSVCDIR) ; + + # bury IA64 in the path for the SDK + + local I ; if $(OSPLAT) = IA64 { I = ia64\\ ; } else { I = "" ; } AR ?= lib ; AS ?= masm386 ; @@ -222,18 +227,18 @@ if $(NT) C++FLAGS ?= $(CCFLAGS) ; LINK ?= link /nologo ; LINKFLAGS ?= "" ; - LINKLIBS ?= $(MSVCNT)\\lib\\advapi32.lib - $(MSVCNT)\\lib\\libc.lib - $(MSVCNT)\\lib\\oldnames.lib - $(MSVCNT)\\lib\\kernel32.lib ; + LINKLIBS ?= + $(MSVCNT)\\lib\\$(I)libc.lib + $(MSVCNT)\\lib\\$(I)oldnames.lib + $(MSVCNT)\\lib\\$(I)kernel32.lib ; OPTIM ?= "" ; STDHDRS ?= $(MSVCNT)\\include ; UNDEFFLAG ?= "/u _" ; } else { - Exit On NT, set BCCROOT, MSVCNT, or MSVC to the root of the - Borland or Microsoft directories. ; + EXIT On NT, set BCCROOT, MSVCDIR, MSVCNT, or MSVC to the root + of the Borland or Microsoft directories. ; } } @@ -331,24 +336,24 @@ else if $(MAC) "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ; MPWLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib" ; + "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" + "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ; MPWNLLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW(NL).Lib" ; + "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" + "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ; SIOUXHDRS ?= ; SIOUXLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL SIOUX.PPC.Lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC.Lib" ; + "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib" + "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib" + "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ; C++ ?= mwcppc ; - C++FLAGS ?= -w off -nomapcr ; + C++FLAGS ?= -w off ; CC ?= mwcppc ; - CCFLAGS ?= -w off -nomapcr ; + CCFLAGS ?= -w off ; CP ?= duplicate -y ; DOT ?= ":" ; DOTDOT ?= "::" ; @@ -378,12 +383,13 @@ else if $(OS) = BEOS && $(OSPLAT) = PPC CHGRP ?= chgrp ; CHOWN ?= chown ; FORTRAN ?= "" ; - LEX ?= flex ; + LEX ?= flex ; LIBDIR ?= /boot/home/config/lib ; LINK ?= mwld ; LINKFLAGS ?= "" ; MANDIR ?= /boot/home/config/man ; NOARSCAN ?= true ; + RANLIB ?= ranlib ; STDHDRS ?= /boot/develop/headers/posix ; YACC ?= bison -y ; YACCGEN ?= .c ; @@ -399,7 +405,7 @@ else if $(OS) = BEOS CHGRP ?= chgrp ; CHOWN ?= chown ; FORTRAN ?= "" ; - LEX ?= flex ; + LEX ?= flex ; LIBDIR ?= /boot/home/config/lib ; LINK ?= gcc ; MANDIR ?= /boot/home/config/man ; @@ -463,10 +469,8 @@ else if $(UNIX) RANLIB ?= "" ; case MACOSX : - AR ?= libtool -o ; C++ ?= c++ ; MANDIR ?= /usr/local/share/man ; - RANLIB ?= "" ; case NCR : RANLIB ?= "" ; @@ -560,12 +564,15 @@ else if $(UNIX) OPTIM ?= ; RCP ?= rcp ; RM ?= rm -f ; + RMDIR ?= $(RM) ; RSH ?= rsh ; SED ?= sed ; SHELLHEADER ?= "#!/bin/sh" ; SHELLMODE ?= 755 ; SLASH ?= / ; STDHDRS ?= /usr/include ; + SUBDIRRULES ?= ; + SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ; SUFEXE ?= "" ; SUFLIB ?= .a ; SUFOBJ ?= .o ; @@ -886,7 +893,7 @@ rule LibraryFromObjects # If we can't scan the library, we have to leave the .o's around. - if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(_l) : $(_s) ; } + if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; } } rule Link @@ -965,37 +972,52 @@ rule MainFromObjects rule MakeLocate { + # MakeLocate targets : directory ; + + # Sets special variable LOCATE on targets, and arranges + # with MkDir to create target directory. + + # Note we grist the directory name with 'dir', + # so that directory path components and other + # targets don't conflict. + if $(>) { LOCATE on $(<) = $(>) ; - Depends $(<) : $(>[1]) ; - MkDir $(>[1]) ; + Depends $(<) : $(>[1]:G=dir) ; + MkDir $(>[1]:G=dir) ; } } rule MkDir { - # If dir exists, don't update it - # Do this even for $(DOT). + # MkDir directory ; + + # Make a directory and all its parent directories. + + # Ignore timestamps on directories: we only care if they + # exist. NoUpdate $(<) ; - if $(<) != $(DOT) && ! $($(<)-mkdir) - { - local s ; + # Don't create . or any directory already created. + if $(<:G=) != $(DOT) && ! $($(<)-mkdir) + { # Cheesy gate to prevent multiple invocations on same dir - # MkDir1 has the actions # Arrange for jam dirs + # MkDir1 has the actions $(<)-mkdir = true ; - MkDir1 $(<) ; LocalDepends dirs : $(<) ; + MkDir1 $(<) ; # Recursively make parent directories. # $(<:P) = $(<)'s parent, & we recurse until root - s = $(<:P) ; + local s = $(<:P) ; + + # Don't try to create A: or A:\ on windows if $(NT) { @@ -1006,16 +1028,21 @@ rule MkDir } } - if $(s) && $(s) != $(<) + if $(s) = $(<) { + # The parent is the same as the dir. + # We're at the root, which some OS's can't stat, so we mark + # it as NotFile. + + NotFile $(s) ; + } + else if $(s:G=) + { + # There's a parent; recurse. + Depends $(<) : $(s) ; MkDir $(s) ; } - else if $(s) - { - NotFile $(s) ; - } - } } @@ -1151,65 +1178,190 @@ rule SoftLink rule SubDir { # - # SubDir TOP d1 [ ... ] + # SubDir TOP d1 d2 ... ; # - # 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. + # Support for a project tree spanning multiple directories. # - # If the variable $(TOPRULES) is set (where TOP is the first arg - # to SubDir), that file is included instead of $(TOP)/Jamrules. + # SubDir declares a Jamfile's location in a project tree, setting + # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source + # files can be found. + # + # TOP is a user-select variable name for root of the tree, and + # d1 d2 ... are the directory elements that lead from the root + # of the tree to the directory of the Jamfile. + # + # TOP can be set externally, but normally the first SubDir call + # computes TOP as the path up from the current directory; the + # path contains one ../ for each of d1 d2 ... + # + # SubDir reads once the project-specific rules file Jamrules + # in the TOP directory, if present. This can be overridden + # with the variable TOPRULES. + # + # SubDir supports multiple, overlaid project trees: SubDir + # invocations with different TOPs can appear in the same Jamfile. + # The location established by the first SubDir call is used set + # the TOPs for the subsequent SubDir calls. + # + # SubDir's public variables: + # + # $(TOP) = path from CWD to root. + # $(SUBDIR) = path from CWD to the directory SubDir names. + # $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names + # $(SEARCH_SOURCE) = $(SUBDIR) + # $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR) + # $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR) + # $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s # - # 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. - # local _top = $(<[1]) ; + local _tokens = $(<[2-]) ; - if ! $($(_top)) + # + # First time through sets up relative root and includes Jamrules. + # + + if ! $(_top) { - if ! $(_top) + Exit SubDir syntax error ; + } + + if ! $($(_top)-SET) + { + $(_top)-SET = true ; + + # First time we've seen this TOP. + # We'll initialize a number of internal variables: + # + # $(TOP-UP) = directories from ROOT to a common point + # $(TOP-DOWN) = directories from common point to TOP + # $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD + # $(SUBDIR_UP) = current value of $(TOP-UP) + # $(SUBDIR_DOWN) = current value of $(TOP-DOWN) + # $(SUBDIR_ROOT) = current value of $(TOP-ROOT) + # + + if $($(_top)) { - Exit SubDir syntax error ; + # TOP externally set. + # We'll ignore the relative (UP/DOWN) path that + # got us here, and instead remember the hard ROOT. + + $(_top)-UP = ; + $(_top)-DOWN = ; + $(_top)-ROOT = $($(_top)) ; + } + else + { + # TOP not preset. + + # Establishing a new TOP. In the simplest case, + # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's + # merely a certain number of directories down from + # the current directory, and FSubDirPath will set + # TOP to a path consisting of ../ for each of the + # elements of _tokens, because that represents how + # far below TOP the current directory sits. + # + # In the more complicated case, the starting directory + # isn't the directory of jam's invocation but an + # location established by previous SubDir call. The + # starting directory is SUBDIR_UP directories up from + # SUBDIR_ROOT, and then SUBDIR_DOWN directories down + # from that. If SUBDIR_ROOT is not set, that means + # SUBDIR_DOWN and SUBDIR_UP represent the path from + # the directory of jam's invocation. + # + # In the most complicated case, the _tokens also + # represents directories down, because TOP is being + # estalished in a directory other than TOP's root. + # Hopefully, _tokens and SUBDIR_DOWN represent the + # same final directory, relative to the new TOP and + # the previous SubDIr's TOP. To find the new TOP, + # we have to chop off any common directories from + # then ends of _tokens and SUBDIR_DOWN. To do so, + # we reverse each of them, call FStripCommon to + # remove the initial common elements, and then + # reverse them again. After this process, if + # both _tokens and SUBDIR_DOWN have elements, it + # means the directory names estalished by the two + # SubDir calls don't match, and a warning is issued. + # All hell will likely break loose at this point, + # since the whole SubDir scheme relies on the SubDir + # calls accurately naming the current directory. + + # Strip common trailing elements of _tokens and SUBDIR_DOWN. + + _tokens = [ FReverse $(_tokens) ] ; + SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ; + FStripCommon _tokens : SUBDIR_DOWN ; + SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ; + _tokens = [ FReverse $(_tokens) ] ; + + if $(SUBDIR_DOWN) && $(_tokens) + { + Echo Warning: SubDir $(<) misplaced! ; + } + + # We'll remember the relative (UP/DOWN) path that + # got us here, plus any hard ROOT starting point + # for the UP/DOWN. If TOP is never set externally, + # ROOT will always be "" (directory of jam's invocation). + + $(_top)-UP = $(SUBDIR_UP) $(_tokens) ; + $(_top)-DOWN = $(SUBDIR_DOWN) ; + $(_top)-ROOT = $(SUBDIR_ROOT:E="") ; + $(_top) = [ FSubDirPath $(_top) ] ; } - $(_top) = [ FSubDir $(<[2-]) ] ; - } + # Set subdir vars for the inclusion of the Jamrules, + # just in case they have SubDir rules of their own. + # Note that SUBDIR_DOWN is empty: it's all the way + # up where the Jamrules live. These gets overrided + # just after the inclusion. - # If we are the first Jamfile, include the top Jamfile and stop processing - # this file any further. - # - if ! $(INVOCATION_SUBDIR_SET) { - INVOCATION_SUBDIR_SET = true ; - INVOCATION_SUBDIR = $(<[2-]) ; - if $(INVOCATION_SUBDIR) { - SubInclude $(_top) ; - jumptoeof ; + SUBDIR_UP = $($(_top)-UP) ; + SUBDIR_DOWN = ; + SUBDIR_ROOT = $($(_top)-ROOT) ; + + # Include $(TOPRULES) or $(TOP)/Jamrules. + # Include $(TOPRULES) if set. + # Otherwise include $(TOP)/Jamrules if present. + + if $($(_top)RULES) { + include $($(_top)RULES) ; + } else { + NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ; + include $(JAMRULES:R=$($(_top)):G=$(_top)) ; + } + + ## LOCAL CHANGE + # + # If we are the first Jamfile, we include the top Jamfile of this + # tree and stop processing. + # + if ! $(INVOCATION_SUBDIR_SET) { + INVOCATION_SUBDIR_SET = true ; + INVOCATION_SUBDIR_TOP = $(_top) ; + INVOCATION_SUBDIR = $(_tokens) ; + if $(INVOCATION_SUBDIR) { + SubInclude $(_top) ; + jumptoeof ; + } } + # + ## LOCAL CHANGE } - # - # If $(TOP)/Jamrules hasn't been included, do so. - # - - if ! $($(_top)-included) - { - # Gated entry. - - $(_top)-included = TRUE ; - - # File is $(TOPRULES) or $(TOP)/Jamrules. - - include $($(_top)RULES:E=$(JAMRULES:R=$($(_top)))) ; - } - - # Get path to current directory from root using SubDir. + # Get path from $(TOP) to named directory. # Save dir tokens for other potential uses. - local _s = [ FDirName $(<[2-]) ] ; - SUBDIR = $(_s:R=$($(_top))) ; - SUBDIR_TOKENS = $(<[2-]) ; + SUBDIR_UP = $($(_top)-UP) ; + SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ; + SUBDIR_ROOT = $($(_top)-ROOT) ; + SUBDIR_TOKENS = $(SUBDIR_DOWN) ; + + SUBDIR = [ FSubDirPath $(<) ] ; # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST # These can be reset if needed. For example, if the source @@ -1219,7 +1371,8 @@ rule SubDir SEARCH_SOURCE = $(SUBDIR) ; LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ; LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ; - SOURCE_GRIST = [ FGrist $(<[2-]) ] ; + SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ; + ## LOCAL CHANGE -- OPT_HEADER_CACHE_EXT. With the header # cache, we can grist all files found during a header scan # without incurring a performance penalty. @@ -1228,11 +1381,35 @@ rule SubDir # ## LOCAL CHANGE - # Reset per-directory ccflags, hdrs + # Reset per-directory ccflags, hdrs, etc, + # listed in SUBDIRRESET. + # Note use of variable expanded assignment var - SUBDIRCCFLAGS = ; - SUBDIRC++FLAGS = ; - SUBDIRHDRS = ; + SUBDIR$(SUBDIRRESET) = ; + + # Invoke user-specific SubDir extensions, + # rule names listed in SUBDIRRULES. + # Note use of variable expanded rule invocation + + $(SUBDIRRULES) $(<) ; +} + +rule FSubDirPath +{ + # FSubDirPath TOP d1 ... ; + + # Returns path to named directory. + + # If jam is invoked in a subdirectory of the TOP, then we + # need to prepend a ../ for every level we must climb up + # (TOP-UP), and then append the directory names we must + # climb down (TOP-DOWN), plus the named directories d1 ... + # If TOP was set externally, or computed from another TOP + # that was, we'll have to reroot the whole thing at TOP-ROOT. + + local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ; + + return $(_r:R=$($(<[1])-ROOT)) ; } rule SubDirCcFlags @@ -1252,21 +1429,38 @@ rule SubDirHdrs rule SubInclude { - local _s ; - - # That's - # SubInclude TOP d1 [ d2 [ d3 [ d4 ] ] ] + # SubInclude TOP d1 ... ; # - # to include a subdirectory's Jamfile. + # Include a subdirectory's Jamfile. + + # We use SubDir to get there, in case the included Jamfile + # either doesn't have its own SubDir (naughty) or is a subtree + # with its own TOP. if ! $($(<[1])) { - Exit Top level of source tree has not been set with $(<[1]) ; + Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ; } - _s = [ FDirName $(<[2-]) ] ; - - include $(JAMFILE:D=$(_s):R=$($(<[1]))) ; + SubDir $(<) ; + + include $(JAMFILE:D=$(SUBDIR)) ; +} + +rule SubRules +{ + # SubRules TOP d1 ... : Other-TOP ; + # + # Read another tree's Jamrules, by giving it's path according + # to this tree and it's own name. + + if ! $($(<[1])) + { + Exit SubRules $(<[1]) without prior SubDir $(<[1]) ; + } + + SubDir $(<) ; + SubDir $(>) ; } rule Undefines @@ -1375,6 +1569,14 @@ rule FIsPrefix } } +rule FReverse +{ + # FReverse a1 a2 a3 ... ; + # return ... a3 a2 a1 ; + + if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; } +} + rule FSubDir { # If $(>) is the path to the current directory, compute the @@ -1400,15 +1602,18 @@ rule FSubDir } } -rule _makeCommon +rule FStripCommon { - # strip common initial elements + # FStripCommon v1 : v2 ; + + # Strip common initial elements of variables v1 and v2. + # Modifies the variable values themselves. if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) { $(<) = $($(<)[2-]) ; $(>) = $($(>)[2-]) ; - _makeCommon $(<) : $(>) ; + FStripCommon $(<) : $(>) ; } } @@ -1421,7 +1626,7 @@ rule FRelPath _l = $(<) ; _r = $(>) ; - _makeCommon _l : _r ; + FStripCommon _l : _r ; # now make path to root and path down @@ -1716,6 +1921,19 @@ if $(NOARUPDATE) } } +# +# UNIX specific actions +# + +if $(UNIX) +{ + actions GenFile1 + { + PATH="$PATH:." + $(>[1]) $(<) $(>[2-]) + } +} + # # NT specific actions # @@ -1939,7 +2157,8 @@ rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; } # Compatibility with jam 2.2. rule addDirName { $(<) += [ FDirName $(>) ] ; } -rule makeCommon { _makeCommon $(<) : $(>) ; } +rule makeCommon { FStripCommon $(<) : $(>) ; } +rule _makeCommon { FStripCommon $(<) : $(>) ; } rule makeDirName { $(<) = [ FDirName $(>) ] ; } rule makeGrist { $(<) = [ FGrist $(>) ] ; } rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; } diff --git a/src/tools/jam/Jamfile b/src/tools/jam/Jamfile index 60ec2f223f..846f97b2b3 100644 --- a/src/tools/jam/Jamfile +++ b/src/tools/jam/Jamfile @@ -153,7 +153,7 @@ rule Ball } } -VERSION = jam-2.4 ; +VERSION = jam-2.5rc1 ; actions Tar { diff --git a/src/tools/jam/Makefile b/src/tools/jam/Makefile index 6aa3d20a32..bf60c3b4f8 100644 --- a/src/tools/jam/Makefile +++ b/src/tools/jam/Makefile @@ -1,8 +1,9 @@ # Makefile for jam CC = cc -TARGET = -o jam0 CFLAGS = +EXENAME = ./jam0 +TARGET = -o $(EXENAME) # Special flavors - uncomment appropriate lines @@ -22,12 +23,14 @@ CFLAGS = #CFLAGS = -I $(Include) -DNT #TARGET = /Fejam0 #LINKLIBS = $(Lib)/oldnames.lib $(Lib)/kernel32.lib $(Lib)/libc.lib +#EXENAME = .\jam0.exe # NT (with Microsoft compiler) # People with DevStudio settings already in shell environment. #CC = cl /nologo #CFLAGS = -DNT #TARGET = /Fejam0 +#EXENAME = .\jam0.exe # Interix - gcc #CC = gcc @@ -55,8 +58,8 @@ SOURCES = \ newstr.c option.c parse.c pathunix.c pathvms.c regexp.c \ rules.c scan.c search.c timestamp.c variable.c -all: jam0 - ./jam0 +all: $(EXENAME) + $(EXENAME) -jam0: +$(EXENAME): $(CC) $(TARGET) $(CFLAGS) $(SOURCES) $(LINKLIBS) diff --git a/src/tools/jam/compile.c b/src/tools/jam/compile.c index deec64992d..94c1bdc4b9 100644 --- a/src/tools/jam/compile.c +++ b/src/tools/jam/compile.c @@ -4,23 +4,13 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" - -# include "lists.h" -# include "parse.h" -# include "compile.h" -# include "variable.h" -# include "expand.h" -# include "rules.h" -# include "newstr.h" -# include "search.h" - /* * compile.c - compile parsed jam statements * * External routines: * * compile_append() - append list results of two statements + * compile_break() - compile 'break/continue/return' rule * compile_eval() - evaluate if to determine which leg to compile * compile_foreach() - compile the "for x in y" statement * compile_if() - compile 'if' rule @@ -55,16 +45,43 @@ * 01/22/95 (seiwald) - Exit rule. * 02/02/95 (seiwald) - Always rule; LEAVES rule. * 02/14/95 (seiwald) - NoUpdate rule. + * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C + * 09/07/00 (seiwald) - stop crashing when a rule redefines itself * 09/11/00 (seiwald) - new evaluate_rule() for headers(). - * 09/11/00 (seiwald) - compile_xxx() now return LIST *. - * New compile_append() and compile_list() in - * support of building lists here, rather than - * in jamgram.yy. - * 01/10/00 (seiwald) - built-ins split out to builtin.c. + * 09/11/00 (seiwald) - rules now return values, accessed via [ rule arg ... ] + * 09/12/00 (seiwald) - don't complain about rules invoked without targets + * 01/13/01 (seiwald) - fix case where rule is defined within another + * 01/10/01 (seiwald) - built-ins split out to builtin.c. + * 01/11/01 (seiwald) - optimize compile_rules() for tail recursion + * 01/21/01 (seiwald) - replace evaluate_if() with compile_eval() + * 01/24/01 (seiwald) - 'while' statement + * 03/23/01 (seiwald) - "[ on target rule ]" support + * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx + * 03/02/02 (seiwald) - rules can be invoked via variable names + * 03/12/02 (seiwald) - &&,&,||,|,in now short-circuit again + * 03/25/02 (seiwald) - if ( "" a b ) one again returns true + * 06/21/02 (seiwald) - support for named parameters + * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() + * 10/22/02 (seiwald) - working return/break/continue statements + * 11/04/02 (seiwald) - const-ing for string literals + * 11/18/02 (seiwald) - remove bogus search() in 'on' statement. + * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars */ -static void debug_compile( int which, char *s ); -int glob( char *s, char *c ); +# include "jam.h" + +# include "lists.h" +# include "parse.h" +# include "compile.h" +# include "variable.h" +# include "expand.h" +# include "rules.h" +# include "newstr.h" +# include "search.h" + +static const char *set_names[] = { "=", "+=", "?=" }; +static void debug_compile( int which, const char *s ); +int glob( const char *s, const char *c ); @@ -78,13 +95,32 @@ int glob( char *s, char *c ); LIST * compile_append( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { /* Append right to left. */ return list_append( - (*parse->left->func)( parse->left, args ), - (*parse->right->func)( parse->right, args ) ); + (*parse->left->func)( parse->left, args, jmp ), + (*parse->right->func)( parse->right, args, jmp ) ); +} + +/* + * compile_break() - compile 'break/continue/return' rule + * + * parse->left results + * parse->num JMP_BREAK/CONTINUE/RETURN + */ + +LIST * +compile_break( + PARSE *parse, + LOL *args, + int *jmp ) +{ + LIST *lv = (*parse->left->func)( parse->left, args, jmp ); + *jmp = parse->num; + return lv; } /* @@ -102,8 +138,8 @@ lcmp( LIST *t, LIST *s ) while( !status && ( t || s ) ) { - char *st = t ? t->string : ""; - char *ss = s ? s->string : ""; + const char *st = t ? t->string : ""; + const char *ss = s ? s->string : ""; status = strcmp( st, ss ); @@ -117,14 +153,15 @@ lcmp( LIST *t, LIST *s ) LIST * compile_eval( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { LIST *ll, *lr, *s, *t; int status = 0; /* Short circuit lr eval for &&, ||, and 'in' */ - ll = (*parse->left->func)( parse->left, args ); + ll = (*parse->left->func)( parse->left, args, jmp ); lr = 0; switch( parse->num ) @@ -132,7 +169,7 @@ compile_eval( case EXPR_AND: case EXPR_IN: if( ll ) goto eval; break; case EXPR_OR: if( !ll ) goto eval; break; - default: eval: lr = (*parse->right->func)( parse->right, args ); + default: eval: lr = (*parse->right->func)( parse->right, args, jmp ); } /* Now eval */ @@ -195,7 +232,7 @@ compile_eval( if( !status ) t = 0; else if( ll ) t = ll, ll = 0; else if( lr ) t = lr, lr = 0; - else t = list_new( L0, newstr( "1" ) ); + else t = list_new( L0, "1", 0 ); if( ll ) list_free( ll ); if( lr ) list_free( lr ); @@ -215,26 +252,43 @@ compile_eval( LIST * compile_foreach( - PARSE *parse, - LOL *args ) + PARSE *p, + LOL *args, + int *jmp ) { - LIST *nv = (*parse->left->func)( parse->left, args ); + LIST *nv = (*p->left->func)( p->left, args, jmp ); + LIST *result = 0; LIST *l; - /* Call var_set to reset $(parse->string) for each val. */ + /* for each value for var */ - for( l = nv; l; l = list_next( l ) ) + for( l = nv; l && *jmp == JMP_NONE; l = list_next( l ) ) { - LIST *val = list_new( L0, copystr( l->string ) ); + /* Reset $(p->string) for each val. */ - var_set( parse->string, val, VAR_SET ); + var_set( p->string, list_new( L0, l->string, 1 ), VAR_SET ); - list_free( (*parse->right->func)( parse->right, args ) ); + /* Keep only last result. */ + + list_free( result ); + result = (*p->right->func)( p->right, args, jmp ); + + /* continue loop? */ + + if( *jmp == JMP_CONTINUE ) + *jmp = JMP_NONE; } + /* Here by break/continue? */ + + if( *jmp == JMP_BREAK || *jmp == JMP_CONTINUE ) + *jmp = JMP_NONE; + list_free( nv ); - return L0; + /* Returns result of last loop */ + + return result; } /* @@ -248,19 +302,16 @@ compile_foreach( LIST * compile_if( PARSE *p, - LOL *args ) + LOL *args, + int *jmp ) { - LIST *l = (*p->left->func)( p->left, args ); + LIST *l = (*p->left->func)( p->left, args, jmp ); - if( l ) - { - list_free( l ); - return (*p->right->func)( p->right, args ); - } - else - { - return (*p->third->func)( p->third, args ); - } + p = l ? p->right : p->third; + + list_free( l ); + + return (*p->func)( p, args, jmp ); } /* @@ -272,9 +323,10 @@ compile_if( LIST * compile_include( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { - LIST *nt = (*parse->left->func)( parse->left, args ); + LIST *nt = (*parse->left->func)( parse->left, args, jmp ); if( DEBUG_COMPILE ) { @@ -290,12 +342,16 @@ compile_include( /* Bind the include file under the influence of */ /* "on-target" variables. Though they are targets, */ /* include files are not built with make(). */ + /* Needn't copysettings(), as search sets no vars. */ pushsettings( t->settings ); t->boundname = search( t->name, &t->time ); popsettings( t->settings ); - parse_file( t->boundname ); + /* Don't parse missing file if NOCARE set */ + + if( t->time || !( t->flags & T_FLAG_NOCARE ) ) + parse_file( t->boundname ); } list_free( nt ); @@ -312,10 +368,11 @@ compile_include( LIST * compile_list( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { /* voodoo 1 means: s is a copyable string */ - char *s = parse->string; + const char *s = parse->string; return var_expand( L0, s, s + strlen( s ), args, 1 ); } @@ -330,12 +387,13 @@ compile_list( LIST * compile_local( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { LIST *l; SETTINGS *s = 0; - LIST *nt = (*parse->left->func)( parse->left, args ); - LIST *ns = (*parse->right->func)( parse->right, args ); + LIST *nt = (*parse->left->func)( parse->left, args, jmp ); + LIST *ns = (*parse->right->func)( parse->right, args, jmp ); LIST *result; if( DEBUG_COMPILE ) @@ -359,9 +417,8 @@ compile_local( /* variable, making it not so much local as layered. */ pushsettings( s ); - result = (*parse->third->func)( parse->third, args ); + result = (*parse->third->func)( parse->third, args, jmp ); popsettings( s ); - freesettings( s ); return result; @@ -374,39 +431,26 @@ compile_local( LIST * compile_null( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { return L0; } -/* - * compile_jumptoeof() - terminates parsing of the current file - */ - -LIST * -compile_jumptoeof( - PARSE *parse, - LOL *args ) -{ - parse_jumptoeof(); - return L0; -} - /* * compile_on() - run rule under influence of on-target variables * - * parse->left list of files to include (can only do 1) + * parse->left target list; only first used * parse->right rule to run - * - * EXPERIMENTAL! */ LIST * compile_on( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { - LIST *nt = (*parse->left->func)( parse->left, args ); + LIST *nt = (*parse->left->func)( parse->left, args, jmp ); LIST *result = 0; if( DEBUG_COMPILE ) @@ -416,14 +460,20 @@ compile_on( printf( "\n" ); } + /* + * Copy settings, so that 'on target var on target = val' + * doesn't set var globally. + */ + if( nt ) { TARGET *t = bindtarget( nt->string ); + SETTINGS *s = copysettings( t->settings ); - pushsettings( t->settings ); - result = (*parse->right->func)( parse->right, args ); - popsettings( t->settings ); - + pushsettings( s ); + result = (*parse->right->func)( parse->right, args, jmp ); + popsettings( s ); + freesettings( s ); } list_free( nt ); @@ -431,7 +481,6 @@ compile_on( return result; } - /* * compile_rule() - compile a single user defined rule * @@ -444,7 +493,8 @@ compile_on( LIST * compile_rule( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { LOL nargs[1]; LIST *result = 0; @@ -453,14 +503,14 @@ compile_rule( /* list of rules to run -- normally 1! */ - ll = (*parse->left->func)( parse->left, args ); + ll = (*parse->left->func)( parse->left, args, jmp ); /* Build up the list of arg lists */ lol_init( nargs ); for( p = parse->right; p; p = p->left ) - lol_add( nargs, (*p->right->func)( p->right, args ) ); + lol_add( nargs, (*p->right->func)( p->right, args, jmp ) ); /* Run rules, appending results from each */ @@ -479,7 +529,7 @@ compile_rule( LIST * evaluate_rule( - char *rulename, + const char *rulename, LOL *args, LIST *result ) { @@ -521,13 +571,32 @@ evaluate_rule( } /* Now recursively compile any parse tree associated with this rule */ - /* refer/free to ensure rule not freed during use */ if( rule->procedure ) { PARSE *parse = rule->procedure; + SETTINGS *s = 0; + int jmp = JMP_NONE; + LIST *l; + int i; + + /* build parameters as local vars */ + + for( l = rule->params, i = 0; l; l = l->next, i++ ) + s = addsettings( s, 0, l->string, + list_copy( L0, lol_get( args, i ) ) ); + + /* Run rule. */ + /* Bring in local params. */ + /* refer/free to ensure rule not freed during use. */ + parse_refer( parse ); - result = list_append( result, (*parse->func)( parse, args ) ); + + pushsettings( s ); + result = list_append( result, (*parse->func)( parse, args, &jmp ) ); + popsettings( s ); + freesettings( s ); + parse_free( parse ); } @@ -547,16 +616,28 @@ evaluate_rule( LIST * compile_rules( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { /* Ignore result from first statement; return the 2nd. */ /* Optimize recursion on the right by looping. */ - do list_free( (*parse->left->func)( parse->left, args ) ); - while( (parse = parse->right)->func == compile_rules - && !parse_shall_skip() ); + LIST *result = 0; - return (parse_shall_skip() ? L0 :(*parse->func)( parse, args )); + while( *jmp == JMP_NONE && parse->func == compile_rules ) + { + list_free( result ); + result = (*parse->left->func)( parse->left, args, jmp ); + parse = parse->right; + } + + if( *jmp == JMP_NONE ) + { + list_free( result ); + result = (*parse->func)( parse, args, jmp ); + } + + return result; } /* @@ -564,33 +645,24 @@ compile_rules( * * parse->left variable names * parse->right variable values - * parse->num ASSIGN_SET/APPEND/DEFAULT + * parse->num VAR_SET/APPEND/DEFAULT */ LIST * compile_set( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { - LIST *nt = (*parse->left->func)( parse->left, args ); - LIST *ns = (*parse->right->func)( parse->right, args ); + LIST *nt = (*parse->left->func)( parse->left, args, jmp ); + LIST *ns = (*parse->right->func)( parse->right, args, jmp ); LIST *l; - int setflag; - char *trace; - - switch( parse->num ) - { - case ASSIGN_SET: setflag = VAR_SET; trace = "="; break; - case ASSIGN_APPEND: setflag = VAR_APPEND; trace = "+="; break; - case ASSIGN_DEFAULT: setflag = VAR_DEFAULT; trace = "?="; break; - default: setflag = VAR_SET; trace = ""; break; - } if( DEBUG_COMPILE ) { debug_compile( 0, "set" ); list_print( nt ); - printf( " %s ", trace ); + printf( " %s ", set_names[ parse->num ] ); list_print( ns ); printf( "\n" ); } @@ -599,7 +671,7 @@ compile_set( /* var_set keeps ns, so need to copy it */ for( l = nt; l; l = list_next( l ) ) - var_set( l->string, list_copy( L0, ns ), setflag ); + var_set( l->string, list_copy( L0, ns ), parse->num ); list_free( nt ); @@ -610,20 +682,31 @@ compile_set( * compile_setcomp() - support for `rule` - save parse tree * * parse->string rule name - * parse->left rules for rule + * parse->left list of argument names + * parse->right rules for rule */ LIST * compile_setcomp( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { RULE *rule = bindrule( parse->string ); + LIST *params = 0; + PARSE *p; + + /* Build param list */ + + for( p = parse->left; p; p = p->left ) + params = list_new( params, p->string, 1 ); if( DEBUG_COMPILE ) { debug_compile( 0, "rule" ); - printf( " %s\n", parse->string ); + printf( "%s ", parse->string ); + list_print( params ); + printf( "\n" ); } /* Free old one, if present */ @@ -631,12 +714,16 @@ compile_setcomp( if( rule->procedure ) parse_free( rule->procedure ); - rule->procedure = parse->left; + if( rule->params ) + list_free( rule->params ); + + rule->procedure = parse->right; + rule->params = params; /* we now own this parse tree */ /* don't let parse_free() release it */ - parse_refer( parse->left ); + parse_refer( parse->right ); return L0; } @@ -656,10 +743,11 @@ compile_setcomp( LIST * compile_setexec( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { RULE *rule = bindrule( parse->string ); - LIST *bindlist = (*parse->left->func)( parse->left, args ); + LIST *bindlist = (*parse->left->func)( parse->left, args, jmp ); /* Free old one, if present */ @@ -682,19 +770,19 @@ compile_setexec( * parse->left variable names * parse->right target name * parse->third variable value - * parse->num ASSIGN_SET/APPEND + * parse->num VAR_SET/APPEND/DEFAULT */ LIST * compile_settings( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { - LIST *nt = (*parse->left->func)( parse->left, args ); - LIST *ns = (*parse->third->func)( parse->third, args ); - LIST *targets = (*parse->right->func)( parse->right, args ); + LIST *nt = (*parse->left->func)( parse->left, args, jmp ); + LIST *ns = (*parse->third->func)( parse->third, args, jmp ); + LIST *targets = (*parse->right->func)( parse->right, args, jmp ); LIST *ts; - int append = parse->num == ASSIGN_APPEND; if( DEBUG_COMPILE ) { @@ -702,7 +790,7 @@ compile_settings( list_print( nt ); printf( "on " ); list_print( targets ); - printf( " %s ", append ? "+=" : "=" ); + printf( " %s ", set_names[ parse->num ] ); list_print( ns ); printf( "\n" ); } @@ -717,7 +805,7 @@ compile_settings( LIST *l; for( l = nt; l; l = list_next( l ) ) - t->settings = addsettings( t->settings, append, + t->settings = addsettings( t->settings, parse->num, l->string, list_copy( (LIST*)0, ns ) ); } @@ -743,9 +831,10 @@ compile_settings( LIST * compile_switch( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { - LIST *nt = (*parse->left->func)( parse->left, args ); + LIST *nt = (*parse->left->func)( parse->left, args, jmp ); LIST *result = 0; if( DEBUG_COMPILE ) @@ -763,7 +852,7 @@ compile_switch( { /* Get & exec parse tree for this case */ parse = parse->left->left; - result = (*parse->func)( parse, args ); + result = (*parse->func)( parse, args, jmp ); break; } } @@ -783,21 +872,40 @@ compile_switch( LIST * compile_while( PARSE *p, - LOL *args ) + LOL *args, + int *jmp ) { - LIST *r = 0; + LIST *result = 0; LIST *l; /* Returns the value from the last execution of the block */ - while( l = (*p->left->func)( p->left, args ) ) + while( ( *jmp == JMP_NONE ) && + ( l = (*p->left->func)( p->left, args, jmp ) ) ) { + /* Always toss while's expression */ + list_free( l ); - if( r ) list_free( r ); - r = (*p->right->func)( p->right, args ); + + /* Keep only last result. */ + + list_free( result ); + result = (*p->right->func)( p->right, args, jmp ); + + /* continue loop? */ + + if( *jmp == JMP_CONTINUE ) + *jmp = JMP_NONE; } - return r; + /* Here by break/continue? */ + + if( *jmp == JMP_BREAK || *jmp == JMP_CONTINUE ) + *jmp = JMP_NONE; + + /* Returns result of last loop */ + + return result; } /* @@ -805,7 +913,7 @@ compile_while( */ static void -debug_compile( int which, char *s ) +debug_compile( int which, const char *s ) { static int level = 0; static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|"; diff --git a/src/tools/jam/compile.h b/src/tools/jam/compile.h index 6e66fe11c1..ab7b5e6460 100644 --- a/src/tools/jam/compile.h +++ b/src/tools/jam/compile.h @@ -6,36 +6,37 @@ /* * compile.h - compile parsed jam statements + * + * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() + * 01/24/01 (seiwald) - 'while' statement + * 03/02/02 (seiwald) - rules can be invoked via variable names + * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx + * 10/22/02 (seiwald) - working return/break/continue statements + * 11/04/02 (seiwald) - const-ing for string literals */ void compile_builtins(); -LIST *compile_append( PARSE *parse, LOL *args ); -LIST *compile_foreach( PARSE *parse, LOL *args ); -LIST *compile_if( PARSE *parse, LOL *args ); -LIST *compile_eval( PARSE *parse, LOL *args ); -LIST *compile_include( PARSE *parse, LOL *args ); -LIST *compile_jumptoeof( PARSE *parse, LOL *args ); -LIST *compile_list( PARSE *parse, LOL *args ); -LIST *compile_local( PARSE *parse, LOL *args ); -LIST *compile_null( PARSE *parse, LOL *args ); -LIST *compile_on( PARSE *parse, LOL *args ); -LIST *compile_rule( PARSE *parse, LOL *args ); -LIST *compile_rules( PARSE *parse, LOL *args ); -LIST *compile_set( PARSE *parse, LOL *args ); -LIST *compile_setcomp( PARSE *parse, LOL *args ); -LIST *compile_setexec( PARSE *parse, LOL *args ); -LIST *compile_settings( PARSE *parse, LOL *args ); -LIST *compile_switch( PARSE *parse, LOL *args ); -LIST *compile_while( PARSE *parse, LOL *args ); +LIST *compile_append( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_break( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_foreach( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_if( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_eval( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_include( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_list( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_local( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_null( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_on( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_rule( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_rules( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_set( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_setcomp( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_setexec( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_settings( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_switch( PARSE *parse, LOL *args, int *jmp ); +LIST *compile_while( PARSE *parse, LOL *args, int *jmp ); -LIST *evaluate_rule( char *rulename, LOL *args, LIST *result ); - -/* 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 */ +LIST *evaluate_rule( const char *rulename, LOL *args, LIST *result ); /* Conditions for compile_if() */ @@ -51,3 +52,11 @@ LIST *evaluate_rule( char *rulename, LOL *args, LIST *result ); # define EXPR_MORE 8 /* arg > arg */ # define EXPR_MOREEQ 9 /* arg >= arg */ # define EXPR_IN 10 /* arg in arg */ + +/* Flags for compile_return */ + +# define JMP_NONE 0 /* flow continues */ +# define JMP_BREAK 1 /* break out of loop */ +# define JMP_CONTINUE 2 /* step to end of loop */ +# define JMP_RETURN 3 /* return from rule */ +# define JMP_EOF 4 /* stop executing the current file */ diff --git a/src/tools/jam/hcache.c b/src/tools/jam/hcache.c index 3134250813..aec513a20e 100644 --- a/src/tools/jam/hcache.c +++ b/src/tools/jam/hcache.c @@ -234,7 +234,7 @@ hcache_init() fprintf(stderr, "invalid %s\n", hcachename); goto bail; } - l = list_new(l, s); + l = list_new(l, s, 1); } c->includes = l; @@ -252,7 +252,7 @@ hcache_init() fprintf(stderr, "invalid %s\n", hcachename); goto bail; } - l = list_new(l, s); + l = list_new(l, s, 1); } c->hdrscan = l; @@ -344,7 +344,7 @@ hcache_done() } LIST * -hcache (TARGET *t, int rec, regexp *re[], LIST *hdrscan) +hcache (TARGET *t, LIST *hdrscan) { HCACHEDATA cachedata, *c = &cachedata; LIST *l = 0; @@ -408,7 +408,7 @@ hcache (TARGET *t, int rec, regexp *re[], LIST *hdrscan) /* 'c' points at the cache entry. Its out of date. */ - l = headers1 (0, t->boundname, rec, re); + l = headers1 (t->boundname, 0); c->time = t->time; c->age = 0; diff --git a/src/tools/jam/hcache.h b/src/tools/jam/hcache.h index af942126d0..ea5852e5ff 100644 --- a/src/tools/jam/hcache.h +++ b/src/tools/jam/hcache.h @@ -8,4 +8,4 @@ void hcache_init(void); void hcache_done(void); -LIST *hcache(TARGET *t, int rec, regexp *re[], LIST *hdrscan); +LIST *hcache(TARGET *t, LIST *hdrscan); diff --git a/src/tools/jam/headers.c b/src/tools/jam/headers.c index 50469d023b..c1513d185e 100644 --- a/src/tools/jam/headers.c +++ b/src/tools/jam/headers.c @@ -4,20 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "compile.h" -# include "rules.h" -# include "variable.h" -# include "regexp.h" -# include "headers.h" -# include "newstr.h" - -#ifdef OPT_HEADER_CACHE_EXT -# include "hcache.h" -#endif - /* * headers.c - handle #includes in source files * @@ -37,10 +23,28 @@ * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule, * so that headers() doesn't have to mock up a parse structure * just to invoke a rule. + * 03/02/02 (seiwald) - rules can be invoked via variable names + * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() + * 11/04/02 (seiwald) - const-ing for string literals + * 12/09/02 (seiwald) - push regexp creation down to headers1(). */ +# include "jam.h" +# include "lists.h" +# include "parse.h" +# include "compile.h" +# include "rules.h" +# include "variable.h" +# include "regexp.h" +# include "headers.h" +# include "newstr.h" + +#ifdef OPT_HEADER_CACHE_EXT +# include "hcache.h" +#endif + #ifndef OPT_HEADER_CACHE_EXT -static LIST *headers1( LIST *l, char *file, int rec, regexp *re[] ); +static LIST *headers1( const char *file, LIST *hdrscan ); #endif /* @@ -54,35 +58,26 @@ headers( TARGET *t ) { LIST *hdrscan; LIST *hdrrule; - LIST *headlist = 0; + LIST *hdrcache; LOL lol; - regexp *re[ MAXINC ]; - int rec = 0; if( !( hdrscan = var_get( "HDRSCAN" ) ) || !( hdrrule = var_get( "HDRRULE" ) ) ) return; - if( DEBUG_HEADER ) - printf( "header scan %s\n", t->name ); - - /* Compile all regular expressions in HDRSCAN */ - - while( rec < MAXINC && hdrscan ) - { - re[rec++] = regcomp( hdrscan->string ); - hdrscan = list_next( hdrscan ); - } - /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ + if( DEBUG_HEADER ) + printf( "header scan %s\n", t->name ); + lol_init( &lol ); - lol_add( &lol, list_new( L0, t->name ) ); + + lol_add( &lol, list_new( L0, t->name, 1 ) ); #ifdef OPT_HEADER_CACHE_EXT - lol_add( &lol, hcache( t, rec, re, var_get("HDRSCAN") ) ); + lol_add( &lol, hcache( t, var_get("HDRSCAN") ) ); #else - lol_add( &lol, headers1( headlist, t->boundname, rec, re ) ); + lol_add( &lol, headers1( t->boundname, hdrscan ) ); #endif if( lol_get( &lol, 1 ) ) @@ -91,9 +86,6 @@ headers( TARGET *t ) /* Clean up */ lol_free( &lol ); - - while( rec ) - free( (char *)re[--rec] ); } /* @@ -106,39 +98,47 @@ LIST * static LIST * #endif headers1( - LIST *l, - char *file, - int rec, - regexp *re[] ) + const char *file, + LIST *hdrscan ) { FILE *f; + int i; + int rec = 0; + LIST *result = 0; + regexp *re[ MAXINC ]; char buf[ 1024 ]; - int i; if( !( f = fopen( file, "r" ) ) ) - return l; + return result; + + while( rec < MAXINC && hdrscan ) + { + re[rec++] = regcomp( hdrscan->string ); + hdrscan = list_next( hdrscan ); + } while( fgets( buf, sizeof( buf ), f ) ) { for( i = 0; i < rec; i++ ) if( regexec( re[i], buf ) && re[i]->startp[1] ) { - re[i]->endp[1][0] = '\0'; + /* Copy and terminate extracted string. */ + + char buf2[ MAXSYM ]; + int l = re[i]->endp[1] - re[i]->startp[1]; + memcpy( buf2, re[i]->startp[1], l ); + buf2[ l ] = 0; + result = list_new( result, buf2, 0 ); if( DEBUG_HEADER ) - printf( "header found: %s\n", re[i]->startp[1] ); - - l = list_new( l, newstr( re[i]->startp[1] ) ); + printf( "header found: %s\n", buf2 ); } } + while( rec ) + free( (char *)re[--rec] ); + fclose( f ); - return l; -} - -void -regerror( char *s ) -{ - printf( "re error %s\n", s ); + return result; } diff --git a/src/tools/jam/headers.h b/src/tools/jam/headers.h index 624475fe7d..43b4b25de0 100644 --- a/src/tools/jam/headers.h +++ b/src/tools/jam/headers.h @@ -11,6 +11,5 @@ void headers( TARGET *t ); #ifdef OPT_HEADER_CACHE_EXT -struct regexp; -LIST *headers1( LIST *l, char *file, int rec, struct regexp *re[] ); +LIST *headers1( const char *file, LIST *hdrscan ); #endif diff --git a/src/tools/jam/jam.c b/src/tools/jam/jam.c index 5ac8d1d570..a36cd38955 100644 --- a/src/tools/jam/jam.c +++ b/src/tools/jam/jam.c @@ -94,6 +94,11 @@ * 02/22/95 (seiwald) - -v for version info. * 09/11/00 (seiwald) - PATCHLEVEL folded into VERSION. * 01/10/01 (seiwald) - pathsys.h split from filesys.h + * 01/21/02 (seiwald) - new -q to quit quickly on build failure + * 03/16/02 (seiwald) - support for -g (reorder builds by source time) + * 09/19/02 (seiwald) - new -d displays + * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() + * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" @@ -132,16 +137,16 @@ struct globs globs = { 0, /* quitquick */ 0, /* newestfirst */ # ifdef OS_MAC - { 0, 0 }, /* debug - suppress tracing output */ + { 0 }, /* display - suppress actions output */ # else - { 0, 1 }, /* debug ... */ + { 0, 1 }, /* display actions */ # endif 0 /* output commands, not run them */ } ; /* Symbols to be defined as true for use in Jambase */ -static char *othersyms[] = { OSMAJOR, OSMINOR, OSPLAT, JAMVERSYM, 0 } ; +static const char *othersyms[] = { OSMAJOR, OSMINOR, OSPLAT, JAMVERSYM, 0 } ; /* Known for sure: * mac needs arg_enviro @@ -165,9 +170,9 @@ extern char **environ; main( int argc, char **argv, char **arg_environ ) { int n; - char *s; + const char *s; struct option optv[N_OPTS]; - char *all = "all"; + const char *all = "all"; int anyhow = 0; int status; @@ -182,9 +187,10 @@ main( int argc, char **argv, char **arg_environ ) printf( "\nusage: jam [ options ] targets...\n\n" ); printf( "-a Build all targets, even if they are current.\n" ); - printf( "-dx Set the debug level to x (0-9).\n" ); + printf( "-dx Display (a)actions (c)causes (d)dependencies\n" ); + printf( " (m)make tree (x)commands (0-9) debug levels.\n" ); printf( "-fx Read x instead of Jambase.\n" ); - /* printf( "-g Build from newest sources first.\n" ); */ + printf( "-g Build from newest sources first.\n" ); printf( "-jx Run up to x shell commands concurrently.\n" ); printf( "-n Don't actually execute the updating actions.\n" ); printf( "-ox Write the updating actions to file x.\n" ); @@ -211,7 +217,7 @@ main( int argc, char **argv, char **arg_environ ) /* Pick up interesting options */ if( ( s = getoptval( optv, 'n', 0 ) ) ) - globs.noexec++, globs.debug[2] = 1; + globs.noexec++, DEBUG_MAKE = DEBUG_MAKEQ = DEBUG_EXEC = 1; if( ( s = getoptval( optv, 'q', 0 ) ) ) globs.quitquick = 1; @@ -229,45 +235,55 @@ main( int argc, char **argv, char **arg_environ ) for( n = 0; s = getoptval( optv, 'd', n ); n++ ) { - int i; + int i = atoi( s ); /* First -d, turn off defaults. */ if( !n ) - for( i = 0; i < DEBUG_MAX; i++ ) - globs.debug[i] = 0; + DEBUG_MAKE = DEBUG_MAKEQ = DEBUG_EXEC = 0; - i = atoi( s ); + /* n turns on levels 1-n */ + /* +n turns on level n */ + /* c turns on named display c */ if( i < 0 || i >= DEBUG_MAX ) { printf( "Invalid debug level '%s'.\n", s ); - continue; } - - /* n turns on levels 1-n */ - /* +n turns on level n */ - - if( *s == '+' ) + else if( *s == '+' ) + { globs.debug[i] = 1; - else while( i ) + } + else if( i ) while( i ) + { globs.debug[i--] = 1; + } + else while( *s ) switch( *s++ ) + { + case 'a': DEBUG_MAKE = DEBUG_MAKEQ = 1; break; + case 'c': DEBUG_CAUSES = 1; break; + case 'd': DEBUG_DEPENDS = 1; break; + case 'm': DEBUG_MAKEPROG = 1; break; + case 'x': DEBUG_EXEC = 1; break; + case '0': break; + default: printf( "Invalid debug flag '%c'.\n", s[-1] ); + } } /* Set JAMDATE first */ { - char *date; + char buf[ 128 ]; time_t clock; time( &clock ); - date = newstr( ctime( &clock ) ); + strcpy( buf, ctime( &clock ) ); /* Trim newline from date */ - if( strlen( date ) == 25 ) - date[ 24 ] = 0; + if( strlen( buf ) == 25 ) + buf[ 24 ] = 0; - var_set( "JAMDATE", list_new( L0, newstr( date ) ), VAR_SET ); + var_set( "JAMDATE", list_new( L0, buf, 0 ), VAR_SET ); } /* And JAMUNAME */ @@ -277,17 +293,13 @@ main( int argc, char **argv, char **arg_environ ) if( uname( &u ) >= 0 ) { - var_set( "JAMUNAME", - list_new( - list_new( - list_new( - list_new( - list_new( L0, - newstr( u.sysname ) ), - newstr( u.nodename ) ), - newstr( u.release ) ), - newstr( u.version ) ), - newstr( u.machine ) ), VAR_SET ); + LIST *l = L0; + l = list_new( l, u.machine, 0 ); + l = list_new( l, u.version, 0 ); + l = list_new( l, u.release, 0 ); + l = list_new( l, u.nodename, 0 ); + l = list_new( l, u.sysname, 0 ); + var_set( "JAMUNAME", l, VAR_SET ); } } # endif /* unix */ @@ -300,13 +312,13 @@ main( int argc, char **argv, char **arg_environ ) /* load up environment variables */ - var_defines( use_environ ); + var_defines( (const char **)use_environ ); /* Load up variables set on command line. */ for( n = 0; s = getoptval( optv, 's', n ); n++ ) { - char *symv[2]; + const char *symv[2]; symv[0] = s; symv[1] = 0; var_defines( symv ); @@ -355,7 +367,7 @@ main( int argc, char **argv, char **arg_environ ) if( !argc ) status |= make( 1, &all, anyhow ); else - status |= make( argc, argv, anyhow ); + status |= make( argc, (const char **)argv, anyhow ); /* Widely scattered cleanup */ diff --git a/src/tools/jam/jam.h b/src/tools/jam/jam.h index d309b67d6e..f8080ffae3 100644 --- a/src/tools/jam/jam.h +++ b/src/tools/jam/jam.h @@ -24,9 +24,18 @@ * 11/21/96 (peterk) - added BeOS with MW CW mwcc * 12/21/96 (seiwald) - OSPLAT now defined for NT. * 07/19/99 (sickel) - Mac OS X Server and Client support added + * 02/22/01 (seiwald) - downshift paths on case-insensitive macintosh + * 03/23/01 (seiwald) - VMS C++ changes. + * 10/29/01 (brett) - More IA64 ifdefs for MS. * 02/18/00 (belmonte)- Support for Cygwin. * 09/12/00 (seiwald) - OSSYMS split to OSMAJOR/OSMINOR/OSPLAT * 12/29/00 (seiwald) - OSVER dropped. + * 01/21/02 (seiwald) - new -q to quit quickly on build failure + * 03/16/02 (seiwald) - support for -g (reorder builds by source time) + * 03/20/02 (seiwald) - MINGW porting from Max Blagai + * 08/16/02 (seiwald) - BEOS porting from Ingo Weinhold + * 09/19/02 (seiwald) - new -d displays + * 11/05/02 (seiwald) - OSPLAT now set to sparc on solaris. */ /* @@ -167,6 +176,7 @@ # include # include # include +# include # define OSMAJOR "MAC=true" # define OSMINOR "OS=MAC" @@ -414,8 +424,7 @@ # endif # ifdef __sparc__ -# if !defined( OS_SUNOS ) && \ - !defined( OS_SOLARIS ) +# if !defined( OS_SUNOS ) # define OSPLAT "OSPLAT=SPARC" # endif # endif @@ -471,7 +480,7 @@ /* Jam private definitions below. */ -# define DEBUG_MAX 10 +# define DEBUG_MAX 15 struct globs { int noexec; @@ -484,11 +493,8 @@ struct globs { 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 ] ) /* -da show actions when executed */ +# define DEBUG_MAKEPROG ( globs.debug[ 3 ] ) /* -dm show progress of make0 */ # define DEBUG_EXECCMD ( globs.debug[ 4 ] ) /* show execcmds()'s work */ @@ -506,3 +512,8 @@ extern struct globs globs; # define DEBUG_SCAN ( globs.debug[ 9 ] ) /* show scanner tokens */ # define DEBUG_MEM ( globs.debug[ 9 ] ) /* show memory use */ +# define DEBUG_MAKEQ ( globs.debug[ 11 ] ) /* -da show even quiet actions */ +# define DEBUG_EXEC ( globs.debug[ 12 ] ) /* -dx show text of actions */ +# define DEBUG_DEPENDS ( globs.debug[ 13 ] ) /* -dd show dependency graph */ +# define DEBUG_CAUSES ( globs.debug[ 14 ] ) /* -dc show dependency graph */ + diff --git a/src/tools/jam/jambase.c b/src/tools/jam/jambase.c index 23f7845316..be7260d016 100644 --- a/src/tools/jam/jambase.c +++ b/src/tools/jam/jambase.c @@ -1,18 +1,19 @@ /* Generated by mkjambase from Jambase */ -char *jambase[] = { +const char *jambase[] = { /* Jambase */ +"JAMBASEDATE = 2002.05.09 ;\n", "if $(NT)\n", "{\n", "MV ?= move /y ;\n", "CP ?= copy ;\n", "RM ?= del /f/q ;\n", +"RMDIR ?= rmdir /s/q ;\n", "SLASH ?= \\\\ ;\n", "SUFLIB ?= .lib ;\n", "SUFOBJ ?= .obj ;\n", "SUFEXE ?= .exe ;\n", "if $(BCCROOT)\n", "{\n", -"Echo \"Compiler is Borland C++\" ;\n", "AR ?= tlib /C /P64 ;\n", "CC ?= bcc32 ;\n", "CCFLAGS ?= -v -w- -q -DWIN -tWR -tWM -tWC ;\n", @@ -26,7 +27,6 @@ char *jambase[] = { "}\n", "else if $(MSVC)\n", "{\n", -"Echo \"Compiler is Microsoft Visual C++ 16 bit\" ;\n", "AR ?= lib /nologo ;\n", "CC ?= cl /nologo ;\n", "CCFLAGS ?= /D \\\"WIN\\\" ;\n", @@ -44,9 +44,10 @@ char *jambase[] = { "STDHDRS ?= $(MSVC)\\\\include ;\n", "UNDEFFLAG ?= \"/u _\" ;\n", "}\n", -"else if $(MSVCNT)\n", +"else if $(MSVCNT) || $(MSVCDIR)\n", "{\n", -"Echo \"Compiler is Microsoft Visual C++\" ;\n", +"MSVCNT ?= $(MSVCDIR) ; \n", +"local I ; if $(OSPLAT) = IA64 { I = ia64\\\\ ; } else { I = \"\" ; }\n", "AR ?= lib ;\n", "AS ?= masm386 ;\n", "CC ?= cl /nologo ;\n", @@ -55,18 +56,18 @@ char *jambase[] = { "C++FLAGS ?= $(CCFLAGS) ;\n", "LINK ?= link /nologo ;\n", "LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= $(MSVCNT)\\\\lib\\\\advapi32.lib\n", -"$(MSVCNT)\\\\lib\\\\libc.lib\n", -"$(MSVCNT)\\\\lib\\\\oldnames.lib\n", -"$(MSVCNT)\\\\lib\\\\kernel32.lib ;\n", +"LINKLIBS ?= \n", +"$(MSVCNT)\\\\lib\\\\$(I)libc.lib\n", +"$(MSVCNT)\\\\lib\\\\$(I)oldnames.lib\n", +"$(MSVCNT)\\\\lib\\\\$(I)kernel32.lib ;\n", "OPTIM ?= \"\" ;\n", "STDHDRS ?= $(MSVCNT)\\\\include ;\n", "UNDEFFLAG ?= \"/u _\" ;\n", "}\n", "else\n", "{\n", -"Exit On NT, set BCCROOT, MSVCNT, or MSVC to the root of the\n", -"Borland or Microsoft directories. ;\n", +"EXIT On NT, set BCCROOT, MSVCDIR, MSVCNT, or MSVC to the root\n", +"of the Borland or Microsoft directories. ;\n", "}\n", "}\n", "else if $(MINGW)\n", @@ -154,20 +155,20 @@ char *jambase[] = { "\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib\"\n", "\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib\" ;\n", "MPWLIBS ?= \n", -"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib\" ;\n", +"\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib\"\n", +"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib\" ;\n", "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", +"\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib\"\n", +"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib\" ;\n", "SIOUXHDRS ?= ;\n", "SIOUXLIBS ?= \n", -"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL SIOUX.PPC.Lib\" \n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC.Lib\" ;\n", +"\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib\"\n", +"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib\" \n", +"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib\" ;\n", "C++ ?= mwcppc ;\n", -"C++FLAGS ?= -w off -nomapcr ;\n", +"C++FLAGS ?= -w off ;\n", "CC ?= mwcppc ;\n", -"CCFLAGS ?= -w off -nomapcr ;\n", +"CCFLAGS ?= -w off ;\n", "CP ?= duplicate -y ;\n", "DOT ?= \":\" ;\n", "DOTDOT ?= \"::\" ;\n", @@ -197,12 +198,13 @@ char *jambase[] = { "CHGRP ?= chgrp ;\n", "CHOWN ?= chown ;\n", "FORTRAN ?= \"\" ;\n", -"LEX ?= flex ;\n", +"LEX ?= flex ;\n", "LIBDIR ?= /boot/home/config/lib ;\n", "LINK ?= mwld ;\n", "LINKFLAGS ?= \"\" ;\n", "MANDIR ?= /boot/home/config/man ;\n", "NOARSCAN ?= true ;\n", +"RANLIB ?= ranlib ;\n", "STDHDRS ?= /boot/develop/headers/posix ;\n", "YACC ?= bison -y ;\n", "YACCGEN ?= .c ;\n", @@ -218,7 +220,7 @@ char *jambase[] = { "CHGRP ?= chgrp ;\n", "CHOWN ?= chown ;\n", "FORTRAN ?= \"\" ;\n", -"LEX ?= flex ;\n", +"LEX ?= flex ;\n", "LIBDIR ?= /boot/home/config/lib ;\n", "LINK ?= gcc ;\n", "MANDIR ?= /boot/home/config/man ;\n", @@ -272,10 +274,8 @@ char *jambase[] = { "AR ?= libtool -o ;\n", "RANLIB ?= \"\" ;\n", "case MACOSX :\n", -"AR ?= libtool -o ;\n", "C++ ?= c++ ;\n", "MANDIR ?= /usr/local/share/man ;\n", -"RANLIB ?= \"\" ;\n", "case NCR :\n", "RANLIB ?= \"\" ;\n", "case PTX :\n", @@ -353,12 +353,15 @@ char *jambase[] = { "OPTIM ?= ;\n", "RCP ?= rcp ;\n", "RM ?= rm -f ;\n", +"RMDIR ?= $(RM) ;\n", "RSH ?= rsh ;\n", "SED ?= sed ;\n", "SHELLHEADER ?= \"#!/bin/sh\" ;\n", "SHELLMODE ?= 755 ;\n", "SLASH ?= / ;\n", "STDHDRS ?= /usr/include ;\n", +"SUBDIRRULES ?= ;\n", +"SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ;\n", "SUFEXE ?= \"\" ;\n", "SUFLIB ?= .a ;\n", "SUFOBJ ?= .o ;\n", @@ -565,7 +568,7 @@ char *jambase[] = { "if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }\n", "Archive $(_l) : $(_s) ;\n", "if $(RANLIB) { Ranlib $(_l) ; }\n", -"if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(_l) : $(_s) ; }\n", +"if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }\n", "}\n", "rule Link\n", "{\n", @@ -616,20 +619,19 @@ char *jambase[] = { "if $(>)\n", "{\n", "LOCATE on $(<) = $(>) ;\n", -"Depends $(<) : $(>[1]) ;\n", -"MkDir $(>[1]) ;\n", +"Depends $(<) : $(>[1]:G=dir) ;\n", +"MkDir $(>[1]:G=dir) ;\n", "}\n", "}\n", "rule MkDir\n", "{\n", "NoUpdate $(<) ;\n", -"if $(<) != $(DOT) && ! $($(<)-mkdir) \n", +"if $(<:G=) != $(DOT) && ! $($(<)-mkdir) \n", "{\n", -"local s ;\n", "$(<)-mkdir = true ;\n", -"MkDir1 $(<) ;\n", "LocalDepends dirs : $(<) ;\n", -"s = $(<:P) ;\n", +"MkDir1 $(<) ;\n", +"local s = $(<:P) ;\n", "if $(NT)\n", "{\n", "switch $(s)\n", @@ -638,15 +640,15 @@ char *jambase[] = { "case *:\\\\ : s = ;\n", "}\n", "}\n", -"if $(s) && $(s) != $(<)\n", +"if $(s) = $(<)\n", +"{\n", +"NotFile $(s) ;\n", +"}\n", +"else if $(s:G=)\n", "{\n", "Depends $(<) : $(s) ;\n", "MkDir $(s) ;\n", "}\n", -"else if $(s)\n", -"{\n", -"NotFile $(s) ;\n", -"}\n", "}\n", "}\n", "rule Object\n", @@ -733,38 +735,72 @@ char *jambase[] = { "rule SubDir\n", "{\n", "local _top = $(<[1]) ;\n", -"if ! $($(_top))\n", -"{\n", +"local _tokens = $(<[2-]) ;\n", "if ! $(_top)\n", "{\n", "Exit SubDir syntax error ;\n", "}\n", -"$(_top) = [ FSubDir $(<[2-]) ] ;\n", +"if ! $($(_top)-SET)\n", +"{\n", +"$(_top)-SET = true ;\n", +"if $($(_top))\n", +"{\n", +"$(_top)-UP = ;\n", +"$(_top)-DOWN = ;\n", +"$(_top)-ROOT = $($(_top)) ;\n", +"}\n", +"else\n", +"{\n", +"_tokens = [ FReverse $(_tokens) ] ;\n", +"SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;\n", +"FStripCommon _tokens : SUBDIR_DOWN ;\n", +"SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;\n", +"_tokens = [ FReverse $(_tokens) ] ;\n", +"if $(SUBDIR_DOWN) && $(_tokens) \n", +"{ \n", +"Echo Warning: SubDir $(<) misplaced! ; \n", +"}\n", +"$(_top)-UP = $(SUBDIR_UP) $(_tokens) ;\n", +"$(_top)-DOWN = $(SUBDIR_DOWN) ;\n", +"$(_top)-ROOT = $(SUBDIR_ROOT:E=\"\") ;\n", +"$(_top) = [ FSubDirPath $(_top) ] ;\n", +"}\n", +"SUBDIR_UP = $($(_top)-UP) ;\n", +"SUBDIR_DOWN = ;\n", +"SUBDIR_ROOT = $($(_top)-ROOT) ;\n", +"if $($(_top)RULES) { \n", +"include $($(_top)RULES) ;\n", +"} else { \n", +"NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;\n", +"include $(JAMRULES:R=$($(_top)):G=$(_top)) ;\n", "}\n", "if ! $(INVOCATION_SUBDIR_SET) {\n", "INVOCATION_SUBDIR_SET = true ;\n", -"INVOCATION_SUBDIR = $(<[2-]) ;\n", +"INVOCATION_SUBDIR_TOP = $(_top) ;\n", +"INVOCATION_SUBDIR = $(_tokens) ;\n", "if $(INVOCATION_SUBDIR) {\n", "SubInclude $(_top) ;\n", "jumptoeof ;\n", "}\n", "}\n", -"if ! $($(_top)-included)\n", -"{\n", -"$(_top)-included = TRUE ;\n", -"include $($(_top)RULES:E=$(JAMRULES:R=$($(_top)))) ;\n", "}\n", -"local _s = [ FDirName $(<[2-]) ] ;\n", -"SUBDIR = $(_s:R=$($(_top))) ;\n", -"SUBDIR_TOKENS = $(<[2-]) ;\n", +"SUBDIR_UP = $($(_top)-UP) ;\n", +"SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;\n", +"SUBDIR_ROOT = $($(_top)-ROOT) ;\n", +"SUBDIR_TOKENS = $(SUBDIR_DOWN) ;\n", +"SUBDIR = [ FSubDirPath $(<) ] ;\n", "SEARCH_SOURCE = $(SUBDIR) ;\n", "LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", "LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", -"SOURCE_GRIST = [ FGrist $(<[2-]) ] ;\n", +"SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;\n", "HDRGRIST = $(SOURCE_GRIST) ;\n", -"SUBDIRCCFLAGS = ;\n", -"SUBDIRC++FLAGS = ;\n", -"SUBDIRHDRS = ;\n", +"SUBDIR$(SUBDIRRESET) = ;\n", +"$(SUBDIRRULES) $(<) ;\n", +"}\n", +"rule FSubDirPath\n", +"{\n", +"local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;\n", +"return $(_r:R=$($(<[1])-ROOT)) ;\n", "}\n", "rule SubDirCcFlags\n", "{\n", @@ -780,13 +816,21 @@ char *jambase[] = { "}\n", "rule SubInclude\n", "{\n", -"local _s ;\n", "if ! $($(<[1]))\n", "{\n", -"Exit Top level of source tree has not been set with $(<[1]) ;\n", +"Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;\n", "}\n", -"_s = [ FDirName $(<[2-]) ] ;\n", -"include $(JAMFILE:D=$(_s):R=$($(<[1]))) ;\n", +"SubDir $(<) ;\n", +"include $(JAMFILE:D=$(SUBDIR)) ;\n", +"}\n", +"rule SubRules\n", +"{\n", +"if ! $($(<[1]))\n", +"{\n", +"Exit SubRules $(<[1]) without prior SubDir $(<[1]) ;\n", +"}\n", +"SubDir $(<) ;\n", +"SubDir $(>) ;\n", "}\n", "rule Undefines\n", "{\n", @@ -836,6 +880,10 @@ char *jambase[] = { "return true ;\n", "}\n", "}\n", +"rule FReverse \n", +"{\n", +"if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }\n", +"}\n", "rule FSubDir\n", "{\n", "if ! $(<[1]) \n", @@ -853,13 +901,13 @@ char *jambase[] = { "return $(_d) ;\n", "}\n", "}\n", -"rule _makeCommon\n", +"rule FStripCommon\n", "{\n", "if $($(<)[1]) && $($(<)[1]) = $($(>)[1])\n", "{\n", "$(<) = $($(<)[2-]) ;\n", "$(>) = $($(>)[2-]) ;\n", -"_makeCommon $(<) : $(>) ;\n", +"FStripCommon $(<) : $(>) ;\n", "}\n", "}\n", "rule FRelPath\n", @@ -867,7 +915,7 @@ char *jambase[] = { "local _l _r ;\n", "_l = $(<) ;\n", "_r = $(>) ;\n", -"_makeCommon _l : _r ;\n", +"FStripCommon _l : _r ;\n", "_l = [ FSubDir $(_l) ] ;\n", "_r = [ FDirName $(_r) ] ;\n", "if $(_r) = $(DOT) {\n", @@ -1076,6 +1124,14 @@ char *jambase[] = { "$(AR) $(<) $(>)\n", "}\n", "}\n", +"if $(UNIX)\n", +"{\n", +"actions GenFile1\n", +"{\n", +"PATH=\"$PATH:.\"\n", +"$(>[1]) $(<) $(>[2-])\n", +"}\n", +"}\n", "if $(NT) && $(MSVCNT)\n", "{\n", "actions updated together piecemeal Archive\n", @@ -1243,7 +1299,8 @@ char *jambase[] = { "rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }\n", "rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }\n", "rule addDirName { $(<) += [ FDirName $(>) ] ; }\n", -"rule makeCommon { _makeCommon $(<) : $(>) ; }\n", +"rule makeCommon { FStripCommon $(<) : $(>) ; }\n", +"rule _makeCommon { FStripCommon $(<) : $(>) ; }\n", "rule makeDirName { $(<) = [ FDirName $(>) ] ; }\n", "rule makeGrist { $(<) = [ FGrist $(>) ] ; }\n", "rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }\n", diff --git a/src/tools/jam/jamgram.c b/src/tools/jam/jamgram.c index 894bc0f807..f59fff33a1 100644 --- a/src/tools/jam/jamgram.c +++ b/src/tools/jam/jamgram.c @@ -23,38 +23,42 @@ #define _RBRACKET_t 273 #define ACTIONS_t 274 #define BIND_t 275 -#define CASE_t 276 -#define DEFAULT_t 277 -#define ELSE_t 278 -#define EXISTING_t 279 -#define FOR_t 280 -#define IF_t 281 -#define IGNORE_t 282 -#define IN_t 283 -#define INCLUDE_t 284 -#define JUMPTOEOF_t 285 -#define LOCAL_t 286 -#define ON_t 287 -#define PIECEMEAL_t 288 -#define QUIETLY_t 289 -#define RETURN_t 290 -#define RULE_t 291 -#define SWITCH_t 292 -#define TOGETHER_t 293 -#define UPDATED_t 294 -#define WHILE_t 295 -#define _LBRACE_t 296 -#define _BAR_t 297 -#define _BARBAR_t 298 -#define _RBRACE_t 299 -#define ARG 300 -#define STRING 301 +#define BREAK_t 276 +#define CASE_t 277 +#define CONTINUE_t 278 +#define DEFAULT_t 279 +#define ELSE_t 280 +#define EXISTING_t 281 +#define FOR_t 282 +#define IF_t 283 +#define IGNORE_t 284 +#define IN_t 285 +#define INCLUDE_t 286 +#define JUMPTOEOF_t 287 +#define LOCAL_t 288 +#define MAXLINE_t 289 +#define ON_t 290 +#define PIECEMEAL_t 291 +#define QUIETLY_t 292 +#define RETURN_t 293 +#define RULE_t 294 +#define SWITCH_t 295 +#define TOGETHER_t 296 +#define UPDATED_t 297 +#define WHILE_t 298 +#define _LBRACE_t 299 +#define _BAR_t 300 +#define _BARBAR_t 301 +#define _RBRACE_t 302 +#define ARG 303 +#define STRING 304 -#line 89 "jamgram.y" +#line 85 "jamgram.y" #include "jam.h" #include "lists.h" +#include "variable.h" #include "parse.h" #include "scan.h" #include "compile.h" @@ -63,16 +67,16 @@ # define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ -# define F0 (LIST *(*)(PARSE *, LOL *))0 +# define F0 (LIST *(*)(PARSE *, LOL *, int *))0 # define P0 (PARSE *)0 # define S0 (char *)0 # define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) +# define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) # define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) # define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) # define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) # define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) -# define pj2eof( ) parse_make( compile_jumptoeof,P0,P0,P0,S0,S0,0 ) # define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) # define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) # define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) @@ -81,7 +85,7 @@ # define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) +# define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) # define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) @@ -104,11 +108,11 @@ -#define YYFINAL 142 +#define YYFINAL 157 #define YYFLAG -32768 -#define YYNTBASE 48 +#define YYNTBASE 51 -#define YYTRANSLATE(x) ((unsigned)(x) <= 301 ? yytranslate[x] : 67) +#define YYTRANSLATE(x) ((unsigned)(x) <= 304 ? yytranslate[x] : 71) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -141,58 +145,62 @@ static const char yytranslate[] = { 0, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47 + 47, 48, 49, 50 }; #if YYDEBUG != 0 static const short yyprhs[] = { 0, 0, 1, 3, 4, 6, 8, 11, 16, 23, 27, - 31, 34, 38, 43, 50, 54, 62, 68, 74, 82, - 88, 92, 96, 97, 98, 108, 110, 112, 114, 117, - 119, 123, 127, 131, 135, 139, 143, 147, 151, 155, - 159, 163, 166, 170, 171, 174, 179, 181, 185, 187, - 188, 191, 193, 194, 199, 202, 207, 212, 213, 216, - 218, 220, 222, 224, 226, 228, 229 + 31, 35, 39, 44, 51, 55, 59, 63, 71, 77, + 83, 91, 97, 104, 108, 109, 110, 120, 122, 124, + 126, 129, 131, 135, 139, 143, 147, 151, 155, 159, + 163, 167, 171, 175, 178, 182, 183, 186, 191, 192, + 196, 198, 200, 204, 206, 207, 210, 212, 213, 218, + 221, 226, 231, 232, 235, 237, 239, 241, 243, 245, + 247, 250, 251 }; static const short yyrhs[] = { -1, - 50, 0, 0, 50, 0, 51, 0, 51, 50, 0, - 32, 59, 11, 49, 0, 32, 59, 14, 59, 11, - 49, 0, 42, 49, 45, 0, 30, 59, 11, 0, - 31, 11, 0, 61, 58, 11, 0, 61, 54, 59, - 11, 0, 61, 33, 59, 54, 59, 11, 0, 36, - 59, 11, 0, 26, 46, 29, 59, 42, 49, 45, - 0, 38, 59, 42, 56, 45, 0, 27, 55, 42, - 49, 45, 0, 27, 55, 42, 49, 45, 24, 51, - 0, 41, 55, 42, 49, 45, 0, 37, 46, 51, - 0, 33, 61, 51, 0, 0, 0, 20, 64, 46, - 66, 42, 52, 47, 53, 45, 0, 14, 0, 9, - 0, 17, 0, 23, 14, 0, 61, 0, 55, 14, - 55, 0, 55, 4, 55, 0, 55, 12, 55, 0, - 55, 13, 55, 0, 55, 15, 55, 0, 55, 16, - 55, 0, 55, 5, 55, 0, 55, 6, 55, 0, - 55, 43, 55, 0, 55, 44, 55, 0, 61, 29, - 59, 0, 3, 55, 0, 7, 55, 8, 0, 0, - 57, 56, 0, 22, 46, 10, 49, 0, 59, 0, - 59, 10, 58, 0, 60, 0, 0, 60, 61, 0, - 46, 0, 0, 18, 62, 63, 19, 0, 61, 58, - 0, 33, 61, 61, 58, 0, 33, 61, 36, 59, - 0, 0, 64, 65, 0, 40, 0, 39, 0, 28, - 0, 35, 0, 34, 0, 25, 0, 0, 21, 59, - 0 + 53, 0, 0, 53, 0, 54, 0, 54, 53, 0, + 34, 63, 11, 52, 0, 34, 63, 14, 63, 11, + 52, 0, 45, 52, 48, 0, 32, 63, 11, 0, + 33, 63, 11, 0, 65, 62, 11, 0, 65, 57, + 63, 11, 0, 65, 36, 63, 57, 63, 11, 0, + 22, 63, 11, 0, 24, 63, 11, 0, 39, 63, + 11, 0, 28, 49, 31, 63, 45, 52, 48, 0, + 41, 63, 45, 59, 48, 0, 29, 58, 45, 52, + 48, 0, 29, 58, 45, 52, 48, 26, 54, 0, + 44, 58, 45, 52, 48, 0, 40, 49, 61, 45, + 52, 48, 0, 36, 65, 54, 0, 0, 0, 20, + 68, 49, 70, 45, 55, 50, 56, 48, 0, 14, + 0, 9, 0, 17, 0, 25, 14, 0, 65, 0, + 58, 14, 58, 0, 58, 4, 58, 0, 58, 12, + 58, 0, 58, 13, 58, 0, 58, 15, 58, 0, + 58, 16, 58, 0, 58, 5, 58, 0, 58, 6, + 58, 0, 58, 46, 58, 0, 58, 47, 58, 0, + 65, 31, 63, 0, 3, 58, 0, 7, 58, 8, + 0, 0, 60, 59, 0, 23, 49, 10, 52, 0, + 0, 49, 10, 61, 0, 49, 0, 63, 0, 63, + 10, 62, 0, 64, 0, 0, 64, 65, 0, 49, + 0, 0, 18, 66, 67, 19, 0, 65, 62, 0, + 36, 65, 65, 62, 0, 36, 65, 39, 63, 0, + 0, 68, 69, 0, 43, 0, 42, 0, 30, 0, + 38, 0, 37, 0, 27, 0, 35, 49, 0, 0, + 21, 63, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, - 131, 133, 144, 146, 150, 152, 154, 156, 160, 162, - 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, - 184, 186, 188, 191, 193, 200, 202, 204, 206, 214, - 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, - 236, 238, 240, 250, 252, 256, 265, 267, 277, 281, - 283, 287, 289, 289, 298, 300, 302, 311, 313, 317, - 319, 321, 323, 325, 327, 336, 338 + 128, 130, 141, 143, 147, 149, 151, 153, 157, 159, + 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, + 181, 183, 185, 187, 189, 192, 194, 201, 203, 205, + 207, 215, 217, 219, 221, 223, 225, 227, 229, 231, + 233, 235, 237, 239, 241, 251, 253, 257, 266, 268, + 270, 279, 281, 291, 295, 297, 301, 303, 303, 312, + 314, 316, 325, 327, 331, 333, 335, 337, 339, 341, + 343, 352, 354 }; #endif @@ -203,137 +211,143 @@ static const char * const yytname[] = { "$","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","DEFAULT_t","ELSE_t","EXISTING_t","FOR_t","IF_t","IGNORE_t", -"IN_t","INCLUDE_t","JUMPTOEOF_t","LOCAL_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","run","block","rules","rule", -"@1","@2","assign","expr","cases","case","lol","list","listp","arg","@3","func", -"eflags","eflag","bindlist", NULL +"BIND_t","BREAK_t","CASE_t","CONTINUE_t","DEFAULT_t","ELSE_t","EXISTING_t","FOR_t", +"IF_t","IGNORE_t","IN_t","INCLUDE_t","JUMPTOEOF_t","LOCAL_t","MAXLINE_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","run", +"block","rules","rule","@1","@2","assign","expr","cases","case","params","lol", +"list","listp","arg","@3","func","eflags","eflag","bindlist", NULL }; #endif static const short yyr1[] = { 0, - 48, 48, 49, 49, 50, 50, 50, 50, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 52, 53, 51, 54, 54, 54, 54, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 56, 56, 57, 58, 58, 59, 60, - 60, 61, 62, 61, 63, 63, 63, 64, 64, 65, - 65, 65, 65, 65, 65, 66, 66 + 51, 51, 52, 52, 53, 53, 53, 53, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 55, 56, 54, 57, 57, 57, + 57, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 59, 59, 60, 61, 61, + 61, 62, 62, 63, 64, 64, 65, 66, 65, 67, + 67, 67, 68, 68, 69, 69, 69, 69, 69, 69, + 69, 70, 70 }; static const short yyr2[] = { 0, 0, 1, 0, 1, 1, 2, 4, 6, 3, 3, - 2, 3, 4, 6, 3, 7, 5, 5, 7, 5, - 3, 3, 0, 0, 9, 1, 1, 1, 2, 1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 0, 2, 4, 1, 3, 1, 0, - 2, 1, 0, 4, 2, 4, 4, 0, 2, 1, - 1, 1, 1, 1, 1, 0, 2 + 3, 3, 4, 6, 3, 3, 3, 7, 5, 5, + 7, 5, 6, 3, 0, 0, 9, 1, 1, 1, + 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 3, 0, 2, 4, 0, 3, + 1, 1, 3, 1, 0, 2, 1, 0, 4, 2, + 4, 4, 0, 2, 1, 1, 1, 1, 1, 1, + 2, 0, 2 }; static const short yydefact[] = { 1, - 53, 58, 0, 0, 50, 0, 50, 0, 50, 0, - 50, 0, 3, 52, 2, 5, 50, 0, 0, 0, - 0, 0, 0, 30, 0, 49, 11, 0, 0, 0, - 0, 0, 0, 0, 4, 6, 27, 26, 28, 0, - 50, 50, 0, 47, 0, 50, 0, 65, 62, 64, - 63, 61, 60, 66, 59, 50, 42, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 0, 0, 50, - 10, 51, 3, 50, 22, 15, 21, 44, 3, 9, - 29, 0, 0, 12, 50, 0, 55, 54, 50, 0, - 0, 43, 32, 37, 38, 33, 34, 31, 35, 36, - 0, 39, 40, 41, 7, 0, 0, 0, 44, 0, - 50, 13, 48, 50, 50, 67, 23, 3, 18, 3, - 0, 17, 45, 20, 0, 57, 56, 0, 0, 0, - 8, 3, 14, 24, 16, 19, 46, 0, 25, 0, - 0, 0 + 58, 63, 55, 55, 0, 0, 55, 55, 55, 0, + 55, 0, 55, 0, 3, 57, 2, 5, 55, 0, + 0, 0, 54, 0, 0, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 49, 0, 0, 0, 4, 6, + 29, 28, 30, 0, 55, 55, 0, 52, 0, 55, + 0, 70, 67, 0, 69, 68, 66, 65, 72, 64, + 15, 56, 16, 55, 44, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 55, 10, 11, + 3, 55, 24, 17, 51, 0, 46, 3, 9, 31, + 0, 0, 12, 55, 0, 60, 59, 71, 55, 0, + 0, 45, 34, 39, 40, 35, 36, 33, 37, 38, + 0, 41, 42, 43, 7, 0, 49, 3, 0, 0, + 46, 0, 55, 13, 53, 55, 55, 73, 25, 3, + 20, 3, 50, 0, 0, 19, 47, 22, 0, 62, + 61, 0, 0, 0, 8, 23, 3, 14, 26, 18, + 21, 48, 0, 27, 0, 0, 0 }; -static const short yydefgoto[] = { 140, - 34, 35, 16, 128, 138, 42, 23, 108, 109, 43, - 44, 26, 24, 18, 47, 19, 55, 90 +static const short yydefgoto[] = { 155, + 38, 39, 18, 142, 153, 46, 28, 120, 121, 86, + 47, 48, 23, 29, 20, 51, 21, 60, 100 }; -static const short yypact[] = { 140, --32768,-32768, -26, 7,-32768, 30,-32768, 1,-32768, -22, --32768, 7, 140,-32768,-32768, 140, 13, -12, 184, 10, - 7, 7, 100, 15, 31, 1,-32768, 21, 169, 43, - 169, 26, 121, 18,-32768,-32768,-32768,-32768,-32768, 41, --32768,-32768, 58, 61, 1,-32768, 55,-32768,-32768,-32768, --32768,-32768,-32768, 54,-32768,-32768,-32768, 141, 7, 7, - 7, 7, 7, 7, 7, 7, 140, 7, 7,-32768, --32768,-32768, 140,-32768,-32768,-32768,-32768, 73, 140,-32768, --32768, 42, 66,-32768,-32768, -3,-32768,-32768,-32768, 56, - 57,-32768, 45, 68, 68,-32768,-32768, 45,-32768,-32768, - 63, 221, 221,-32768,-32768, 89, 65, 64, 73, 72, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 140, 77, 140, - 92,-32768,-32768,-32768, 108,-32768,-32768, 74, 78, 169, --32768, 140,-32768,-32768,-32768,-32768,-32768, 79,-32768, 122, - 128,-32768 +static const short yypact[] = { 141, +-32768,-32768,-32768,-32768, -45, 14,-32768,-32768,-32768, 1, +-32768, -37,-32768, 14, 141,-32768,-32768, 141, 103, 6, + 185, 2, 1, 3, -5, 14, 14, 25, -4, 36, + 42, 37, 169, 43, -13, 15, 121, 11,-32768,-32768, +-32768,-32768,-32768, 47,-32768,-32768, 53, 56, 1,-32768, + 48,-32768,-32768, 19,-32768,-32768,-32768,-32768, 52,-32768, +-32768,-32768,-32768,-32768,-32768, 137, 14, 14, 14, 14, + 14, 14, 14, 14, 141, 14, 14,-32768,-32768,-32768, + 141,-32768,-32768,-32768, 59, 29, 55, 141,-32768,-32768, + 186, 78,-32768,-32768, 7,-32768,-32768,-32768,-32768, 45, + 46,-32768, 71, 142, 142,-32768,-32768, 71,-32768,-32768, + 34, 225, 225,-32768,-32768, 81, -13, 141, 44, 58, + 55, 61,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 141, + 70, 141,-32768, 62, 101,-32768,-32768,-32768, 102,-32768, +-32768, 65, 68, 169,-32768,-32768, 141,-32768,-32768,-32768, +-32768,-32768, 74,-32768, 119, 123,-32768 }; static const short yypgoto[] = {-32768, - -56, 12, -27,-32768,-32768, 47, 28, 22,-32768, -37, - -4,-32768, 0,-32768,-32768,-32768,-32768,-32768 + -53, 16, -30,-32768,-32768, 38, 31, 10,-32768, 21, + -42, -2,-32768, 0,-32768,-32768,-32768,-32768,-32768 }; -#define YYLAST 237 +#define YYLAST 241 -static const short yytable[] = { 17, - 25, 75, 28, 77, 30, 1, 32, 29, 87, 21, - 101, 15, 17, 22, 1, 17, 105, 46, 1, 20, - 45, 37, 110, 31, 1, 72, 38, 36, 17, 39, - 17, 73, 114, 14, 74, 40, 82, 83, 56, 33, - 27, 71, 14, 70, 86, 41, 14, 113, 57, 58, - 37, 91, 14, 76, 81, 38, 62, 63, 39, 65, - 66, 129, 80, 131, 40, 104, 17, 78, 84, 106, - 85, 59, 17, 88, 89, 137, 112, 127, 17, 62, - 63, 64, 65, 66, 116, 115, 93, 94, 95, 96, - 97, 98, 99, 100, 107, 102, 103, 117, 118, 120, - 130, 132, 136, 59, 60, 61, 125, 119, 122, 126, - 121, 62, 63, 64, 65, 66, 124, 17, 133, 17, - 134, 141, 135, 139, 59, 60, 61, 142, 111, 17, - 123, 17, 62, 63, 64, 65, 66, 0, 0, 0, - 0, 67, 68, 69, 59, 60, 61, 0, 92, 0, - 0, 0, 62, 63, 64, 65, 66, 1, 0, 2, - 0, 0, 79, 68, 69, 3, 4, 0, 0, 5, - 6, 7, 8, 0, 0, 9, 10, 11, 0, 0, - 12, 13, 0, 68, 69, 14, 1, 0, 2, 0, - 0, 0, 0, 0, 3, 4, 0, 0, 5, 6, - 0, 8, 0, 0, 9, 10, 11, 0, 48, 12, - 13, 49, 0, 0, 14, 0, 0, 50, 51, 0, - 0, 0, 52, 53, 59, 60, 61, 0, 0, 54, - 0, 0, 62, 63, 64, 65, 66 +static const short yytable[] = { 19, + 22, 24, 83, 25, 30, 31, 32, 96, 34, 33, + 36, 35, 61, 63, 19, 17, 26, 19, 1, 50, + 27, 111, 62, 1, 1, 64, 78, 115, 67, 68, + 69, 1, 19, 40, 122, 85, 70, 71, 72, 73, + 74, 49, 91, 92, 37, 126, 79, 81, 95, 16, + 82, 125, 80, 84, 16, 16, 65, 66, 89, 87, + 90, 101, 16, 93, 134, 94, 97, 98, 117, 75, + 76, 77, 99, 118, 19, 114, 143, 119, 145, 116, + 19, 131, 70, 71, 141, 73, 74, 19, 124, 129, + 130, 132, 135, 152, 127, 144, 128, 103, 104, 105, + 106, 107, 108, 109, 110, 136, 112, 113, 138, 146, + 147, 41, 148, 151, 149, 150, 42, 19, 156, 43, + 139, 154, 157, 140, 67, 68, 69, 44, 123, 19, + 137, 19, 70, 71, 72, 73, 74, 133, 45, 0, + 67, 68, 69, 19, 102, 67, 19, 0, 70, 71, + 72, 73, 74, 70, 71, 72, 73, 74, 1, 0, + 2, 0, 3, 0, 4, 88, 76, 77, 5, 6, + 0, 0, 7, 8, 9, 0, 10, 0, 0, 11, + 12, 13, 76, 77, 14, 15, 1, 0, 2, 16, + 3, 0, 4, 0, 41, 0, 5, 6, 0, 42, + 7, 8, 43, 0, 10, 0, 0, 11, 12, 13, + 44, 52, 14, 15, 53, 0, 0, 16, 0, 54, + 0, 55, 56, 0, 0, 0, 57, 58, 67, 68, + 69, 0, 0, 59, 0, 0, 70, 71, 72, 73, + 74 }; static const short yycheck[] = { 0, - 5, 29, 7, 31, 9, 18, 11, 8, 46, 3, - 67, 0, 13, 7, 18, 16, 73, 18, 18, 46, - 33, 9, 79, 46, 18, 26, 14, 16, 29, 17, - 31, 11, 36, 46, 14, 23, 41, 42, 29, 12, - 11, 11, 46, 29, 45, 33, 46, 85, 21, 22, - 9, 56, 46, 11, 14, 14, 12, 13, 17, 15, - 16, 118, 45, 120, 23, 70, 67, 42, 11, 74, - 10, 4, 73, 19, 21, 132, 11, 115, 79, 12, - 13, 14, 15, 16, 89, 86, 59, 60, 61, 62, - 63, 64, 65, 66, 22, 68, 69, 42, 42, 11, - 24, 10, 130, 4, 5, 6, 111, 45, 45, 114, - 46, 12, 13, 14, 15, 16, 45, 118, 11, 120, - 47, 0, 45, 45, 4, 5, 6, 0, 82, 130, - 109, 132, 12, 13, 14, 15, 16, -1, -1, -1, - -1, 42, 43, 44, 4, 5, 6, -1, 8, -1, - -1, -1, 12, 13, 14, 15, 16, 18, -1, 20, - -1, -1, 42, 43, 44, 26, 27, -1, -1, 30, - 31, 32, 33, -1, -1, 36, 37, 38, -1, -1, - 41, 42, -1, 43, 44, 46, 18, -1, 20, -1, - -1, -1, -1, -1, 26, 27, -1, -1, 30, 31, - -1, 33, -1, -1, 36, 37, 38, -1, 25, 41, - 42, 28, -1, -1, 46, -1, -1, 34, 35, -1, - -1, -1, 39, 40, 4, 5, 6, -1, -1, 46, - -1, -1, 12, 13, 14, 15, 16 + 3, 4, 33, 49, 7, 8, 9, 50, 11, 10, + 13, 49, 11, 11, 15, 0, 3, 18, 18, 20, + 7, 75, 23, 18, 18, 31, 31, 81, 4, 5, + 6, 18, 33, 18, 88, 49, 12, 13, 14, 15, + 16, 36, 45, 46, 14, 39, 11, 11, 49, 49, + 14, 94, 11, 11, 49, 49, 26, 27, 48, 45, + 14, 64, 49, 11, 118, 10, 19, 49, 10, 45, + 46, 47, 21, 45, 75, 78, 130, 23, 132, 82, + 81, 48, 12, 13, 127, 15, 16, 88, 11, 45, + 45, 11, 49, 147, 95, 26, 99, 67, 68, 69, + 70, 71, 72, 73, 74, 48, 76, 77, 48, 48, + 10, 9, 11, 144, 50, 48, 14, 118, 0, 17, + 123, 48, 0, 126, 4, 5, 6, 25, 91, 130, + 121, 132, 12, 13, 14, 15, 16, 117, 36, -1, + 4, 5, 6, 144, 8, 4, 147, -1, 12, 13, + 14, 15, 16, 12, 13, 14, 15, 16, 18, -1, + 20, -1, 22, -1, 24, 45, 46, 47, 28, 29, + -1, -1, 32, 33, 34, -1, 36, -1, -1, 39, + 40, 41, 46, 47, 44, 45, 18, -1, 20, 49, + 22, -1, 24, -1, 9, -1, 28, 29, -1, 14, + 32, 33, 17, -1, 36, -1, -1, 39, 40, 41, + 25, 27, 44, 45, 30, -1, -1, 49, -1, 35, + -1, 37, 38, -1, -1, -1, 42, 43, 4, 5, + 6, -1, -1, 49, -1, -1, 12, 13, 14, 15, + 16 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/etc/bison.simple" @@ -881,267 +895,291 @@ yyreduce: switch (yyn) { case 2: -#line 134 "jamgram.y" +#line 131 "jamgram.y" { parse_save( yyvsp[0].parse ); ; break;} case 3: -#line 145 "jamgram.y" +#line 142 "jamgram.y" { yyval.parse = pnull(); ; break;} case 4: -#line 147 "jamgram.y" +#line 144 "jamgram.y" { yyval.parse = yyvsp[0].parse; ; break;} case 5: -#line 151 "jamgram.y" +#line 148 "jamgram.y" { yyval.parse = yyvsp[0].parse; ; break;} case 6: -#line 153 "jamgram.y" +#line 150 "jamgram.y" { yyval.parse = prules( yyvsp[-1].parse, yyvsp[0].parse ); ; break;} case 7: -#line 155 "jamgram.y" +#line 152 "jamgram.y" { yyval.parse = plocal( yyvsp[-2].parse, pnull(), yyvsp[0].parse ); ; break;} case 8: -#line 157 "jamgram.y" +#line 154 "jamgram.y" { yyval.parse = plocal( yyvsp[-4].parse, yyvsp[-2].parse, yyvsp[0].parse ); ; break;} case 9: -#line 161 "jamgram.y" +#line 158 "jamgram.y" { yyval.parse = yyvsp[-1].parse; ; break;} case 10: -#line 163 "jamgram.y" +#line 160 "jamgram.y" { yyval.parse = pincl( yyvsp[-1].parse ); ; break;} case 11: -#line 165 "jamgram.y" -{ yyval.parse = pj2eof( ); ; +#line 162 "jamgram.y" +{ yyval.parse = pbreak( yyvsp[-1].parse, JMP_EOF ); ; break;} case 12: -#line 167 "jamgram.y" +#line 164 "jamgram.y" { yyval.parse = prule( yyvsp[-2].parse, yyvsp[-1].parse ); ; break;} case 13: -#line 169 "jamgram.y" +#line 166 "jamgram.y" { yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; break;} case 14: -#line 171 "jamgram.y" +#line 168 "jamgram.y" { yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; break;} case 15: -#line 173 "jamgram.y" -{ yyval.parse = yyvsp[-1].parse; ; +#line 170 "jamgram.y" +{ yyval.parse = pbreak( yyvsp[-1].parse, JMP_BREAK ); ; break;} case 16: -#line 175 "jamgram.y" -{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse ); ; +#line 172 "jamgram.y" +{ yyval.parse = pbreak( yyvsp[-1].parse, JMP_CONTINUE ); ; break;} case 17: -#line 177 "jamgram.y" -{ yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); ; +#line 174 "jamgram.y" +{ yyval.parse = pbreak( yyvsp[-1].parse, JMP_RETURN ); ; break;} case 18: -#line 179 "jamgram.y" -{ yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); ; +#line 176 "jamgram.y" +{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse ); ; break;} case 19: -#line 181 "jamgram.y" -{ yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); ; +#line 178 "jamgram.y" +{ yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); ; break;} case 20: -#line 183 "jamgram.y" -{ yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); ; +#line 180 "jamgram.y" +{ yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); ; break;} case 21: -#line 185 "jamgram.y" -{ yyval.parse = psetc( yyvsp[-1].string, yyvsp[0].parse ); ; +#line 182 "jamgram.y" +{ yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); ; break;} case 22: -#line 187 "jamgram.y" -{ yyval.parse = pon( yyvsp[-1].parse, yyvsp[0].parse ); ; +#line 184 "jamgram.y" +{ yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); ; break;} case 23: -#line 189 "jamgram.y" -{ yymode( SCAN_STRING ); ; +#line 186 "jamgram.y" +{ yyval.parse = psetc( yyvsp[-4].string, yyvsp[-3].parse, yyvsp[-1].parse ); ; break;} case 24: -#line 191 "jamgram.y" -{ yymode( SCAN_NORMAL ); ; +#line 188 "jamgram.y" +{ yyval.parse = pon( yyvsp[-1].parse, yyvsp[0].parse ); ; break;} case 25: -#line 193 "jamgram.y" -{ yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); ; +#line 190 "jamgram.y" +{ yymode( SCAN_STRING ); ; break;} case 26: -#line 201 "jamgram.y" -{ yyval.number = ASSIGN_SET; ; - break;} -case 27: -#line 203 "jamgram.y" -{ yyval.number = ASSIGN_APPEND; ; - break;} -case 28: -#line 205 "jamgram.y" -{ yyval.number = ASSIGN_DEFAULT; ; - break;} -case 29: -#line 207 "jamgram.y" -{ yyval.number = ASSIGN_DEFAULT; ; - break;} -case 30: -#line 215 "jamgram.y" -{ yyval.parse = peval( EXPR_EXISTS, yyvsp[0].parse, pnull() ); ; - break;} -case 31: -#line 217 "jamgram.y" -{ yyval.parse = peval( EXPR_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 32: -#line 219 "jamgram.y" -{ yyval.parse = peval( EXPR_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 33: -#line 221 "jamgram.y" -{ yyval.parse = peval( EXPR_LESS, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 34: -#line 223 "jamgram.y" -{ yyval.parse = peval( EXPR_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 35: -#line 225 "jamgram.y" -{ yyval.parse = peval( EXPR_MORE, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 36: -#line 227 "jamgram.y" -{ yyval.parse = peval( EXPR_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 37: -#line 229 "jamgram.y" -{ yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 38: -#line 231 "jamgram.y" -{ yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 39: -#line 233 "jamgram.y" -{ yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 40: -#line 235 "jamgram.y" -{ yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 41: -#line 237 "jamgram.y" -{ yyval.parse = peval( EXPR_IN, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 42: -#line 239 "jamgram.y" -{ yyval.parse = peval( EXPR_NOT, yyvsp[0].parse, pnull() ); ; - break;} -case 43: -#line 241 "jamgram.y" -{ yyval.parse = yyvsp[-1].parse; ; - break;} -case 44: -#line 251 "jamgram.y" -{ yyval.parse = P0; ; - break;} -case 45: -#line 253 "jamgram.y" -{ yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); ; - break;} -case 46: -#line 257 "jamgram.y" -{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); ; - break;} -case 47: -#line 266 "jamgram.y" -{ yyval.parse = pnode( P0, yyvsp[0].parse ); ; - break;} -case 48: -#line 268 "jamgram.y" -{ yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); ; - break;} -case 49: -#line 278 "jamgram.y" -{ yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); ; - break;} -case 50: -#line 282 "jamgram.y" -{ yyval.parse = pnull(); yymode( SCAN_PUNCT ); ; - break;} -case 51: -#line 284 "jamgram.y" -{ yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); ; - break;} -case 52: -#line 288 "jamgram.y" -{ yyval.parse = plist( yyvsp[0].string ); ; - break;} -case 53: -#line 289 "jamgram.y" +#line 192 "jamgram.y" { yymode( SCAN_NORMAL ); ; break;} -case 54: -#line 290 "jamgram.y" +case 27: +#line 194 "jamgram.y" +{ yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); ; + break;} +case 28: +#line 202 "jamgram.y" +{ yyval.number = VAR_SET; ; + break;} +case 29: +#line 204 "jamgram.y" +{ yyval.number = VAR_APPEND; ; + break;} +case 30: +#line 206 "jamgram.y" +{ yyval.number = VAR_DEFAULT; ; + break;} +case 31: +#line 208 "jamgram.y" +{ yyval.number = VAR_DEFAULT; ; + break;} +case 32: +#line 216 "jamgram.y" +{ yyval.parse = peval( EXPR_EXISTS, yyvsp[0].parse, pnull() ); ; + break;} +case 33: +#line 218 "jamgram.y" +{ yyval.parse = peval( EXPR_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 34: +#line 220 "jamgram.y" +{ yyval.parse = peval( EXPR_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 35: +#line 222 "jamgram.y" +{ yyval.parse = peval( EXPR_LESS, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 36: +#line 224 "jamgram.y" +{ yyval.parse = peval( EXPR_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 37: +#line 226 "jamgram.y" +{ yyval.parse = peval( EXPR_MORE, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 38: +#line 228 "jamgram.y" +{ yyval.parse = peval( EXPR_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 39: +#line 230 "jamgram.y" +{ yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 40: +#line 232 "jamgram.y" +{ yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 41: +#line 234 "jamgram.y" +{ yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 42: +#line 236 "jamgram.y" +{ yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 43: +#line 238 "jamgram.y" +{ yyval.parse = peval( EXPR_IN, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 44: +#line 240 "jamgram.y" +{ yyval.parse = peval( EXPR_NOT, yyvsp[0].parse, pnull() ); ; + break;} +case 45: +#line 242 "jamgram.y" { yyval.parse = yyvsp[-1].parse; ; break;} +case 46: +#line 252 "jamgram.y" +{ yyval.parse = P0; ; + break;} +case 47: +#line 254 "jamgram.y" +{ yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); ; + break;} +case 48: +#line 258 "jamgram.y" +{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); ; + break;} +case 49: +#line 267 "jamgram.y" +{ yyval.parse = P0; ; + break;} +case 50: +#line 269 "jamgram.y" +{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); ; + break;} +case 51: +#line 271 "jamgram.y" +{ yyval.parse = psnode( yyvsp[0].string, P0 ); ; + break;} +case 52: +#line 280 "jamgram.y" +{ yyval.parse = pnode( P0, yyvsp[0].parse ); ; + break;} +case 53: +#line 282 "jamgram.y" +{ yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); ; + break;} +case 54: +#line 292 "jamgram.y" +{ yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); ; + break;} case 55: -#line 299 "jamgram.y" -{ yyval.parse = prule( yyvsp[-1].parse, yyvsp[0].parse ); ; +#line 296 "jamgram.y" +{ yyval.parse = pnull(); yymode( SCAN_PUNCT ); ; break;} case 56: -#line 301 "jamgram.y" -{ yyval.parse = pon( yyvsp[-2].parse, prule( yyvsp[-1].parse, yyvsp[0].parse ) ); ; +#line 298 "jamgram.y" +{ yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); ; break;} case 57: -#line 303 "jamgram.y" -{ yyval.parse = pon( yyvsp[-2].parse, yyvsp[0].parse ); ; +#line 302 "jamgram.y" +{ yyval.parse = plist( yyvsp[0].string ); ; break;} case 58: -#line 312 "jamgram.y" -{ yyval.number = 0; ; +#line 303 "jamgram.y" +{ yymode( SCAN_NORMAL ); ; break;} case 59: -#line 314 "jamgram.y" -{ yyval.number = yyvsp[-1].number | yyvsp[0].number; ; +#line 304 "jamgram.y" +{ yyval.parse = yyvsp[-1].parse; ; break;} case 60: -#line 318 "jamgram.y" -{ yyval.number = RULE_UPDATED; ; +#line 313 "jamgram.y" +{ yyval.parse = prule( yyvsp[-1].parse, yyvsp[0].parse ); ; break;} case 61: -#line 320 "jamgram.y" -{ yyval.number = RULE_TOGETHER; ; +#line 315 "jamgram.y" +{ yyval.parse = pon( yyvsp[-2].parse, prule( yyvsp[-1].parse, yyvsp[0].parse ) ); ; break;} case 62: -#line 322 "jamgram.y" -{ yyval.number = RULE_IGNORE; ; +#line 317 "jamgram.y" +{ yyval.parse = pon( yyvsp[-2].parse, yyvsp[0].parse ); ; break;} case 63: -#line 324 "jamgram.y" -{ yyval.number = RULE_QUIETLY; ; +#line 326 "jamgram.y" +{ yyval.number = 0; ; break;} case 64: -#line 326 "jamgram.y" -{ yyval.number = RULE_PIECEMEAL; ; +#line 328 "jamgram.y" +{ yyval.number = yyvsp[-1].number | yyvsp[0].number; ; break;} case 65: -#line 328 "jamgram.y" -{ yyval.number = RULE_EXISTING; ; +#line 332 "jamgram.y" +{ yyval.number = RULE_UPDATED; ; break;} case 66: -#line 337 "jamgram.y" -{ yyval.parse = pnull(); ; +#line 334 "jamgram.y" +{ yyval.number = RULE_TOGETHER; ; break;} case 67: -#line 339 "jamgram.y" +#line 336 "jamgram.y" +{ yyval.number = RULE_IGNORE; ; + break;} +case 68: +#line 338 "jamgram.y" +{ yyval.number = RULE_QUIETLY; ; + break;} +case 69: +#line 340 "jamgram.y" +{ yyval.number = RULE_PIECEMEAL; ; + break;} +case 70: +#line 342 "jamgram.y" +{ yyval.number = RULE_EXISTING; ; + break;} +case 71: +#line 344 "jamgram.y" +{ yyval.number = atoi( yyvsp[0].string ) * RULE_MAXLINE; ; + break;} +case 72: +#line 353 "jamgram.y" +{ yyval.parse = pnull(); ; + break;} +case 73: +#line 355 "jamgram.y" { yyval.parse = yyvsp[0].parse; ; break;} } @@ -1370,4 +1408,4 @@ yyerrhandle: } return 1; } -#line 343 "jamgram.y" +#line 359 "jamgram.y" diff --git a/src/tools/jam/jamgram.h b/src/tools/jam/jamgram.h index 22d0479c11..6a40a7671f 100644 --- a/src/tools/jam/jamgram.h +++ b/src/tools/jam/jamgram.h @@ -20,32 +20,35 @@ #define _RBRACKET_t 273 #define ACTIONS_t 274 #define BIND_t 275 -#define CASE_t 276 -#define DEFAULT_t 277 -#define ELSE_t 278 -#define EXISTING_t 279 -#define FOR_t 280 -#define IF_t 281 -#define IGNORE_t 282 -#define IN_t 283 -#define INCLUDE_t 284 -#define JUMPTOEOF_t 285 -#define LOCAL_t 286 -#define ON_t 287 -#define PIECEMEAL_t 288 -#define QUIETLY_t 289 -#define RETURN_t 290 -#define RULE_t 291 -#define SWITCH_t 292 -#define TOGETHER_t 293 -#define UPDATED_t 294 -#define WHILE_t 295 -#define _LBRACE_t 296 -#define _BAR_t 297 -#define _BARBAR_t 298 -#define _RBRACE_t 299 -#define ARG 300 -#define STRING 301 +#define BREAK_t 276 +#define CASE_t 277 +#define CONTINUE_t 278 +#define DEFAULT_t 279 +#define ELSE_t 280 +#define EXISTING_t 281 +#define FOR_t 282 +#define IF_t 283 +#define IGNORE_t 284 +#define IN_t 285 +#define INCLUDE_t 286 +#define JUMPTOEOF_t 287 +#define LOCAL_t 288 +#define MAXLINE_t 289 +#define ON_t 290 +#define PIECEMEAL_t 291 +#define QUIETLY_t 292 +#define RETURN_t 293 +#define RULE_t 294 +#define SWITCH_t 295 +#define TOGETHER_t 296 +#define UPDATED_t 297 +#define WHILE_t 298 +#define _LBRACE_t 299 +#define _BAR_t 300 +#define _BARBAR_t 301 +#define _RBRACE_t 302 +#define ARG 303 +#define STRING 304 extern YYSTYPE yylval; diff --git a/src/tools/jam/jamgram.y b/src/tools/jam/jamgram.y index 7db1b61096..096357f3ad 100644 --- a/src/tools/jam/jamgram.y +++ b/src/tools/jam/jamgram.y @@ -17,7 +17,9 @@ %token _RBRACKET_t %token ACTIONS_t %token BIND_t +%token BREAK_t %token CASE_t +%token CONTINUE_t %token DEFAULT_t %token ELSE_t %token EXISTING_t @@ -28,6 +30,7 @@ %token INCLUDE_t %token JUMPTOEOF_t %token LOCAL_t +%token MAXLINE_t %token ON_t %token PIECEMEAL_t %token QUIETLY_t @@ -59,23 +62,16 @@ * 02/11/95 (seiwald) - when scanning arguments to rules, only treat * punctuation keywords as keywords. All arg lists * are terminated with punctuation keywords. - * - * 09/11/00 (seiwald) - Support for function calls: - * - * Rules now return lists (LIST *), rather than void. - * - * New "[ rule ]" syntax evals rule into a LIST. - * - * Lists are now generated by compile_list() and - * compile_append(), and any other rule that indirectly - * makes a list, rather than being built directly here, - * so that lists values can contain rule evaluations. - * - * New 'return' rule sets the return value, though - * other statements also may have return values. - * - * 'run' production split from 'block' production so - * that empty blocks can be handled separately. + * 09/11/00 (seiwald) - Support for function calls; rules return LIST *. + * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() + * 01/24/01 (seiwald) - 'while' statement + * 03/23/01 (seiwald) - "[ on target rule ]" support + * 02/27/02 (seiwald) - un-break "expr : arg in list" syntax + * 03/02/02 (seiwald) - rules can be invoked via variable names + * 03/12/02 (seiwald) - set YYMAXDEPTH for big, right-recursive rules + * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx + * 06/21/02 (seiwald) - support for named parameters + * 10/22/02 (seiwald) - working return/break/continue statements */ %token ARG STRING @@ -90,6 +86,7 @@ #include "jam.h" #include "lists.h" +#include "variable.h" #include "parse.h" #include "scan.h" #include "compile.h" @@ -98,16 +95,16 @@ # define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ -# define F0 (LIST *(*)(PARSE *, LOL *))0 +# define F0 (LIST *(*)(PARSE *, LOL *, int *))0 # define P0 (PARSE *)0 # define S0 (char *)0 # define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) +# define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) # define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) # define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) # define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) # define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) -# define pj2eof( ) parse_make( compile_jumptoeof,P0,P0,P0,S0,S0,0 ) # define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) # define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) # define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) @@ -116,7 +113,7 @@ # define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) +# define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) # define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) @@ -161,16 +158,20 @@ rule : _LBRACE_t block _RBRACE_t { $$.parse = $2.parse; } | INCLUDE_t list _SEMIC_t { $$.parse = pincl( $2.parse ); } - | JUMPTOEOF_t _SEMIC_t - { $$.parse = pj2eof( ); } + | JUMPTOEOF_t list _SEMIC_t + { $$.parse = pbreak( $2.parse, JMP_EOF ); } | arg lol _SEMIC_t { $$.parse = prule( $1.parse, $2.parse ); } | arg assign list _SEMIC_t { $$.parse = pset( $1.parse, $3.parse, $2.number ); } | arg ON_t list assign list _SEMIC_t { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } + | BREAK_t list _SEMIC_t + { $$.parse = pbreak( $2.parse, JMP_BREAK ); } + | CONTINUE_t list _SEMIC_t + { $$.parse = pbreak( $2.parse, JMP_CONTINUE ); } | RETURN_t list _SEMIC_t - { $$.parse = $2.parse; } + { $$.parse = pbreak( $2.parse, JMP_RETURN ); } | FOR_t ARG IN_t list _LBRACE_t block _RBRACE_t { $$.parse = pfor( $2.string, $4.parse, $6.parse ); } | SWITCH_t list _LBRACE_t cases _RBRACE_t @@ -181,8 +182,8 @@ rule : _LBRACE_t block _RBRACE_t { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } | WHILE_t expr _LBRACE_t block _RBRACE_t { $$.parse = pwhile( $2.parse, $4.parse ); } - | RULE_t ARG rule - { $$.parse = psetc( $2.string, $3.parse ); } + | RULE_t ARG params _LBRACE_t block _RBRACE_t + { $$.parse = psetc( $2.string, $3.parse, $5.parse ); } | ON_t arg rule { $$.parse = pon( $2.parse, $3.parse ); } | ACTIONS_t eflags ARG bindlist _LBRACE_t @@ -198,13 +199,13 @@ rule : _LBRACE_t block _RBRACE_t */ assign : _EQUALS_t - { $$.number = ASSIGN_SET; } + { $$.number = VAR_SET; } | _PLUS_EQUALS_t - { $$.number = ASSIGN_APPEND; } + { $$.number = VAR_APPEND; } | _QUESTION_EQUALS_t - { $$.number = ASSIGN_DEFAULT; } + { $$.number = VAR_DEFAULT; } | DEFAULT_t _EQUALS_t - { $$.number = ASSIGN_DEFAULT; } + { $$.number = VAR_DEFAULT; } ; /* @@ -257,6 +258,19 @@ case : CASE_t ARG _COLON_t block { $$.parse = psnode( $2.string, $4.parse ); } ; +/* + * params - optional parameter names to rule definition + * right-recursive rule so that params can be added in order. + */ + +params : /* empty */ + { $$.parse = P0; } + | ARG _COLON_t params + { $$.parse = psnode( $1.string, $3.parse ); } + | ARG + { $$.parse = psnode( $1.string, P0 ); } + ; + /* * lol - list of lists * right-recursive rule so that lists can be added in order. @@ -326,6 +340,8 @@ eflag : UPDATED_t { $$.number = RULE_PIECEMEAL; } | EXISTING_t { $$.number = RULE_EXISTING; } + | MAXLINE_t ARG + { $$.number = atoi( $2.string ) * RULE_MAXLINE; } ; diff --git a/src/tools/jam/jamgram.yy b/src/tools/jam/jamgram.yy index f17f4ce09a..4687bc9f7d 100644 --- a/src/tools/jam/jamgram.yy +++ b/src/tools/jam/jamgram.yy @@ -16,23 +16,16 @@ * 02/11/95 (seiwald) - when scanning arguments to rules, only treat * punctuation keywords as keywords. All arg lists * are terminated with punctuation keywords. - * - * 09/11/00 (seiwald) - Support for function calls: - * - * Rules now return lists (LIST *), rather than void. - * - * New "[ rule ]" syntax evals rule into a LIST. - * - * Lists are now generated by compile_list() and - * compile_append(), and any other rule that indirectly - * makes a list, rather than being built directly here, - * so that lists values can contain rule evaluations. - * - * New 'return' rule sets the return value, though - * other statements also may have return values. - * - * 'run' production split from 'block' production so - * that empty blocks can be handled separately. + * 09/11/00 (seiwald) - Support for function calls; rules return LIST *. + * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() + * 01/24/01 (seiwald) - 'while' statement + * 03/23/01 (seiwald) - "[ on target rule ]" support + * 02/27/02 (seiwald) - un-break "expr : arg in list" syntax + * 03/02/02 (seiwald) - rules can be invoked via variable names + * 03/12/02 (seiwald) - set YYMAXDEPTH for big, right-recursive rules + * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx + * 06/21/02 (seiwald) - support for named parameters + * 10/22/02 (seiwald) - working return/break/continue statements */ %token ARG STRING @@ -47,6 +40,7 @@ #include "jam.h" #include "lists.h" +#include "variable.h" #include "parse.h" #include "scan.h" #include "compile.h" @@ -55,16 +49,16 @@ # define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ -# define F0 (LIST *(*)(PARSE *, LOL *))0 +# define F0 (LIST *(*)(PARSE *, LOL *, int *))0 # define P0 (PARSE *)0 # define S0 (char *)0 # define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) +# define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) # define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) # define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) # define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) # define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) -# define pj2eof( ) parse_make( compile_jumptoeof,P0,P0,P0,S0,S0,0 ) # define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) # define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) # define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) @@ -73,7 +67,7 @@ # define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) +# define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) # define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) @@ -118,16 +112,20 @@ rule : `{` block `}` { $$.parse = $2.parse; } | `include` list `;` { $$.parse = pincl( $2.parse ); } - | `jumptoeof` `;` - { $$.parse = pj2eof( ); } + | `jumptoeof` list `;` + { $$.parse = pbreak( $2.parse, JMP_EOF ); } | arg lol `;` { $$.parse = prule( $1.parse, $2.parse ); } | arg assign list `;` { $$.parse = pset( $1.parse, $3.parse, $2.number ); } | arg `on` list assign list `;` { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } + | `break` list `;` + { $$.parse = pbreak( $2.parse, JMP_BREAK ); } + | `continue` list `;` + { $$.parse = pbreak( $2.parse, JMP_CONTINUE ); } | `return` list `;` - { $$.parse = $2.parse; } + { $$.parse = pbreak( $2.parse, JMP_RETURN ); } | `for` ARG `in` list `{` block `}` { $$.parse = pfor( $2.string, $4.parse, $6.parse ); } | `switch` list `{` cases `}` @@ -138,8 +136,8 @@ rule : `{` block `}` { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } | `while` expr `{` block `}` { $$.parse = pwhile( $2.parse, $4.parse ); } - | `rule` ARG rule - { $$.parse = psetc( $2.string, $3.parse ); } + | `rule` ARG params `{` block `}` + { $$.parse = psetc( $2.string, $3.parse, $5.parse ); } | `on` arg rule { $$.parse = pon( $2.parse, $3.parse ); } | `actions` eflags ARG bindlist `{` @@ -155,13 +153,13 @@ rule : `{` block `}` */ assign : `=` - { $$.number = ASSIGN_SET; } + { $$.number = VAR_SET; } | `+=` - { $$.number = ASSIGN_APPEND; } + { $$.number = VAR_APPEND; } | `?=` - { $$.number = ASSIGN_DEFAULT; } + { $$.number = VAR_DEFAULT; } | `default` `=` - { $$.number = ASSIGN_DEFAULT; } + { $$.number = VAR_DEFAULT; } ; /* @@ -214,6 +212,19 @@ case : `case` ARG `:` block { $$.parse = psnode( $2.string, $4.parse ); } ; +/* + * params - optional parameter names to rule definition + * right-recursive rule so that params can be added in order. + */ + +params : /* empty */ + { $$.parse = P0; } + | ARG `:` params + { $$.parse = psnode( $1.string, $3.parse ); } + | ARG + { $$.parse = psnode( $1.string, P0 ); } + ; + /* * lol - list of lists * right-recursive rule so that lists can be added in order. @@ -283,6 +294,8 @@ eflag : `updated` { $$.number = RULE_PIECEMEAL; } | `existing` { $$.number = RULE_EXISTING; } + | `maxline` ARG + { $$.number = atoi( $2.string ) * RULE_MAXLINE; } ; diff --git a/src/tools/jam/jamgramtab.h b/src/tools/jam/jamgramtab.h index 916cb916ab..6eb95ea06d 100644 --- a/src/tools/jam/jamgramtab.h +++ b/src/tools/jam/jamgramtab.h @@ -17,7 +17,9 @@ { "]", _RBRACKET_t }, { "actions", ACTIONS_t }, { "bind", BIND_t }, + { "break", BREAK_t }, { "case", CASE_t }, + { "continue", CONTINUE_t }, { "default", DEFAULT_t }, { "else", ELSE_t }, { "existing", EXISTING_t }, @@ -28,6 +30,7 @@ { "include", INCLUDE_t }, { "jumptoeof", JUMPTOEOF_t }, { "local", LOCAL_t }, + { "maxline", MAXLINE_t }, { "on", ON_t }, { "piecemeal", PIECEMEAL_t }, { "quietly", QUIETLY_t }, diff --git a/src/tools/jam/jcache.c b/src/tools/jam/jcache.c index 48bd828952..de120a7720 100644 --- a/src/tools/jam/jcache.c +++ b/src/tools/jam/jcache.c @@ -338,7 +338,7 @@ find_jcache_entry(jamfile_cache* cache, char* filename) { jcache_entry _entry; jcache_entry* entry = &_entry; - entry->filename = filename; +entry->filename = filename; if (!hashcheck(cache->entries, (HASHDATA**)&entry)) entry = 0; return entry; @@ -554,7 +554,7 @@ jcache_name(void) popsettings( t->settings ); if (t->boundname) { - name = copystr(t->boundname); + name = (char*)copystr(t->boundname); } } } diff --git a/src/tools/jam/make.c b/src/tools/jam/make.c index f17480ecad..3552a40b5e 100644 --- a/src/tools/jam/make.c +++ b/src/tools/jam/make.c @@ -38,6 +38,16 @@ * 03/02/01 (seiwald) - reverse NOCARE change. * 03/14/02 (seiwald) - TEMPORARY targets no longer take on parents age * 03/16/02 (seiwald) - support for -g (reorder builds by source time) + * 07/17/02 (seiwald) - TEMPORARY sources for headers now get built + * 09/19/02 (seiwald) - new -d displays + * 09/23/02 (seiwald) - suppress "...using temp..." in default output + * 09/28/02 (seiwald) - make0() takes parent pointer; new -dc display + * 11/04/02 (seiwald) - const-ing for string literals + * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends + * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars + * 01/03/03 (seiwald) - T_FATE_NEWER once again gets set with missing parent + * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET + * 04/04/03 (seiwald) - fix INTERNAL node binding to avoid T_BIND_PARENTS */ # include "jam.h" @@ -66,12 +76,12 @@ typedef struct { int made; } COUNTS ; -static void make0( TARGET *t, time_t ptime, int depth, +static void make0( TARGET *t, TARGET *p, int depth, COUNTS *counts, int anyhow ); static TARGETS *make0sort( TARGETS *c ); -static char *target_fate[] = +static const char *target_fate[] = { "init", /* T_FATE_INIT */ "making", /* T_FATE_MAKING */ @@ -80,13 +90,14 @@ static char *target_fate[] = "temp", /* T_FATE_ISTMP */ "touched", /* T_FATE_TOUCHED */ "missing", /* T_FATE_MISSING */ + "needtmp", /* T_FATE_NEEDTMP */ "old", /* T_FATE_OUTDATED */ "update", /* T_FATE_UPDATE */ "nofind", /* T_FATE_CANTFIND */ "nomake" /* T_FATE_CANTMAKE */ } ; -static char *target_bind[] = +static const char *target_bind[] = { "unbound", "missing", @@ -102,9 +113,9 @@ static char *target_bind[] = int make( - int n_targets, - char **targets, - int anyhow ) + int n_targets, + const char **targets, + int anyhow ) { int i; COUNTS counts[1]; @@ -120,7 +131,7 @@ make( { TARGET *t = bindtarget( targets[i] ); - make0( t, (time_t)0, 0, counts, anyhow ); + make0( t, 0, 0, counts, anyhow ); } if( DEBUG_MAKE ) @@ -159,36 +170,25 @@ make( static void make0( TARGET *t, - time_t ptime, /* parent target's timestamp */ + TARGET *p, /* parent */ int depth, /* for display purposes */ COUNTS *counts, /* for reporting */ int anyhow ) /* forcibly touch all (real) targets */ { - TARGETS *c; - int fate, hfate; - time_t last, leaf, hlast, hleaf; - char *flag = ""; + TARGETS *c, *d, *incs; + TARGET *ptime = t; + time_t last, leaf, hlast; + int fate; + const char *flag = ""; + SETTINGS *s; + + /* + * Step 1: initialize + */ if( DEBUG_MAKEPROG ) printf( "make\t--\t%s%s\n", spaces( depth ), t->name ); - /* - * Step 1: don't remake if already trying or tried - */ - - switch( t->fate ) - { - case T_FATE_MAKING: - printf( "warning: %s depends on itself\n", t->name ); - return; - - default: - return; - - case T_FATE_INIT: - break; - } - t->fate = T_FATE_MAKING; /* @@ -198,7 +198,8 @@ make0( /* Step 2a: set "on target" variables. */ - pushsettings( t->settings ); + s = copysettings( t->settings ); + pushsettings( s ); /* Step 2b: find and timestamp the target file (if it's a file). */ @@ -208,10 +209,20 @@ make0( t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING; } + /* INTERNAL, NOTFILE header nodes have the time of their parents */ + + if( p && t->flags & T_FLAG_INTERNAL ) + ptime = p; + /* If temp file doesn't exist but parent does, use parent */ - if( t->binding == T_BIND_MISSING && t->flags & T_FLAG_TEMP && ptime ) + if( p && t->flags & T_FLAG_TEMP && + t->binding == T_BIND_MISSING && + p->binding != T_BIND_MISSING ) + { t->binding = T_BIND_PARENTS; + ptime = p; + } /* Step 2c: If its a file, search for headers. */ @@ -220,13 +231,14 @@ make0( /* Step 2d: reset "on target" variables */ - popsettings( t->settings ); + popsettings( s ); + freesettings( s ); /* * Pause for a little progress reporting */ - if( DEBUG_BIND ) + if( DEBUG_MAKEPROG ) { if( strcmp( t->name, t->boundname ) ) { @@ -251,26 +263,61 @@ make0( } /* - * Step 3: recursively make0() dependents + * Step 3: recursively make0() dependents & headers */ + /* Step 3a: recursively make0() dependents */ + + for( c = t->depends; c; c = c->next ) + { + int internal = t->flags & T_FLAG_INTERNAL; + + if( DEBUG_DEPENDS ) + printf( "%s \"%s\" : \"%s\" ;\n", + internal ? "Includes" : "Depends", + t->name, c->target->name ); + + /* Warn about circular deps, except for includes, */ + /* which include each other alot. */ + + if( c->target->fate == T_FATE_INIT ) + make0( c->target, ptime, depth + 1, counts, anyhow ); + else if( c->target->fate == T_FATE_MAKING && !internal ) + printf( "warning: %s depends on itself\n", c->target->name ); + } + + /* Step 3b: recursively make0() internal includes node */ + + if( t->includes ) + make0( t->includes, p, depth + 1, counts, anyhow ); + + /* Step 3c: add dependents' includes to our direct dependencies */ + + incs = 0; + + for( c = t->depends; c; c = c->next ) + if( c->target->includes ) + incs = targetentry( incs, c->target->includes ); + + t->depends = targetchain( t->depends, incs ); + + /* + * Step 4: compute time & fate + */ + + /* Step 4a: pick up dependents' time and fate */ + last = 0; leaf = 0; fate = T_FATE_STABLE; - for( c = t->deps[ T_DEPS_DEPENDS ]; c; c = c->next ) + for( c = t->depends; c; c = c->next ) { - /* Pass our time or our parent's time down. */ - - int time = t->binding == T_BIND_PARENTS ? ptime : t->time; - - make0( c->target, time, depth + 1, counts, anyhow ); - leaf = max( leaf, c->target->leaf ); - leaf = max( leaf, c->target->hleaf ); - /* If LEAVES has been applied, we only heed the timestamps of */ /* the leaf source nodes. */ + leaf = max( leaf, c->target->leaf ); + if( t->flags & T_FLAG_LEAVES ) { last = leaf; @@ -278,27 +325,34 @@ make0( } last = max( last, c->target->time ); - last = max( last, c->target->htime ); fate = max( fate, c->target->fate ); - fate = max( fate, c->target->hfate ); } - /* If a NOUPDATE file exists, make dependents eternally old. */ + /* Step 4b: pick up included headers time */ + + /* + * If a header is newer than a temp source that includes it, + * the temp source will need building. + */ + + hlast = t->includes ? t->includes->time : 0; + + /* Step 4c: handle NOUPDATE oddity */ + + /* + * If a NOUPDATE file exists, make dependents eternally old. + * Don't inherit our fate from our dependents. Decide fate + * based only upon other flags and our binding (done later). + */ if( t->flags & T_FLAG_NOUPDATE ) { last = 0; t->time = 0; - - /* - * Don't inherit our fate from our dependents. Decide fate - * based only upon other flags and our binding (done later). - */ - fate = T_FATE_STABLE; } - /* Step 3b: determine fate: rebuild target or what? */ + /* Step 4d: determine fate: rebuild target or what? */ /* In English: @@ -307,10 +361,15 @@ make0( If target missing, make it. If children newer, make target. If temp's children newer than parent, make temp. + If temp's headers newer than parent, make temp. If deliberately touched, make it. If up-to-date temp file present, use it. - If target newer than parent, mark target newer. - Don't propagate child's "newer" status. + If target newer than non-notfile parent, mark target newer. + Otherwise, stable! + + Note this block runs from least to most stable: + as we make it further down the list, the target's + fate is getting stabler. */ if( fate >= T_FATE_BROKEN ) @@ -329,9 +388,13 @@ make0( { fate = T_FATE_OUTDATED; } - else if( t->binding == T_BIND_PARENTS && last > ptime ) + else if( t->binding == T_BIND_PARENTS && last > p->time ) { - fate = T_FATE_OUTDATED; + fate = T_FATE_NEEDTMP; + } + else if( t->binding == T_BIND_PARENTS && hlast > p->time ) + { + fate = T_FATE_NEEDTMP; } else if( t->flags & T_FLAG_TOUCHED ) { @@ -345,24 +408,23 @@ make0( { fate = T_FATE_ISTMP; } - else if( t->binding == T_BIND_EXISTS && t->time > ptime ) + else if( t->binding == T_BIND_EXISTS && p && + p->binding != T_BIND_UNBOUND && t->time > p->time ) { fate = T_FATE_NEWER; } - else if( fate == T_FATE_NEWER ) + else { fate = T_FATE_STABLE; } - /* Step 3c: handle missing files */ + /* Step 4e: handle missing files */ /* If it's missing and there are no actions to create it, boom. */ /* If we can't make a target we don't care about, 'sokay */ /* We could insist that there are updating actions for all missing */ /* files, but if they have dependents we just pretend it's NOTFILE. */ - if( fate == T_FATE_MISSING && - !t->actions && - !t->deps[ T_DEPS_DEPENDS ] ) + if( fate == T_FATE_MISSING && !t->actions && !t->depends ) { if( t->flags & T_FLAG_NOCARE ) { @@ -376,49 +438,29 @@ make0( } } - /* Step 3d: propagate dependents' time & fate. */ + /* Step 4f: propagate dependents' time & fate. */ /* Set leaf time to be our time only if this is a leaf. */ t->time = max( t->time, last ); t->leaf = leaf ? leaf : t->time ; t->fate = fate; - /* Step 3e: sort dependents by their update time. */ + /* + * Step 5: sort dependents by their update time. + */ if( globs.newestfirst ) - t->deps[ T_DEPS_DEPENDS ] = make0sort( t->deps[ T_DEPS_DEPENDS ] ); - - /* - * Step 4: Recursively make0() headers. - */ - - /* Step 4a: recursively make0() headers */ - - hlast = 0; - hleaf = 0; - hfate = T_FATE_STABLE; - - for( c = t->deps[ T_DEPS_INCLUDES ]; c; c = c->next ) - { - make0( c->target, ptime, depth + 1, counts, anyhow ); - hlast = max( hlast, c->target->time ); - hlast = max( hlast, c->target->htime ); - hleaf = max( hleaf, c->target->leaf ); - hleaf = max( hleaf, c->target->hleaf ); - hfate = max( hfate, c->target->fate ); - hfate = max( hfate, c->target->hfate ); - } - - /* Step 4b: propagate dependents' time & fate. */ - - t->htime = hlast; - t->hleaf = hleaf ? hleaf : t->htime; - t->hfate = hfate; + t->depends = make0sort( t->depends ); /* - * Step 5: a little harmless tabulating for tracing purposes + * Step 6: a little harmless tabulating for tracing purposes */ + /* Don't count or report interal includes nodes. */ + + if( t->flags & T_FLAG_INTERNAL ) + return; + if( !( ++counts->targets % 1000 ) && DEBUG_MAKE ) printf( "...patience...\n" ); @@ -433,13 +475,18 @@ make0( if( !( t->flags & T_FLAG_NOTFILE ) && fate >= T_FATE_SPOIL ) flag = "+"; - else if( t->binding == T_BIND_EXISTS && ptime && t->time > ptime ) + else if( t->binding == T_BIND_EXISTS && p && t->time > p->time ) flag = "*"; if( DEBUG_MAKEPROG ) printf( "made%s\t%s\t%s%s\n", flag, target_fate[ t->fate ], spaces( depth ), t->name ); + + if( DEBUG_CAUSES && + t->fate >= T_FATE_NEWER && + t->fate <= T_FATE_MISSING ) + printf( "%s %s\n", target_fate[ t->fate ], t->name ); } /* diff --git a/src/tools/jam/parse.c b/src/tools/jam/parse.c index 50e7f5cfdb..45292e3414 100644 --- a/src/tools/jam/parse.c +++ b/src/tools/jam/parse.c @@ -4,12 +4,6 @@ * 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 "newstr.h" - /* * parse.c - make and destroy parse trees as driven by the parser * @@ -17,14 +11,21 @@ * as per Matt Armstrong. * 09/11/00 (seiwald) - structure reworked to reflect that (*func)() * returns a LIST *. + * 10/22/02 (seiwald) - working return/break/continue statements + * 11/04/02 (seiwald) - const-ing for string literals */ +# include "jam.h" +# include "lists.h" +# include "parse.h" +# include "scan.h" +# include "newstr.h" +# include "compile.h" + static PARSE *yypsave; -static int jumptoeof = 0; - void -parse_file( char *f ) +parse_file( const char *f ) { /* Suspend scan of current file */ /* and push this new file in the stream */ @@ -35,10 +36,11 @@ parse_file( char *f ) /* Execute it outside of the parser so that recursive */ /* calls to yyrun() work (no recursive yyparse's). */ - while (!parse_shall_skip()) + for(;;) { LOL l; PARSE *p; + int jmp = 0; /* JMP_NONE */ /* $(<) and $(>) empty in outer scope. */ @@ -55,11 +57,13 @@ parse_file( char *f ) /* Run the parse tree. */ - (*(p->func))( p, &l ); + list_free( (*(p->func))( p, &l, &jmp ) ); parse_free( p ); + + if ( jmp == JMP_EOF ) + break; } - jumptoeof = 0; } void @@ -68,27 +72,15 @@ parse_save( PARSE *p ) yypsave = p; } -void -parse_jumptoeof() -{ - jumptoeof = 1; -} - -int -parse_shall_skip() -{ - return jumptoeof; -} - PARSE * parse_make( - LIST *(*func)( PARSE *p, LOL *args ), - PARSE *left, - PARSE *right, - PARSE *third, - char *string, - char *string1, - int num ) + LIST *(*func)( PARSE *p, LOL *args, int *jmp ), + PARSE *left, + PARSE *right, + PARSE *third, + const char *string, + const char *string1, + int num ) { PARSE *p = (PARSE *)malloc( sizeof( PARSE ) ); diff --git a/src/tools/jam/parse.h b/src/tools/jam/parse.h index 8b8d07a051..137fa629f8 100644 --- a/src/tools/jam/parse.h +++ b/src/tools/jam/parse.h @@ -6,6 +6,9 @@ /* * parse.h - make and destroy parse trees as driven by the parser + * + * 10/22/02 (seiwald) - working return/break/continue statements + * 11/04/02 (seiwald) - const-ing for string literals */ /* @@ -15,29 +18,27 @@ typedef struct _PARSE PARSE; struct _PARSE { - LIST *(*func)( PARSE *p, LOL *args ); - PARSE *left; - PARSE *right; - PARSE *third; - char *string; - char *string1; - int num; - int refs; + LIST *(*func)( PARSE *p, LOL *args, int *jmp ); + PARSE *left; + PARSE *right; + PARSE *third; + const char *string; + const char *string1; + int num; + int refs; } ; -void parse_file( char *f ); +void parse_file( const char *f ); void parse_save( PARSE *p ); -void parse_jumptoeof(); -int parse_shall_skip(); PARSE * parse_make( - LIST *(*func)( PARSE *p, LOL *args ), - PARSE *left, - PARSE *right, - PARSE *third, - char *string, - char *string1, - int num ); + LIST *(*func)( PARSE *p, LOL *args, int *jmp ), + PARSE *left, + PARSE *right, + PARSE *third, + const char *string, + const char *string1, + int num ); void parse_refer( PARSE *p ); void parse_free( PARSE *p ); diff --git a/src/tools/jam/scan.c b/src/tools/jam/scan.c index 50b73fe2ef..d544e67233 100644 --- a/src/tools/jam/scan.c +++ b/src/tools/jam/scan.c @@ -4,15 +4,6 @@ * 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 "jcache.h" -# include "jamgram.h" -# include "jambase.h" -# include "newstr.h" - /* * scan.c - the jam yacc scanner * @@ -24,10 +15,21 @@ * 02/11/95 (seiwald) - honor only punctuation keywords if SCAN_PUNCT. * 07/27/95 (seiwald) - Include jamgram.h after scan.h, so that YYSTYPE is * defined before Linux's yacc tries to redefine it. + * 01/10/01 (seiwald) - \ can now escape any whitespace char + * 11/04/02 (seiwald) - const-ing for string literals */ +# include "jam.h" +# include "lists.h" +# include "parse.h" +# include "scan.h" +# include "jamgram.h" +# include "jambase.h" +# include "jcache.h" +# include "newstr.h" + struct keyword { - char *word; + const char *word; int type; } keywords[] = { # include "jamgramtab.h" @@ -35,13 +37,13 @@ struct keyword { } ; 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 *next; /* next serial include file */ + const char *string; /* pointer into current line */ + char **strings; /* for yyfparse() -- text to parse */ + FILE *file; /* for yyfparse() -- file being read */ + const char *fname; /* for yyfparse() -- file name */ + int line; /* line counter for error messages */ + char buf[ 512 ]; /* for yyfparse() -- line buffer */ } ; static struct include *incp = 0; /* current file; head of chain */ @@ -63,7 +65,7 @@ yymode( int n ) } void -yyerror( char *s ) +yyerror( const char *s ) { if( incp ) printf( "%s: line %d: ", incp->fname, incp->line ); @@ -80,7 +82,7 @@ yyanyerrors() } void -yyfparse( char *s ) +yyfparse( const char *s ) { struct include *i = (struct include *)malloc( sizeof( *i ) ); @@ -144,7 +146,7 @@ yyline() { if ( strcmp( i->fname, "-" ) ) { - i->strings = jcache(i->fname); + i->strings = jcache((char*)i->fname); if (!i->strings || !*i->strings) goto next; i->line++;