diff options
Diffstat (limited to 'libs/predef/check')
-rw-r--r-- | libs/predef/check/build.jam | 9 | ||||
-rw-r--r-- | libs/predef/check/predef.jam | 106 | ||||
-rw-r--r-- | libs/predef/check/predef_check_as_c.c | 119 | ||||
-rw-r--r-- | libs/predef/check/predef_check_as_cpp.cpp | 1 | ||||
-rw-r--r-- | libs/predef/check/predef_check_as_objc.m | 1 | ||||
-rw-r--r-- | libs/predef/check/predef_check_as_objcpp.mm | 1 |
6 files changed, 237 insertions, 0 deletions
diff --git a/libs/predef/check/build.jam b/libs/predef/check/build.jam new file mode 100644 index 000000000..1ce4f11e9 --- /dev/null +++ b/libs/predef/check/build.jam @@ -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 ; diff --git a/libs/predef/check/predef.jam b/libs/predef/check/predef.jam new file mode 100644 index 000000000..0638703a0 --- /dev/null +++ b/libs/predef/check/predef.jam @@ -0,0 +1,106 @@ +# 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 predef_jam + = [ modules.binding $(__name__) ] ; + local source_path + = $(predef_jam:D)/predef_check_as_$(language).$(ext) ; + local include_path + = $(predef_jam:D)/../include ; + _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 ] ; +} + +rule predef_check_action ( targets + : sources + : props * ) +{ + PREDEF_CHECK_EXPRESSION on $(targets) + = [ feature.get-values <predef-expression> : $(props) ] ; +} + +actions predef_check_action bind PREDEF_CHECK_EXPRESSION +{ + $(>) "$(PREDEF_CHECK_EXPRESSION)" > $(<) +} diff --git a/libs/predef/check/predef_check_as_c.c b/libs/predef/check/predef_check_as_c.c new file mode 100644 index 000000000..dcb7d6aa3 --- /dev/null +++ b/libs/predef/check/predef_check_as_c.c @@ -0,0 +1,119 @@ +/* +Copyright Rene Rivera 2011-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) +*/ +#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; + int 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; +} diff --git a/libs/predef/check/predef_check_as_cpp.cpp b/libs/predef/check/predef_check_as_cpp.cpp new file mode 100644 index 000000000..c58abe7a1 --- /dev/null +++ b/libs/predef/check/predef_check_as_cpp.cpp @@ -0,0 +1 @@ +#include "predef_check_as_c.c" diff --git a/libs/predef/check/predef_check_as_objc.m b/libs/predef/check/predef_check_as_objc.m new file mode 100644 index 000000000..c58abe7a1 --- /dev/null +++ b/libs/predef/check/predef_check_as_objc.m @@ -0,0 +1 @@ +#include "predef_check_as_c.c" diff --git a/libs/predef/check/predef_check_as_objcpp.mm b/libs/predef/check/predef_check_as_objcpp.mm new file mode 100644 index 000000000..c58abe7a1 --- /dev/null +++ b/libs/predef/check/predef_check_as_objcpp.mm @@ -0,0 +1 @@ +#include "predef_check_as_c.c" |