Add general predef_check utility program and BBv2 support for using it.

This commit is contained in:
Rene Rivera
2015-01-27 08:28:37 -06:00
parent 3766bba8d0
commit 211a868b80
8 changed files with 234 additions and 3 deletions

9
check/build.jam Normal file
View File

@ -0,0 +1,9 @@
# 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)
exe predef_check_as_c : predef_check_as_c.c : <include>../include ;
exe predef_check_as_cpp : predef_check_as_cpp.cpp : <include>../include ;
exe predef_check_as_objc : predef_check_as_objc.m : <include>../include ;
exe predef_check_as_objcpp : predef_check_as_objcpp.mm : <include>../include ;

98
check/predef.jam Normal file
View File

@ -0,0 +1,98 @@
# 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)
# Defines rules that provide requirements based on checking
# conditions using Boost Predef definitions and version numbers.
import modules ;
import project ;
import feature ;
import string ;
import toolset ;
import modules ;
import path ;
# Create a project for our targets.
project.extension predef check ;
# Feature to pass check expressions to check programs.
feature.feature predef-expression : : free ;
# Check programs. Each needs to be compiled for different languages
# even though they are all the same source code.
local rule check_target ( language : ext )
{
# Need to use absolute paths because we don't know the
# context of the invocation which affects where the paths
# originate from.
local source_path
= [ path.root $(__name__:D)/predef_check_as_$(language).$(ext) [ path.pwd ] ] ;
local include_path
= [ path.root $(__name__:D)/../include [ path.pwd ] ] ;
_check_exe_($(language)) = [
exe predef_check_as_$(language)
: $(source_path)
: <include>$(include_path) ] ;
explicit predef_check_as_$(language) ;
}
check_target c : c ;
check_target cpp : cpp ;
check_target objc : m ;
check_target objcpp : mm ;
# Checks the expressions and when used evaluates to the true-properties
# if the expressions are all true. Otherwise evaluates to the
# false-properties.
rule check ( expressions + : language ? : true-properties * : false-properties * )
{
# Default to C++ on the check context.
language ?= cpp ;
local project_target = [ project.target $(__name__) ] ;
project.push-current $(project_target) ;
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_) )
{
_checks_ += $(key) ;
make
$(key).txt :
$(exe_target) :
@$(__name__).predef_check_action :
<predef-expression>$(expression) ;
explicit
$(key).txt ;
}
local check_target = [ check-target-builds
/check/predef//$(key).txt $(expression)
: $(true-properties)
: $(false-properties) ] ;
result += $(check_target) ;
}
project.pop-current ;
return $(result) ;
}
# Checks the expressions and when used evaluates to <build>no
# if the expressions are all false. Otherwise evaluates to the
# nothing.
rule require ( expressions + : language ? )
{
return [ check $(expressions) : $(language) : : <build>no ] ;
}
actions predef_check_action bind PREDEF_CHECK_EXPRESSION
{
$(>) "$(PREDEF_CHECK_EXPRESSION)" > $(<)
}

119
check/predef_check_as_c.c Normal file
View File

