mirror of
https://github.com/boostorg/build.git
synced 2026-02-18 14:02:11 +00:00
** This comment represents the aggregate changes merged from the **
** bbv2python branch. **
gcc.jam: build and use import libraries on Cygwin and Windows, but
accept DLL-only linking with prebuilt DLLs.
builtin.jam: fix default-host-os so that <target-os> actually becomes
a functional feature. Improve English in comments
property-set.jam: add str method so we can print them in generator
debugging output.
generators.jam: improved debugging output
build-system.jam: add missing semicolon
python.jam:
* fix cross-NT/CYGWIN build support
* add condition to the build requirements of the python targets
os.jam:
* add the ability to get constants for a particular OS
builtin.jam:
* remove "optional" attribute from host-os
* fix confusing indents
python.jam
----------
* Removed comments about known problems because they make no sense.
* Unified MacOS initialization with NT and *nix
* Updated comment describing init behavior
* Support for passing Python command as first argument
* Removed unused get-python-interpreter and get-python-version rules,
since they can't work with that interface. Working versions of
these will be reinstated for Doug Gregor in the near future.
* When invoking Python to collect configuration info, collect it all at at once.
* When a Cygwin symlink is found by an NT build of bjam, give hints
about where to find the file it points at.
* Lots of refactoring
* Make the logic work plausibly even when no Python executable can be found
darwin.jam
----------
* Simplified logic for setting up FRAMEWORK_PATH
* Corrected logic for setting up -framework option
feature.jam
-----------
* Make feature.defaults, feature.attributes, feature.values, and
feature.get-values resilient to feature names being passed without
grist.
gcc.jam, python.jam, builtin.jam
--------------------------------
* Include some progress volodya has made toward support for <suppress-import-lib>
[SVN r37186]
This commit is contained in:
@@ -83,6 +83,7 @@ local rule load-config ( basename : path + )
|
||||
{
|
||||
if $(debug-config)
|
||||
{
|
||||
ECHO notice: searching \"$(path)\" for \"$(basename).jam\" ;
|
||||
local where = [ GLOB $(path) : $(basename).jam ] ;
|
||||
if $(where)
|
||||
{
|
||||
@@ -250,7 +251,7 @@ if ! [ feature.values <toolset> ]
|
||||
ECHO "warning: Configuring default toolset" \"$(default-toolset)\". ;
|
||||
ECHO "warning: If the default is wrong, you may not be able to build C++ programs." ;
|
||||
ECHO "warning: Use the \"--toolset=xxxxx\" option to override our guess." ;
|
||||
ECHO "warning: For more configuration options, please consult"
|
||||
ECHO "warning: For more configuration options, please consult" ;
|
||||
ECHO "warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" ;
|
||||
|
||||
|
||||
|
||||
@@ -165,13 +165,14 @@ rule defaults ( features * )
|
||||
local result ;
|
||||
for local f in $(features)
|
||||
{
|
||||
local a = $($(f).attributes) ;
|
||||
local gf = $(:E=:G=$(f)) ;
|
||||
local a = $($(gf).attributes) ;
|
||||
if ( free in $(a) ) || ( optional in $(a) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
result += $(f)$($(f).default) ;
|
||||
result += $(gf)$($(gf).default) ;
|
||||
}
|
||||
}
|
||||
return $(result) ;
|
||||
@@ -189,13 +190,13 @@ rule valid ( names + )
|
||||
# return the attibutes of the given feature
|
||||
rule attributes ( feature )
|
||||
{
|
||||
return $($(feature).attributes) ;
|
||||
return $($(:E=:G=$(feature)).attributes) ;
|
||||
}
|
||||
|
||||
# return the values of the given feature
|
||||
rule values ( feature )
|
||||
{
|
||||
return $($(feature).values) ;
|
||||
return $($(:E=:G=$(feature)).values) ;
|
||||
}
|
||||
|
||||
# returns true iff 'value-string' is a value-string of an implicit feature
|
||||
@@ -640,6 +641,8 @@ local rule expand-composite ( property )
|
||||
rule get-values ( feature : properties * )
|
||||
{
|
||||
local result ;
|
||||
|
||||
feature = $(:E=:G=$(feature)) ; # add <> if necessary.
|
||||
for local p in $(properties)
|
||||
{
|
||||
if $(p:G) = $(feature)
|
||||
@@ -1050,6 +1053,8 @@ local rule __test__ ( )
|
||||
compose <variant>debug : <define>_DEBUG <optimization>off ;
|
||||
compose <variant>release : <define>NDEBUG <optimization>on ;
|
||||
|
||||
assert.result dynamic static : values <runtime-link> ;
|
||||
assert.result dynamic static : values runtime-link ;
|
||||
|
||||
try ;
|
||||
{
|
||||
@@ -1128,12 +1133,20 @@ local rule __test__ ( )
|
||||
: defaults <runtime-link> <define> <optimization>
|
||||
;
|
||||
|
||||
# make sure defaults is resilient to missing grist.
|
||||
assert.result <runtime-link>dynamic <optimization>on
|
||||
: defaults runtime-link define optimization
|
||||
;
|
||||
|
||||
feature dummy : dummy1 dummy2 ;
|
||||
subfeature dummy : subdummy : x y z : optional ;
|
||||
|
||||
feature fu : fu1 fu2 : optional ;
|
||||
subfeature fu : subfu : x y z : optional ;
|
||||
subfeature fu : subfu2 : q r s ;
|
||||
|
||||
assert.result optional : attributes <fu> ;
|
||||
assert.result optional : attributes fu ;
|
||||
|
||||
assert.result <runtime-link>static <define>foobar <optimization>on <toolset>gcc:<define>FOO
|
||||
<toolset>gcc <variant>debug <stdlib>native <dummy>dummy1 <toolset-gcc:version>2.95.2
|
||||
|
||||
@@ -842,6 +842,9 @@ local rule try-one-generator-really ( project name ? : generator :
|
||||
|
||||
local usage-requirements ;
|
||||
local success ;
|
||||
|
||||
generators.dout [ indent ] returned $(targets) ;
|
||||
|
||||
if $(targets)
|
||||
{
|
||||
success = true ;
|
||||
@@ -859,6 +862,12 @@ local rule try-one-generator-really ( project name ? : generator :
|
||||
|
||||
generators.dout [ indent ] " generator" [ $(generator).id ] " spawned " ;
|
||||
generators.dout [ indent ] " " $(targets) ;
|
||||
if $(usage-requirements)
|
||||
{
|
||||
generators.dout [ indent ] " with usage requirements:" $(x) ;
|
||||
}
|
||||
|
||||
|
||||
if $(success)
|
||||
{
|
||||
return $(usage-requirements) $(targets) ;
|
||||
|
||||
@@ -101,6 +101,11 @@ class property-set
|
||||
return $(self.raw) ;
|
||||
}
|
||||
|
||||
rule str ( )
|
||||
{
|
||||
return "[" $(self.raw) "]" ;
|
||||
}
|
||||
|
||||
# Returns properties that are neither incidental nor free
|
||||
rule base ( )
|
||||
{
|
||||
|
||||
@@ -33,14 +33,17 @@ import generate ;
|
||||
local os = [ modules.peek : OS ] ;
|
||||
feature os : $(os) : propagated link-incompatible ;
|
||||
|
||||
.os-names = amiga aix bsd cygwin darwin dos emx freebsd hpux
|
||||
linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos
|
||||
svr4 sysv ultrix unix unixware vms windows ;
|
||||
|
||||
# Translates from bjam current OS to the os tags used
|
||||
# in host-os and target-os. I.e. it returns the
|
||||
# running host-os.
|
||||
local rule default-host-os ( )
|
||||
{
|
||||
local host-os ;
|
||||
local os-list = [ feature.values host-os ] ;
|
||||
if [ os.name ] in $(os-list:U)
|
||||
if [ os.name ] in $(.os-names:U)
|
||||
{
|
||||
host-os = [ os.name ] ;
|
||||
}
|
||||
@@ -70,18 +73,13 @@ local rule default-host-os ( )
|
||||
# to list all the values to prevent unkown value errors.
|
||||
# Both set the default value to the current OS to account for
|
||||
# the default use case of building on the target OS.
|
||||
feature host-os
|
||||
: amiga aix bsd cygwin darwin dos emx freebsd hpux
|
||||
linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos
|
||||
svr4 sysv ultrix unix unixware vms windows
|
||||
: optional ;
|
||||
feature.set-default host-os : [ default-host-os ] ;
|
||||
feature host-os : $(.os-names) ;
|
||||
feature.set-default host-os : [ default-host-os ] ;
|
||||
|
||||
feature target-os
|
||||
: amiga aix bsd cygwin darwin dos emx freebsd hpux
|
||||
linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos
|
||||
svr4 sysv ultrix unix unixware vms windows
|
||||
: $(.os-names)
|
||||
: propagated link-incompatible ;
|
||||
feature.set-default target-os : [ default-host-os ] ;
|
||||
feature.set-default target-os : [ default-host-os ] ;
|
||||
|
||||
|
||||
feature toolset : : implicit propagated symmetric ;
|
||||
@@ -169,15 +167,17 @@ feature dll-path : : free path ;
|
||||
feature hardcode-dll-paths : true false : incidental ;
|
||||
|
||||
|
||||
# This is internal feature which holds the paths of all dependency
|
||||
# An internal feature that holds the paths of all dependency
|
||||
# dynamic libraries. On Windows, it's needed so that we can all
|
||||
# those paths to PATH, when running applications.
|
||||
# those paths to PATH when running applications.
|
||||
# On Linux, it's needed to add proper -rpath-link command line options.
|
||||
feature xdll-path : : free path ;
|
||||
|
||||
#provides means to specify def-file for windows dlls.
|
||||
feature def-file : : free dependency ;
|
||||
|
||||
feature.feature suppress-import-lib : false true : incidental ;
|
||||
|
||||
# This is internal feature which is used to store the name of
|
||||
# bjam action to call when building a target.
|
||||
feature.feature action : : free ;
|
||||
@@ -726,7 +726,7 @@ class linking-generator : generator
|
||||
}
|
||||
|
||||
# Hardcode dll paths only when linking executables.
|
||||
# Pros: don't need to relinking libraries when installing.
|
||||
# Pros: don't need to relink libraries when installing.
|
||||
# Cons: "standalone" libraries (plugins, python extensions)
|
||||
# can't hardcode paths to dependent libraries.
|
||||
if [ $(property-set).get <hardcode-dll-paths> ] = true
|
||||
|
||||
@@ -338,6 +338,10 @@ rule check-tool-aux ( command )
|
||||
if $(command:D)
|
||||
{
|
||||
if [ path.exists $(command) ]
|
||||
# Both NT and Cygwin will run .exe files by their unqualified names
|
||||
|| [ os.on-windows ] && [ path.exists $(command).exe ]
|
||||
# Only NT will run .bat files by their unqualified names
|
||||
|| [ os.name ] = NT && [ path.exists $(command).bat ]
|
||||
{
|
||||
return $(command) ;
|
||||
}
|
||||
|
||||
@@ -65,14 +65,7 @@ local rule prepare-framework-path ( target + )
|
||||
{
|
||||
local framework-path = [ on $(target) return $(FRAMEWORK:D) ] ;
|
||||
|
||||
if $(framework-path)
|
||||
{
|
||||
FRAMEWORK_PATH on $(target) += -F$(framework-path) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
FRAMEWORK_PATH on $(target) = ;
|
||||
}
|
||||
FRAMEWORK_PATH on $(target) += -F$(framework-path) ;
|
||||
}
|
||||
|
||||
rule link
|
||||
@@ -82,7 +75,7 @@ rule link
|
||||
|
||||
actions link bind LIBRARIES
|
||||
{
|
||||
$(CONFIG_COMMAND) -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=) $(OPTIONS) $(USER_OPTIONS)
|
||||
$(CONFIG_COMMAND) -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS)
|
||||
$(NEED_STRIP)strip $(NEED_STRIP)"$(<)"
|
||||
}
|
||||
|
||||
@@ -93,7 +86,7 @@ rule link.dll
|
||||
|
||||
actions link.dll bind LIBRARIES
|
||||
{
|
||||
$(CONFIG_COMMAND) -dynamiclib -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=) $(OPTIONS) $(USER_OPTIONS)
|
||||
$(CONFIG_COMMAND) -dynamiclib -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS)
|
||||
}
|
||||
|
||||
actions piecemeal archive
|
||||
|
||||
@@ -44,6 +44,9 @@ generators.override gcc.searched-lib-generator : searched-lib-generator ;
|
||||
type.set-generated-target-suffix OBJ : <toolset>gcc : o ;
|
||||
type.set-generated-target-suffix STATIC_LIB : <toolset>gcc : a ;
|
||||
|
||||
type.set-generated-target-suffix IMPORT_LIB : <toolset>gcc <target-os>cygwin : dll.a ;
|
||||
type.set-generated-target-suffix IMPORT_LIB : <toolset>gcc <target-os>windows : a ;
|
||||
|
||||
import rc ;
|
||||
|
||||
# Initializes the gcc toolset for the given version.
|
||||
@@ -75,7 +78,7 @@ rule init ( version ? : command * : options * )
|
||||
# Autodetect the version and flavor if not given.
|
||||
if $(command)
|
||||
{
|
||||
# The 'command' variable can have multiple-element. When calling
|
||||
# The 'command' variable can have multiple elements. When calling
|
||||
# the SHELL builtin we need a single string.
|
||||
local command-string = $(command:J=" ") ;
|
||||
local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ ]+)[^(]*[(]?([^)]*)"
|
||||
@@ -427,8 +430,26 @@ class gcc-linking-generator : unix-linking-generator
|
||||
}
|
||||
else
|
||||
{
|
||||
return [ unix-linking-generator.run $(project) $(name)
|
||||
local generated-targets = [ unix-linking-generator.run $(project) $(name)
|
||||
: $(property-set) : $(sources) ] ;
|
||||
|
||||
# If more than one target was generated, throw out the
|
||||
# last one, which on windows just leaves the import
|
||||
# library. Most generators on windows simply don't accept
|
||||
# shared libraries as input, but being able to link
|
||||
# directly to a shared library without an import library
|
||||
# is an important capability of GCC. Therefore, we remove
|
||||
# the target after the action sees it so that dependent
|
||||
# targets don't try to link to both the import library and
|
||||
# the DLL.
|
||||
if [ $(property-set).get <suppress-import-lib> ] = true
|
||||
{
|
||||
return $(generated-targets[0]) $(generated-targets[-1]) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $(generated-targets[1-2]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,9 +457,17 @@ class gcc-linking-generator : unix-linking-generator
|
||||
generators.register [ new gcc-linking-generator gcc.link : LIB OBJ : EXE
|
||||
: <toolset>gcc ] ;
|
||||
|
||||
generators.register [ new gcc-linking-generator gcc.link.dll : LIB OBJ : SHARED_LIB
|
||||
: <toolset>gcc ] ;
|
||||
.IMPLIB-COMMAND = ;
|
||||
.IMPLIB-TYPE = ;
|
||||
if [ os.on-windows ]
|
||||
{
|
||||
.IMPLIB-COMMAND = "-Wl,--out-implib," ;
|
||||
.IMPLIB-TYPE = IMPORT_LIB ;
|
||||
}
|
||||
|
||||
generators.register
|
||||
[ new gcc-linking-generator gcc.link.dll : LIB OBJ : $(.IMPLIB-TYPE) SHARED_LIB
|
||||
: <toolset>gcc ] ;
|
||||
|
||||
# Declare flags for linking
|
||||
# First, the common flags
|
||||
@@ -601,7 +630,7 @@ rule link.dll ( targets * : sources * : properties * )
|
||||
# Differ from 'link' above only by -shared.
|
||||
actions link.dll bind LIBRARIES
|
||||
{
|
||||
"$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" -o "$(<)" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)
|
||||
"$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)
|
||||
}
|
||||
|
||||
# Set up threading support. It's somewhat contrived, so perform it at the end,
|
||||
|
||||
@@ -301,7 +301,7 @@ local rule configure-really (
|
||||
setup-option = x86 x86_amd64 x86_iPF ;
|
||||
|
||||
# Use a native x64 compiler if possible
|
||||
if [ os.environ PROCESSOR_ARCHITECTURE ] = AMD64
|
||||
if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_IDENTIFIER ] ]
|
||||
{
|
||||
setup-option = x86 amd64 x86_IPF ;
|
||||
}
|
||||
@@ -968,14 +968,19 @@ if [ os.name ] in NT CYGWIN
|
||||
{
|
||||
if $(.version-$(i)-reg)
|
||||
{
|
||||
local vc-path = [ W32_GETREG
|
||||
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"$(.version-$(i)-reg)
|
||||
local vc-path ;
|
||||
for local x in "" "Wow6432Node\\"
|
||||
{
|
||||
vc-path += [ W32_GETREG
|
||||
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"$(x)$(.version-$(i)-reg)
|
||||
: "ProductDir" ] ;
|
||||
}
|
||||
|
||||
|
||||
if $(vc-path)
|
||||
{
|
||||
vc-path = [ path.native [ path.join [ path.make-NT $(vc-path) ] "bin" ] ] ;
|
||||
register-configuration $(i) : $(vc-path) ;
|
||||
vc-path = [ path.native [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ] ;
|
||||
register-configuration $(i) : $(vc-path[1]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1140
v2/tools/python.jam
1140
v2/tools/python.jam
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@
|
||||
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import modules ;
|
||||
import string ;
|
||||
|
||||
# Return the value(s) of the given environment variable(s) at the time
|
||||
# bjam was invoked.
|
||||
@@ -17,50 +18,77 @@ rule environ ( variable-names + )
|
||||
.platform = [ modules.peek : OSPLAT ] ;
|
||||
.version = [ modules.peek : OSVER ] ;
|
||||
|
||||
local rule constant ( c )
|
||||
local rule constant ( c : os ? )
|
||||
{
|
||||
os ?= $(.name) ;
|
||||
# First look for platform-specific name, then general value
|
||||
local variables = .$(c)-$(.name) .$(c) ;
|
||||
local variables = .$(c)-$(os) .$(c) ;
|
||||
local result = $($(variables)) ;
|
||||
return $(result[1]) ;
|
||||
}
|
||||
|
||||
rule get-constant ( )
|
||||
rule get-constant ( os ? )
|
||||
{
|
||||
# Find the name of the constant being accessed, which is
|
||||
# equal to the name used to invoke us.
|
||||
local bt = [ BACKTRACE 1 ] ;
|
||||
local rulename = [ MATCH ([^.]*)$ : $(bt[4]) ] ;
|
||||
return [ constant $(rulename) ] ;
|
||||
return [ constant $(rulename) : $(os) ] ;
|
||||
}
|
||||
|
||||
|
||||
# export all the common constants
|
||||
.constants = name platform version shared-library-path-variable path-separator ;
|
||||
.constants = name platform version shared-library-path-variable path-separator executable-path-variable executable-suffix ;
|
||||
for local constant in $(.constants)
|
||||
{
|
||||
IMPORT $(__name__) : get-constant : $(__name__) : $(constant) ;
|
||||
}
|
||||
EXPORT $(__name__) : $(.constants) ;
|
||||
|
||||
.shared-library-path-variable-NT = PATH ;
|
||||
.executable-path-variable-NT = PATH ;
|
||||
# On Windows the case and capitalization of PATH is not always
|
||||
# predictable, so let's find out what variable name was really set.
|
||||
if $(.name) = NT
|
||||
{
|
||||
for local n in [ VARNAMES .ENVIRON ]
|
||||
{
|
||||
if $(n:L) = path
|
||||
{
|
||||
.executable-path-variable-NT = $(n) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Specific constants for various platforms. There's no need to define
|
||||
# any constant whose value would be the same as the default, below.
|
||||
.shared-library-path-variable-NT = $(.executable-path-variable-NT) ;
|
||||
.path-separator-NT = ";" ;
|
||||
.expand-variable-prefix-NT = % ;
|
||||
.expand-variable-suffix-NT = % ;
|
||||
.executable-suffix-NT = .exe ;
|
||||
|
||||
.shared-library-path-variable-CYGWIN = PATH ;
|
||||
.path-separator-CYGWIN = ":" ;
|
||||
.expand-variable-prefix-CYGWIN = $ ;
|
||||
.expand-variable-suffix-CYGWIN = "" ;
|
||||
|
||||
.shared-library-path-variable-MACOSX = DYLD_LIBRARY_PATH ;
|
||||
|
||||
|
||||
# Default constants
|
||||
.shared-library-path-variable = LD_LIBRARY_PATH ;
|
||||
.path-separator = ":" ;
|
||||
.expand-variable-prefix = $ ;
|
||||
.expand-variable-suffix = "" ;
|
||||
.executable-path-variable = PATH ;
|
||||
.executable-suffix = "" ;
|
||||
|
||||
# Return a list of the directories in the PATH. Yes, that information
|
||||
# is (sort of) available in the global module, but jam code can change
|
||||
# those values, and it isn't always clear what case/capitalization to
|
||||
# use when looking. This rule is a more reliable way to get there.
|
||||
rule executable-path ( )
|
||||
{
|
||||
return [ string.words [ environ [ constant executable-path-variable ] ]
|
||||
: [ constant path-separator ] ] ;
|
||||
}
|
||||
|
||||
if $(.name) = NT
|
||||
{
|
||||
local home = [ environ HOMEDRIVE HOMEPATH ] ;
|
||||
|
||||
@@ -46,6 +46,16 @@ rule transform ( function + : sequence * )
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
rule reverse ( s * )
|
||||
{
|
||||
local r ;
|
||||
for local x in $(s)
|
||||
{
|
||||
r = $(x) $(r) ;
|
||||
}
|
||||
return $(r) ;
|
||||
}
|
||||
|
||||
|
||||
rule less ( a b )
|
||||
{
|
||||
@@ -304,5 +314,7 @@ local rule __test__ ( )
|
||||
|
||||
assert.result e-3 h-3
|
||||
: sequence.select-highest-ranked e-1 e-3 h-3 m-2 : 1 3 3 2 ;
|
||||
|
||||
assert.result 7 6 5 4 3 2 1 : sequence.reverse 1 2 3 4 5 6 7 ;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user