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:
Rene Rivera
2015-05-18 21:54:31 -05:00
parent 550521f1b4
commit 99bd64cd11
3 changed files with 151 additions and 24 deletions

View File

@ -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) ;
}
}

View File

@ -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
View 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;
}