@ -0,0 +1,119 @@
/*
Copyright Rene Rivera 2011-2012
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)
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define BOOST_PREDEF_INTERNAL_GENERATE_TESTS
typedef struct predef_info
{
unsigned tag;
const char * name;
const char * description;
unsigned value;
} predef_info;
predef_info first_predef_info = { 0x43210DEF , "-" , "-" , 0xFFFFFFFF };
#define BOOST_PREDEF_DECLARE_TEST(x,s) \
predef_info x##_predef_info = { 0x67890DEF , #x , s , x };
#include <boost/predef.h>
predef_info last_predef_info = { 0xFFFFFFFF , "-" , "-" , 0x43210DEF };
int predef_info_compare(const void * a, const void * b)
{
const predef_info ** i = (const predef_info **)a;
const predef_info ** j = (const predef_info **)b;
return strcmp((*i)->name,(*j)->name);
}
const char * str_token(const char ** str, const char * space)
{
unsigned span;
char * token;
for (; **str != 0; *str += 1)
{
if (0 == strchr(space, **str))
{
break;
}
}
span = strcspn(*str, space);
token = (char *)malloc(span+1);
strncpy(token, *str, span);
token[span] = 0;
for (*str += span; **str != 0; *str += 1)
{
if (0 == strchr(space, **str))
{
break;
}
}
return token;
}
const char * whitespace = " ";
const char * dot = ".";
int main(int argc, const char ** argv)
{
unsigned x = 0;
unsigned argi = 1;
predef_info ** predefs = 0;
unsigned predef_count = 0;
unsigned * i = &first_predef_info.tag;
unsigned * e = &last_predef_info.tag;
while (i < e)
{
i += 1;
if (*i == 0x67890DEF)
{
predef_count += 1;
predefs = (predef_info**)realloc(predefs,predef_count*sizeof(predef_info*));
predefs[predef_count-1] = (predef_info*)i;
}
}
qsort(predefs,predef_count,sizeof(predef_info*),predef_info_compare);
for (argi = 1; argi < argc; ++argi)
{
const char * exp = argv[argi];
const char * exp_name = str_token(&exp, whitespace);
const char * exp_op = str_token(&exp, whitespace);
const char * exp_val = str_token(&exp, whitespace);
unsigned exp_version = 0;
if (*exp_val != 0)
{
exp = exp_val;
const char * exp_val_a = str_token(&exp, dot);
const char * exp_val_b = str_token(&exp, dot);
const char * exp_val_c = str_token(&exp, dot);
exp_version = BOOST_VERSION_NUMBER(atoi(exp_val_a), atoi(exp_val_b),atoi(exp_val_c));
}
for (x = 0; x < predef_count; ++x)
{
if (*exp_op == 0 &&
predefs[x]->value == 0 &&
strcmp(exp_name, predefs[x]->name) == 0)
{
return argi;
}
else if (*exp_op != 0 && *exp_val != 0 &&
strcmp(exp_name, predefs[x]->name) == 0)
{
if (0 == strcmp(">",exp_op) && !(predefs[x]->value > exp_version)) return argi;
if (0 == strcmp("<",exp_op) && !(predefs[x]->value < exp_version)) return argi;
if (0 == strcmp(">=",exp_op) && !(predefs[x]->value >= exp_version)) return argi;
if (0 == strcmp("<=",exp_op) && !(predefs[x]->value <= exp_version)) return argi;
if (0 == strcmp("==",exp_op) && !(predefs[x]->value == exp_version)) return argi;
if (0 == strcmp("!=",exp_op) && !(predefs[x]->value != exp_version)) return argi;
}
}
}
return 0;
}

View File

@ -0,0 +1 @@
#include "predef_check_as_c.c"

View File

@ -0,0 +1 @@
#include "predef_check_as_c.c"

View File

@ -0,0 +1 @@
#include "predef_check_as_c.c"

View File

@ -52,7 +52,7 @@
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: December 30, 2014 at 14:12:07 GMT</small></p></td>
<td align="left"><p><small>Last revised: January 27, 2015 at 14:25:08 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@ -4,6 +4,8 @@
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import ../check/predef : require : predef-require ;
local predef-include-root ;
local predef-dependency ;
@ -53,6 +55,6 @@ test-suite predef :
[ run info_as_objc.m : : : <test-info>always_show_run_output ]
[ run version.cpp ]
[ run make.cpp ]
[ compile macos_endian.c ]
[ compile macos_vs_bsd.c ]
[ compile macos_endian.c : [ predef-require "BOOST_OS_MACOS" : cpp ] ]
[ compile macos_vs_bsd.c : [ predef-require "BOOST_OS_MACOS" : cpp ] ]
;