summaryrefslogtreecommitdiff
path: root/libs/predef/check
diff options
context:
space:
mode:
Diffstat (limited to 'libs/predef/check')
-rw-r--r--libs/predef/check/build.jam9
-rw-r--r--libs/predef/check/predef.jam106
-rw-r--r--libs/predef/check/predef_check_as_c.c119
-rw-r--r--libs/predef/check/predef_check_as_cpp.cpp1
-rw-r--r--libs/predef/check/predef_check_as_objc.m1
-rw-r--r--libs/predef/check/predef_check_as_objcpp.mm1
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"