forked from boostorg/predef
Fix incorrect check expression eval. It turns out the expression eval
was just not implemented and only really worked for the require checks as those are ok with duplicate properties. Now full and/or expression parsing an evaluation is implemented.
This commit is contained in:
146
check/predef.jam
146
check/predef.jam
@ -13,6 +13,7 @@ import string ;
|
||||
import toolset ;
|
||||
import modules ;
|
||||
import path ;
|
||||
import "class" : new ;
|
||||
|
||||
# Create a project for our targets.
|
||||
project.extension predef check ;
|
||||
@ -54,35 +55,42 @@ rule check ( expressions + : language ? : true-properties * : false-properties *
|
||||
|
||||
local project_target = [ project.target $(__name__) ] ;
|
||||
project.push-current $(project_target) ;
|
||||
local terms ;
|
||||
local result ;
|
||||
for expression in $(expressions)
|
||||
{
|
||||
# The check program to use.
|
||||
local exe_target = [ $(_check_exe_($(language))).name ] ;
|
||||
exe_target = /check/predef//$(exe_target) ;
|
||||
|
||||
# Create the check run if we don't have one yet.
|
||||
local key = [ MD5 $(language)::$(expression) ] ;
|
||||
if ! ( $(key) in $(_checks_) )
|
||||
if $(expression:L) in "and" "or"
|
||||
{
|
||||
_checks_ += $(key) ;
|
||||
make
|
||||
$(key).txt :
|
||||
$(exe_target) :
|
||||
@$(__name__).predef_check_action :
|
||||
<predef-expression>$(expression) ;
|
||||
explicit
|
||||
$(key).txt ;
|
||||
terms += $(expression:L) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
# The check program to use.
|
||||
local exe_target = [ $(_check_exe_($(language))).name ] ;
|
||||
exe_target = /check/predef//$(exe_target) ;
|
||||
|
||||
# Create the check run if we don't have one yet.
|
||||
local key = [ MD5 $(language)::$(expression) ] ;
|
||||
if ! ( $(key) in $(_checks_) )
|
||||
{
|
||||
_checks_ += $(key) ;
|
||||
_message_(/check/predef//$(key).txt) = $(expression) ;
|
||||
make
|
||||
$(key).txt :
|
||||
$(exe_target) :
|
||||
@$(__name__).predef_check_action :
|
||||
<predef-expression>$(expression) ;
|
||||
explicit
|
||||
$(key).txt ;
|
||||
}
|
||||
|
||||
terms += /check/predef//$(key).txt ;
|
||||
}
|
||||
|
||||
local check_target = [ check-target-builds
|
||||
/check/predef//$(key).txt $(expression)
|
||||
: $(true-properties)
|
||||
: $(false-properties) ] ;
|
||||
|
||||
result += $(check_target) ;
|
||||
}
|
||||
project.pop-current ;
|
||||
local instance = [ new check-expression-evaluator
|
||||
$(terms) : $(true-properties) : $(false-properties) ] ;
|
||||
result = <conditional>@$(instance).check ;
|
||||
project.pop-current ;
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
@ -104,3 +112,95 @@ actions predef_check_action bind PREDEF_CHECK_EXPRESSION
|
||||
{
|
||||
$(>) "$(PREDEF_CHECK_EXPRESSION)" > $(<)
|
||||
}
|
||||
|
||||
class check-expression-evaluator
|
||||
{
|
||||
import configure ;
|
||||
|
||||
rule __init__ ( expression + : true-properties * : false-properties * )
|
||||
{
|
||||
self.expression = $(expression) ;
|
||||
self.true-properties = $(true-properties) ;
|
||||
self.false-properties = $(false-properties) ;
|
||||
}
|
||||
|
||||
rule check ( properties * )
|
||||
{
|
||||
local to-eval ;
|
||||
local tokens = "and" "or" ;
|
||||
# Go through the expression and: eval the target values,
|
||||
# and normalize to a full expression.
|
||||
for local term in $(self.expression)
|
||||
{
|
||||
if ! ( $(term:L) in $(tokens) )
|
||||
{
|
||||
# A value is a target reference that will evan to "true"
|
||||
# or "false".
|
||||
if $(to-eval[-1]:L) && ! ( $(to-eval[-1]:L) in $(tokens) )
|
||||
{
|
||||
# Default to "and" operation.
|
||||
to-eval += "and" ;
|
||||
}
|
||||
local message = [ modules.peek predef : _message_($(term)) ] ;
|
||||
if [ configure.builds $(term) : $(properties) : $(message) ]
|
||||
{
|
||||
to-eval += "true" ;
|
||||
}
|
||||
else
|
||||
{
|
||||
to-eval += "false" ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
to-eval += $(term) ;
|
||||
}
|
||||
}
|
||||
# Eval full the expression.
|
||||
local eval-result = [ eval $(to-eval) ] ;
|
||||
# And resolve true/false properties.
|
||||
if $(eval-result) = "true"
|
||||
{
|
||||
return $(self.true-properties) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $(self.false-properties) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule eval ( e * )
|
||||
{
|
||||
local r ;
|
||||
if $(e[1]) && $(e[2]) && $(e[3])
|
||||
{
|
||||
if $(e[2]) = "and"
|
||||
{
|
||||
if $(e[1]) = "true" && $(e[3]) = "true"
|
||||
{
|
||||
r = [ eval "true" $(e[4-]) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = [ eval "false" $(e[4-]) ] ;
|
||||
}
|
||||
}
|
||||
else if $(e[2]) = "or"
|
||||
{
|
||||
if $(e[1]) = "true" || $(e[3]) = "true"
|
||||
{
|
||||
r = [ eval "true" $(e[4-]) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = [ eval "false" $(e[4-]) ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = $(e[1]) ;
|
||||
}
|
||||
return $(r) ;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import ../check/predef : require : predef-require ;
|
||||
import ../check/predef : require check : predef-require predef-check ;
|
||||
|
||||
local predef-include-root ;
|
||||
local predef-dependency ;
|
||||
@ -57,4 +57,5 @@ test-suite predef :
|
||||
[ run make.cpp ]
|
||||
[ compile macos_endian.c : [ predef-require "BOOST_OS_MACOS" : cpp ] ]
|
||||
[ compile macos_vs_bsd.c : [ predef-require "BOOST_OS_MACOS" : cpp ] ]
|
||||
#[ run check_value.cpp : : : [ predef-check "BOOST_COMP_CLANG >= 4.0" "BOOST_OS_MACOS == 0" : : <cxxflags>-DCHECK_VALUE=true : <cxxflags>-DCHECK_VALUE=false ] ]
|
||||
;
|
||||
|
26
test/check_value.cpp
Normal file
26
test/check_value.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright Rene Rivera 2015
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Simple program that just prints out the externally
|
||||
* defined CHECK_VALUE def. It's used to test the check
|
||||
* program and the related BB support.
|
||||
*/
|
||||
|
||||
#include <boost/predef.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifndef CHECK_VALUE
|
||||
#define CHECK_VALUE "undefined"
|
||||
#endif
|
||||
|
||||
int main(int argc, const char ** argv)
|
||||
{
|
||||
std::cout << "CHECK_VALUE == " << CHECK_VALUE << "\n" ;
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user