]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/kernel/errors.jam
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / tools / build / src / kernel / errors.jam
1 # Copyright 2003 Dave Abrahams
2 # Copyright 2004 Vladimir Prus
3 # Distributed under the Boost Software License, Version 1.0.
4 # (See accompanying file LICENSE_1_0.txt or copy at
5 # http://www.boost.org/LICENSE_1_0.txt)
6
7 # Print a stack backtrace leading to this rule's caller. Each argument
8 # represents a line of output to be printed after the first line of the
9 # backtrace.
10 #
11 rule backtrace ( skip-frames prefix messages * : * )
12 {
13 local frame-skips = 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 ;
14 local drop-elements = $(frame-skips[$(skip-frames)]) ;
15 if ! ( $(skip-frames) in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 )
16 {
17 ECHO "warning: backtrace doesn't support skipping $(skip-frames) "
18 "frames; using 1 instead." ;
19 drop-elements = 5 ;
20 }
21
22 local args = $(.args) ;
23 if $(.user-modules-only)
24 {
25 local bt = [ nearest-user-location ] ;
26 if $(bt)
27 {
28 ECHO $(prefix) at $(bt) ;
29 }
30 for local n in $(args)
31 {
32 if $($(n))-is-defined
33 {
34 ECHO $(prefix) $($(n)) ;
35 }
36 }
37 }
38 else
39 {
40 # Get the whole backtrace, then drop the initial quadruples
41 # corresponding to the frames that must be skipped.
42 local bt = [ BACKTRACE ] ;
43 bt = $(bt[$(drop-elements)-]) ;
44
45 while $(bt)
46 {
47 local m = [ MATCH ^(.+)\\.$ : $(bt[3]) ] ;
48 ECHO $(bt[1]):$(bt[2]): "in" $(bt[4]) "from module" $(m) ;
49
50 # The first time through, print each argument on a separate line.
51 for local n in $(args)
52 {
53 if $($(n))-is-defined
54 {
55 ECHO $(prefix) $($(n)) ;
56 }
57 }
58 args = ; # Kill args so that this never happens again.
59
60 # Move on to the next quadruple.
61 bt = $(bt[5-]) ;
62 }
63 }
64 }
65
66 .args ?= messages 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ;
67 .disabled ?= ;
68 .last-error-$(.args) ?= ;
69
70
71 # try-catch --
72 #
73 # This is not really an exception-handling mechanism, but it does allow us to
74 # perform some error-checking on our error-checking. Errors are suppressed after
75 # a try, and the first one is recorded. Use catch to check that the error
76 # message matched expectations.
77
78 # Begin looking for error messages.
79 #
80 rule try ( )
81 {
82 .disabled += true ;
83 .last-error-$(.args) = ;
84 }
85
86
87 # Stop looking for error messages; generate an error if an argument of messages
88 # is not found in the corresponding argument in the error call.
89 #
90 rule catch ( messages * : * )
91 {
92 .disabled = $(.disabled[2-]) ; # Pop the stack.
93
94 import sequence ;
95
96 if ! $(.last-error-$(.args))-is-defined
97 {
98 error-skip-frames 3 expected an error, but none occurred ;
99 }
100 else
101 {
102 for local n in $(.args)
103 {
104 if ! $($(n)) in $(.last-error-$(n))
105 {
106 local v = [ sequence.join $($(n)) : " " ] ;
107 v ?= "" ;
108 local joined = [ sequence.join $(.last-error-$(n)) : " " ] ;
109
110 .last-error-$(.args) = ;
111 error-skip-frames 3 expected \"$(v)\" in argument $(n) of error
112 : got \"$(joined)\" instead ;
113 }
114 }
115 }
116 }
117
118
119 rule error-skip-frames ( skip-frames messages * : * )
120 {
121 if ! $(.disabled)
122 {
123 backtrace $(skip-frames) error: $(messages) : $(2) : $(3) : $(4) : $(5)
124 : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14)
125 : $(15) : $(16) : $(17) : $(18) : $(19) ;
126 EXIT ;
127 }
128 else if ! $(.last-error-$(.args))
129 {
130 for local n in $(.args)
131 {
132 # Add an extra empty string so that we always have something in the
133 # event of an error.
134 .last-error-$(n) = $($(n)) "" ;
135 }
136 }
137 }
138
139 if --no-error-backtrace in [ modules.peek : ARGV ]
140 {
141 .no-error-backtrace = true ;
142 }
143
144
145 # Print an error message with a stack backtrace and exit.
146 #
147 rule error ( messages * : * )
148 {
149 if $(.no-error-backtrace)
150 {
151 local first-printed ;
152 # Print each argument on a separate line.
153 for local n in $(.args)
154 {
155 if $($(n))-is-defined
156 {
157 if ! $(first-printed)
158 {
159 ECHO error: $($(n)) ;
160 first-printed = true ;
161 }
162 else
163 {
164 ECHO $($(n)) ;
165 }
166 }
167 }
168 EXIT ;
169 }
170 else
171 {
172 error-skip-frames 3 $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) :
173 $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16)
174 : $(17) : $(18) : $(19) ;
175 }
176 }
177
178
179 # Same as 'error', but the generated backtrace will include only user files.
180 #
181 rule user-error ( messages * : * )
182 {
183 .user-modules-only = 1 ;
184 error-skip-frames 3 $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) :
185 $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) :
186 $(18) : $(19) ;
187 }
188
189
190 # Print a warning message with a stack backtrace and exit.
191 #
192 rule warning
193 {
194 backtrace 2 warning: $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) :
195 $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) :
196 $(18) : $(19) ;
197 }
198
199
200 # Convert an arbitrary argument list into a list with ":" separators and quoted
201 # elements representing the same information. This is mostly useful for
202 # formatting descriptions of arguments with which a rule was called when
203 # reporting an error.
204 #
205 rule lol->list ( * )
206 {
207 local result ;
208 local remaining = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ;
209 while $($(remaining))
210 {
211 local n = $(remaining[1]) ;
212 remaining = $(remaining[2-]) ;
213
214 if $(n) != 1
215 {
216 result += ":" ;
217 }
218 result += \"$($(n))\" ;
219 }
220 return $(result) ;
221 }
222
223
224 # Return the file:line for the nearest entry in backtrace which correspond to a
225 # user module.
226 #
227 rule nearest-user-location ( )
228 {
229 local bt = [ BACKTRACE ] ;
230
231 local result ;
232 while $(bt) && ! $(result)
233 {
234 local m = [ MATCH ^(.+)\\.$ : $(bt[3]) ] ;
235 local user-modules = ([Jj]amroot(.jam|.v2|)|([Jj]amfile(.jam|.v2|)|user-config.jam|site-config.jam|project-config.jam|project-root.jam) ;
236
237 if [ MATCH $(user-modules) : $(bt[1]:D=) ]
238 {
239 result = $(bt[1]):$(bt[2]) ;
240 }
241 bt = $(bt[5-]) ;
242 }
243 return $(result) ;
244 }
245
246
247 # If optimized rule is available in Jam, use it.
248 if NEAREST_USER_LOCATION in [ RULENAMES ]
249 {
250 rule nearest-user-location ( )
251 {
252 local r = [ NEAREST_USER_LOCATION ] ;
253 return $(r[1]):$(r[2]) ;
254 }
255 }
256
257
258 rule __test__ ( )
259 {
260 # Show that we can correctly catch an expected error.
261 try ;
262 {
263 error an error occurred : somewhere ;
264 }
265 catch an error occurred : somewhere ;
266
267 # Show that unexpected errors generate real errors.
268 try ;
269 {
270 try ;
271 {
272 error an error occurred : somewhere ;
273 }
274 catch an error occurred : nowhere ;
275 }
276 catch expected \"nowhere\" in argument 2 ;
277
278 # Show that not catching an error where one was expected is an error.
279 try ;
280 {
281 try ;
282 {
283 }
284 catch ;
285 }
286 catch expected an error, but none occurred ;
287 }