]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/predef/tools/check/predef.jam
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / predef / tools / check / predef.jam
1 # Copyright Rene Rivera 2015
2 # Distributed under the Boost Software License, Version 1.0.
3 # (See accompanying file LICENSE_1_0.txt or copy at
4 # http://www.boost.org/LICENSE_1_0.txt)
5
6 # Defines rules that provide requirements based on checking
7 # conditions using Boost Predef definitions and version numbers.
8
9 import modules ;
10 import project ;
11 import feature ;
12 import string ;
13 import toolset ;
14 import modules ;
15 import path ;
16 import "class" : new ;
17 import regex ;
18
19 # Create a project for our targets.
20 project.extension predef check ;
21
22 # Feature to pass check expressions to check programs.
23 feature.feature predef-expression : : free ;
24
25 # Checks the expressions and when used evaluates to the true-properties
26 # if the expressions are all true. Otherwise evaluates to the
27 # false-properties.
28 rule check ( expressions + : language ? : true-properties * : false-properties * )
29 {
30 # Default to C++ on the check context.
31 language ?= cpp ;
32
33 local project_target = [ project.target $(__name__) ] ;
34 project.push-current $(project_target) ;
35 local terms ;
36 local result ;
37 for expression in $(expressions)
38 {
39 if $(expression:L) in "and" "or"
40 {
41 terms += $(expression:L) ;
42 }
43 else
44 {
45 # Create the check run if we don't have one yet.
46 local key = [ MD5 $(language)::$(expression) ] ;
47 if ! ( $(key) in $(_checks_) )
48 {
49 _checks_ += $(key) ;
50 _message_(/check/predef//predef_check_cc_$(key)) = $(expression) ;
51 check_target $(language) $(key) : [ change_term_to_def $(expression) ] ;
52 }
53
54 terms += /check/predef//predef_check_cc_$(key) ;
55 }
56 }
57 local instance = [ new check-expression-evaluator
58 $(terms) : $(true-properties) : $(false-properties) ] ;
59 result = <conditional>@$(instance).check ;
60 project.pop-current ;
61 return $(result) ;
62 }
63
64 # Checks the expressions and when used evaluates to <build>no
65 # if the expressions are all false. Otherwise evaluates to the
66 # nothing.
67 rule require ( expressions + : language ? )
68 {
69 return [ check $(expressions) : $(language) : : <build>no ] ;
70 }
71
72 #############################################################################
73
74 .c.ext = c ;
75 .cpp.ext = cpp ;
76 .objc.ext = m ;
77 .objcpp.ext = mm ;
78
79 # Check targets. Each needs to be compiled for different languages
80 # even though they are all the same source code.
81 local rule check_target ( language key : requirements * )
82 {
83 # Need to use absolute paths because we don't know the
84 # context of the invocation which affects where the paths
85 # originate from.
86 local predef_jam
87 = [ modules.binding $(__name__) ] ;
88 local source_path
89 = $(predef_jam:D)/predef_check_cc_as_$(language).$(.$(language).ext) ;
90 local include_path
91 = $(predef_jam:D)/../../include ;
92 obj predef_check_cc_$(key)
93 : $(source_path)
94 : <include>$(include_path) $(requirements) ;
95 explicit predef_check_cc_$(key) ;
96 return predef_check_cc_$(key) ;
97 }
98
99 local rule change_term_to_def ( term )
100 {
101 local parts = [ regex.split $(term) " " ] ;
102 if $(parts[3])
103 {
104 local version_number = [ regex.split $(parts[3]) "[.]" ] ;
105 if ! $(version_number[3]) { version_number += "0" ; }
106 if ! $(version_number[2]) { version_number += "0" ; }
107 parts = $(parts[1-2]) BOOST_VERSION_NUMBER($(version_number:J=",")) ;
108 }
109 return <define>CHECK=\"$(parts:J=" ")\" ;
110 }
111
112 class check-expression-evaluator
113 {
114 import configure ;
115
116 rule __init__ ( expression + : true-properties * : false-properties * )
117 {
118 self.expression = $(expression) ;
119 self.true-properties = $(true-properties) ;
120 self.false-properties = $(false-properties) ;
121 }
122
123 rule check ( properties * )
124 {
125 local to-eval ;
126 local tokens = "and" "or" ;
127 # Go through the expression and: eval the target values,
128 # and normalize to a full expression.
129 for local term in $(self.expression)
130 {
131 if ! ( $(term:L) in $(tokens) )
132 {
133 # A value is a target reference that will evan to "true"
134 # or "false".
135 if $(to-eval[-1]:L) && ! ( $(to-eval[-1]:L) in $(tokens) )
136 {
137 # Default to "and" operation.
138 to-eval += "and" ;
139 }
140 local message = [ modules.peek predef : _message_($(term)) ] ;
141 if [ configure.builds $(term) : $(properties) : $(message) ]
142 {
143 to-eval += "true" ;
144 }
145 else
146 {
147 to-eval += "false" ;
148 }
149 }
150 else
151 {
152 to-eval += $(term) ;
153 }
154 }
155 # Eval full the expression.
156 local eval-result = [ eval $(to-eval) ] ;
157 # And resolve true/false properties.
158 if $(eval-result) = "true"
159 {
160 return $(self.true-properties) ;
161 }
162 else
163 {
164 return $(self.false-properties) ;
165 }
166 }
167
168 rule eval ( e * )
169 {
170 local r ;
171 if $(e[1]) && $(e[2]) && $(e[3])
172 {
173 if $(e[2]) = "and"
174 {
175 if $(e[1]) = "true" && $(e[3]) = "true"
176 {
177 r = [ eval "true" $(e[4-]) ] ;
178 }
179 else
180 {
181 r = [ eval "false" $(e[4-]) ] ;
182 }
183 }
184 else if $(e[2]) = "or"
185 {
186 if $(e[1]) = "true" || $(e[3]) = "true"
187 {
188 r = [ eval "true" $(e[4-]) ] ;
189 }
190 else
191 {
192 r = [ eval "false" $(e[4-]) ] ;
193 }
194 }
195 }
196 else
197 {
198 r = $(e[1]) ;
199 }
200 return $(r) ;
201 }
202 }