t_arith.sh revision 1.8 1 # $NetBSD: t_arith.sh,v 1.8 2017/07/15 18:50:42 kre Exp $
2 #
3 # Copyright (c) 2016 The NetBSD Foundation, Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 # POSSIBILITY OF SUCH DAMAGE.
26 #
27 # the implementation of "sh" to test
28 : ${TEST_SH:="/bin/sh"}
29
30 # Requirement is to support at least "signed long" whatever that means
31 # (number of bits in "long" is not specified - but should be at least 32).
32
33 # These tests use -o inline:"..." rather than -o match:'...' as we have
34 # only digits to examine, and it is good to be sure that 1 + 1 really gives 2
35 # and that 42 or 123 don't look like success because there is a 2 in them.
36
37 ARITH_BITS='?'
38 discover_range()
39 {
40 # cannot use arithmetic "test" operators, range of test in
41 # ATF_SHELL (or even TEST_SH) might not be as big as that
42 # supported by $(( )) in TEST_SH
43
44 if ! ${TEST_SH} -c ': $(( 0x10000 ))' 2>/dev/null
45 then
46 # 16 bits or less, or hex unsupported, just give up...
47 return
48 fi
49 test $( ${TEST_SH} -c 'echo $(( 0x1FFFF ))' ) = 131071 || return
50
51 # when attempting to exceed the number of available bits
52 # the shell may react in any of 3 (rational) ways
53 # 1. syntax error (maybe even core dump...) and fail
54 # 2. represent a positive number input as negative value
55 # 3. keep the number positive, but not the value expected
56 # (perhaps pegged at the max possible value)
57 # any of those may be accompanied by a message to stderr
58
59 # Must check all 3 possibilities for each plausible size
60 # Tests do not use 0x8000... because that value can have weird
61 # other side effects that are not relevant to discover here.
62 # But we do want to try and force the sign bit set.
63
64 if ! ${TEST_SH} -c ': $(( 0xC0000000 ))' 2>/dev/null
65 then
66 # proobably shell detected overflow and complained
67 ARITH_BITS=32
68 return
69 fi
70 if ${TEST_SH} 2>/dev/null \
71 -c 'case $(( 0xC0000000 )); in (-*) exit 0;; esac; exit 1'
72 then
73 ARITH_BITS=32
74 return
75 fi
76 if ${TEST_SH} -c '[ $(( 0xC0000000 )) != 3221225472 ]' 2>/dev/null
77 then
78 ARITH_BITS=32
79 return
80 fi
81
82 if ! ${TEST_SH} -c ': $(( 0xC000000000000000 ))' 2>/dev/null
83 then
84 ARITH_BITS=64
85 return
86 fi
87 if ${TEST_SH} 2>/dev/null \
88 -c 'case $(( 0xC000000000000000 )); in (-*) exit 0;; esac; exit 1'
89 then
90 ARITH_BITS=64
91 return
92 fi
93 if ${TEST_SH} 2>/dev/null \
94 -c '[ $((0xC000000000000000)) != 13835058055282163712 ]'
95 then
96 ARITH_BITS=64
97 return
98 fi
99
100 if ${TEST_SH} 2>/dev/null -c \
101 '[ $((0x123456781234567812345678)) = 5634002657842756053938493048 ]'
102 then
103 # just assume... (for now anyway, revisit when it happens...)
104 ARITH_BITS=96
105 return
106 fi
107 }
108
109 atf_test_case constants
110 constants_head()
111 {
112 atf_set "descr" "Tests that arithmetic expansion can handle constants"
113 }
114 constants_body()
115 {
116 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
117 'echo $(( 1 ))'
118 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
119 'echo $(( 0 ))'
120 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
121 'echo $((0x0))'
122
123 # atf_expect_fail "PR bin/50959"
124 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
125 'echo $((0X0))'
126 # atf_expect_pass
127
128 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
129 'echo $((000))'
130
131 atf_check -s exit:0 -o inline:'1\n' -e empty \
132 ${TEST_SH} -c 'echo $(( 000000001 ))'
133 atf_check -s exit:0 -o inline:'0\n' -e empty \
134 ${TEST_SH} -c 'echo $(( 0x000000 ))'
135
136 atf_check -s exit:0 -o inline:'99999\n' -e empty \
137 ${TEST_SH} -c 'echo $((99999))'
138
139 [ ${ARITH_BITS} -gt 44 ] &&
140 atf_check -s exit:0 -o inline:'9191919191919\n' -e empty \
141 ${TEST_SH} -c 'echo $((9191919191919))'
142
143 atf_check -s exit:0 -o inline:'13\n' -e empty ${TEST_SH} -c \
144 'echo $(( 0xD ))'
145 atf_check -s exit:0 -o inline:'11\n' -e empty ${TEST_SH} -c \
146 'echo $(( 013 ))'
147 atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \
148 'x=7;echo $(($x))'
149 atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
150 'x=9;echo $((x))'
151
152 atf_check -s exit:0 -o inline:'11\n' -e empty \
153 ${TEST_SH} -c 'x=0xB; echo $(( $x ))'
154 atf_check -s exit:0 -o inline:'27\n' -e empty \
155 ${TEST_SH} -c 'x=0X1B; echo $(( x ))'
156 atf_check -s exit:0 -o inline:'27\n' -e empty \
157 ${TEST_SH} -c 'X=033; echo $(( $X ))'
158 atf_check -s exit:0 -o inline:'219\n' -e empty \
159 ${TEST_SH} -c 'X=0333; echo $(( X ))'
160 atf_check -s exit:0 -o inline:'0\n' -e empty \
161 ${TEST_SH} -c 'NULL=; echo $(( NULL ))'
162
163 # Not clear if this is 0, nothing, or an error, so omit for now
164 # atf_check -s exit:0 -o inline:'0\n' -e empty \
165 # ${TEST_SH} -c 'echo $(( ))'
166
167 # not clear whether this should return 0 or an error, so omit for now
168 # atf_check -s exit:0 -o inline:'0\n' -e empty \
169 # ${TEST_SH} -c 'echo $(( UNDEFINED_VAR ))'
170 }
171
172
173 atf_test_case do_unary_plus
174 do_unary_plus_head()
175 {
176 atf_set "descr" "Tests that unary plus works as expected"
177 }
178 do_unary_plus_body()
179 {
180 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
181 'echo $(( +0 ))'
182 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
183 'echo $(( +1 ))'
184 atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
185 'echo $(( + 6 ))'
186 atf_check -s exit:0 -o inline:'4321\n' -e empty ${TEST_SH} -c \
187 'echo $(( + 4321 ))'
188 atf_check -s exit:0 -o inline:'17185\n' -e empty ${TEST_SH} -c \
189 'echo $(( + 0x4321 ))'
190 }
191
192 atf_test_case do_unary_minus
193 do_unary_minus_head()
194 {
195 atf_set "descr" "Tests that unary minus works as expected"
196 }
197 do_unary_minus_body()
198 {
199 atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
200 'echo $(( -1 ))'
201 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
202 'echo $(( - 0 ))'
203 atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
204 'echo $(( - 1 ))'
205 atf_check -s exit:0 -o inline:'-6\n' -e empty ${TEST_SH} -c \
206 'echo $(( - 6 ))'
207 atf_check -s exit:0 -o inline:'-4321\n' -e empty ${TEST_SH} -c \
208 'echo $(( - 4321 ))'
209 atf_check -s exit:0 -o inline:'-2257\n' -e empty ${TEST_SH} -c \
210 'echo $(( - 04321 ))'
211 atf_check -s exit:0 -o inline:'-7\n' -e empty ${TEST_SH} -c \
212 'echo $((-7))'
213 }
214
215 atf_test_case do_unary_not
216 do_unary_not_head()
217 {
218 atf_set "descr" "Tests that unary not (boolean) works as expected"
219 }
220 do_unary_not_body()
221 {
222 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
223 'echo $(( ! 1 ))'
224 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
225 'echo $(( ! 0 ))'
226
227 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
228 'echo $(( !1234 ))'
229 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
230 'echo $(( !0xFFFF ))'
231 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
232 'echo $(( ! 000000 ))'
233 }
234
235 atf_test_case do_unary_tilde
236 do_unary_tilde_head()
237 {
238 atf_set "descr" "Tests that unary not (bitwise) works as expected"
239 }
240 do_unary_tilde_body()
241 {
242 # definitely 2's complement arithmetic here...
243
244 atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
245 'echo $(( ~ 0 ))'
246 atf_check -s exit:0 -o inline:'-2\n' -e empty ${TEST_SH} -c \
247 'echo $(( ~ 1 ))'
248
249 atf_check -s exit:0 -o inline:'-1235\n' -e empty ${TEST_SH} -c \
250 'echo $(( ~1234 ))'
251 atf_check -s exit:0 -o inline:'-256\n' -e empty ${TEST_SH} -c \
252 'echo $(( ~0xFF ))'
253 }
254
255 atf_test_case elementary_add
256 elementary_add_head()
257 {
258 atf_set "descr" "Tests that simple addition works as expected"
259 }
260 elementary_add_body()
261 {
262 # some of these tests actually test unary ops & op precedence...
263
264 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
265 'echo $(( 0 + 0 ))'
266 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
267 'echo $(( 1 + 0 ))'
268 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
269 'echo $(( 0 + 1 ))'
270 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
271 'echo $(( 1 + 1 ))'
272 atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
273 'echo $(( 4 + 6 ))'
274 atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
275 'echo $(( 6 + 4 ))'
276 atf_check -s exit:0 -o inline:'5555\n' -e empty ${TEST_SH} -c \
277 'echo $(( 1234 + 4321 ))'
278 atf_check -s exit:0 -o inline:'3333\n' -e empty ${TEST_SH} -c \
279 'echo $((1111+2222))'
280 atf_check -s exit:0 -o inline:'5555\n' -e empty ${TEST_SH} -c \
281 'echo $((+3333+2222))'
282 atf_check -s exit:0 -o inline:'7777\n' -e empty ${TEST_SH} -c \
283 'echo $((+3333 + +4444))'
284 atf_check -s exit:0 -o inline:'-7777\n' -e empty ${TEST_SH} -c \
285 'echo -$((+4125+ +3652))'
286 }
287
288 atf_test_case elementary_sub
289 elementary_sub_head()
290 {
291 atf_set "descr" "Tests that simple subtraction works as expected"
292 }
293 elementary_sub_body()
294 {
295 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
296 'echo $(( 0 - 0 ))'
297 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
298 'echo $(( 1 - 0 ))'
299 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
300 'echo $(( 1 - 1 ))'
301 atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
302 'echo $(( 0 - 1 ))'
303 atf_check -s exit:0 -o inline:'488\n' -e empty ${TEST_SH} -c \
304 'echo $(( 1066 - 578 ))'
305 atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
306 'echo $(( 2016-5678 ))'
307 atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
308 'echo $(( 2016+-5678 ))'
309 atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
310 'echo $(( 2016-+5678 ))'
311 atf_check -s exit:0 -o inline:'-7694\n' -e empty ${TEST_SH} -c \
312 'echo $(( -2016-5678 ))'
313 atf_check -s exit:0 -o inline:'--1\n' -e empty ${TEST_SH} -c \
314 'echo -$(( -1018 - -1017 ))'
315 }
316
317 atf_test_case elementary_mul
318 elementary_mul_head()
319 {
320 atf_set "descr" "Tests that simple multiplication works as expected"
321 }
322 elementary_mul_body()
323 {
324 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
325 'echo $(( 0 * 0 ))'
326 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
327 'echo $(( 1 * 0 ))'
328 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
329 'echo $(( 0 * 1 ))'
330 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
331 'echo $(( 1 * 1 ))'
332 atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
333 'echo $(( -1 * 1 ))'
334 atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
335 'echo $(( 1 * -1 ))'
336 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
337 'echo $(( -1 * -1 ))'
338 atf_check -s exit:0 -o inline:'391\n' -e empty ${TEST_SH} -c \
339 'echo $(( 17 * 23 ))'
340 atf_check -s exit:0 -o inline:'169\n' -e empty ${TEST_SH} -c \
341 'echo $(( 13*13 ))'
342 atf_check -s exit:0 -o inline:'-11264\n' -e empty ${TEST_SH} -c \
343 'echo $(( -11 *1024 ))'
344 atf_check -s exit:0 -o inline:'-16983\n' -e empty ${TEST_SH} -c \
345 'echo $(( 17* -999 ))'
346 atf_check -s exit:0 -o inline:'9309\n' -e empty ${TEST_SH} -c \
347 'echo $(( -29*-321 ))'
348 }
349
350 atf_test_case elementary_div
351 elementary_div_head()
352 {
353 atf_set "descr" "Tests that simple division works as expected"
354 }
355 elementary_div_body()
356 {
357 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
358 'echo $(( 0 / 1 ))'
359 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
360 'echo $(( 1 / 1 ))'
361 test ${ARITH_BITS} -ge 38 &&
362 atf_check -s exit:0 -o inline:'99999999999\n' -e empty \
363 ${TEST_SH} -c 'echo $(( 99999999999 / 1 ))'
364 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
365 'echo $(( 2 / 1 ))'
366
367 atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
368 'echo $(( 3 / 1 ))'
369 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
370 'echo $(( 3 / 2 ))'
371 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
372 'echo $(( 3 / 3 ))'
373 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
374 'echo $(( 3 / 4 ))'
375
376 atf_check -s exit:0 -o inline:'173\n' -e empty ${TEST_SH} -c \
377 'echo $(( 123456 / 713 ))'
378 atf_check -s exit:0 -o inline:'13\n' -e empty ${TEST_SH} -c \
379 'echo $(( 169 / 13 ))'
380 }
381
382 atf_test_case elementary_rem
383 elementary_rem_head()
384 {
385 atf_set "descr" "Tests that simple modulus works as expected"
386 }
387 elementary_rem_body()
388 {
389 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
390 'echo $(( 0 % 1 ))'
391 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
392 'echo $(( 1 % 1 ))'
393 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
394 'echo $(( 2 % 1 ))'
395 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
396 'echo $(( 9999 % 1 ))'
397
398 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
399 'echo $(( 0 % 2 ))'
400 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
401 'echo $(( 1 % 2 ))'
402 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
403 'echo $(( 2 % 2 ))'
404 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
405 'echo $(( 0xFFFF % 2 ))'
406
407 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
408 'echo $(( 0 % 3 ))'
409 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
410 'echo $(( 1 % 3 ))'
411 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
412 'echo $(( 2 % 3 ))'
413 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
414 'echo $(( 3 % 3 ))'
415 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
416 'echo $(( 3123 % 3 ))'
417
418 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
419 'echo $(( 9999 % 2 ))'
420
421 atf_check -s exit:0 -o inline:'107\n' -e empty ${TEST_SH} -c \
422 'echo $(( 123456%173 ))'
423 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
424 'echo $((169%13))'
425 }
426
427 atf_test_case elementary_shl
428 elementary_shl_head()
429 {
430 atf_set "descr" "Tests that simple shift left works as expected"
431 }
432 elementary_shl_body()
433 {
434 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
435 'echo $(( 0 << 0 ))'
436 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
437 'echo $(( 0 << 1 ))'
438 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
439 'echo $(( 0 << 17 ))'
440
441 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
442 'echo $(( 1 << 0 ))'
443 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
444 'echo $(( 1 << 1 ))'
445 atf_check -s exit:0 -o inline:'131072\n' -e empty ${TEST_SH} -c \
446 'echo $(( 1 << 17 ))'
447
448 atf_check -s exit:0 -o inline:'2021161080\n' -e empty ${TEST_SH} -c \
449 'echo $(( 0x3C3C3C3C << 1 ))'
450
451 test "${ARITH_BITS}" -ge 40 &&
452 atf_check -s exit:0 -o inline:'129354309120\n' -e empty \
453 ${TEST_SH} -c 'echo $(( 0x3C3C3C3C << 7 ))'
454 test "${ARITH_BITS}" -ge 72 &&
455 atf_check -s exit:0 -o inline:'1111145054534149079040\n' \
456 -e empty ${TEST_SH} -c 'echo $(( 0x3C3C3C3C << 40 ))'
457
458 return 0
459 }
460
461 atf_test_case elementary_shr
462 elementary_shr_head()
463 {
464 atf_set "descr" "Tests that simple shift right works as expected"
465 }
466 elementary_shr_body()
467 {
468 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
469 'echo $(( 0 >> 0 ))'
470 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
471 'echo $(( 0 >> 1 ))'
472 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
473 'echo $(( 0 >> 17 ))'
474
475 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
476 'echo $(( 1 >> 0 ))'
477 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
478 'echo $(( 1 >> 1 ))'
479 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
480 'echo $(( 2 >> 1 ))'
481 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
482 'echo $(( 3 >> 1 ))'
483
484 atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
485 'echo $(( 0x10 >> 2 ))'
486 atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
487 'echo $(( 022 >> 2 ))'
488
489 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
490 'echo $(( 131072 >> 17 ))'
491
492 test ${ARITH_BITS} -ge 40 &&
493 atf_check -s exit:0 -o inline:'8\n' -e empty ${TEST_SH} -c \
494 'echo $(( 0x4000000000 >> 35 ))'
495 test ${ARITH_BITS} -ge 80 &&
496 atf_check -s exit:0 -o inline:'4464\n' -e empty ${TEST_SH} -c \
497 'echo $(( 0x93400FACE005C871000 >> 64 ))'
498
499 return 0
500 }
501
502 atf_test_case elementary_eq
503 elementary_eq_head()
504 {
505 atf_set "descr" "Tests that simple equality test works as expected"
506 }
507 elementary_eq_body()
508 {
509 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
510 'echo $(( 0 == 0 ))'
511 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
512 'echo $(( 0 == 0000 ))'
513 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
514 'echo $(( 0 == 0x00 ))'
515 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
516 'echo $(( 1 == 1 ))'
517 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
518 'X=30; Y=0x1E; echo $(( X == Y ))'
519 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
520 'echo $(( 0x1234 == 4660 ))'
521 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
522 'echo $(( 0x1234 == 011064 ))'
523
524 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
525 'echo $(( 0 == 1 ))'
526 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
527 'echo $(( 0 == 0000000000000001 ))'
528 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
529 'echo $(( 0 == 0x10000000000000 ))'
530 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
531 'echo $(( 1 == 2 ))'
532 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
533 'X=3; Y=7; echo $(( X == Y ))'
534 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
535 'echo $(( 1234 == 0x4660 ))'
536 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
537 'echo $(( 01234 == 0x11064 ))'
538 }
539 atf_test_case elementary_ne
540 elementary_ne_head()
541 {
542 atf_set "descr" "Tests that simple inequality test works as expected"
543 }
544 elementary_ne_body()
545 {
546 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
547 'echo $(( 1 != 0 ))'
548 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
549 'echo $(( 0x71 != 17 ))'
550 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
551 'echo $(( 1234 != 01234 ))'
552 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
553 'echo $(( 0x1234 != 01234 ))'
554 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
555 'X=3; echo $(( X != 0 ))'
556 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
557 'X=3; Y=0x11; echo $(( X != Y ))'
558
559 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
560 'echo $(( 3 != 3 ))'
561 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
562 'echo $(( 0 != 0x0 ))'
563 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
564 'echo $(( 0xA != 012 ))'
565 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
566 'X=1; echo $(( X != 1 ))'
567 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
568 'X=0xC; Y=014; echo $(( X != Y ))'
569 }
570 atf_test_case elementary_lt
571 elementary_lt_head()
572 {
573 atf_set "descr" "Tests that simple less than test works as expected"
574 }
575 elementary_lt_body()
576 {
577 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
578 'echo $(( 0 < 1 ))'
579 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
580 'echo $(( -1 < 0 ))'
581 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
582 'echo $(( 0 < 10 ))'
583 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
584 'echo $(( 100 < 101 ))'
585 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
586 'echo $(( 0xA1 < 200 ))'
587
588 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
589 'echo $(( 0 < 0 ))'
590 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
591 'echo $(( 1 < 0 ))'
592
593 test ${ARITH_BITS} -ge 40 &&
594 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
595 'echo $(( 0x1BEEFF00D < 0x1FACECAFE ))'
596
597 return 0
598 }
599 atf_test_case elementary_le
600 elementary_le_head()
601 {
602 atf_set "descr" "Tests that simple less or equal test works as expected"
603 }
604 elementary_le_body()
605 {
606 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
607 'echo $(( 0 <= 1 ))'
608 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
609 'echo $(( -1 <= 0 ))'
610 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
611 'echo $(( 0 <= 0 ))'
612 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
613 'echo $(( 0 <= 10 ))'
614 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
615 'echo $(( 100 <= 101 ))'
616 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
617 'echo $(( 0xA1 <= 161 ))'
618
619 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
620 'echo $(( 1 <= 0 ))'
621 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
622 'echo $(( -100 <= -200 ))'
623
624 test ${ARITH_BITS} -ge 40 &&
625 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
626 'cost=; AUD=; echo $(( $cost 0x2FEEDBABE <= $AUD 12866927294 ))'
627
628 return 0
629 }
630 atf_test_case elementary_gt
631 elementary_gt_head()
632 {
633 atf_set "descr" "Tests that simple greater than works as expected"
634 }
635 elementary_gt_body()
636 {
637 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
638 'echo $(( 1 > 0 ))'
639 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
640 'echo $(( 1 > -1 ))'
641 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
642 'echo $(( 11 > 012 ))'
643
644 # atf_expect_fail "PR bin/50959"
645 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
646 'echo $(( 2147483647 > 0X7FFFFF0 ))'
647 # atf_expect_pass
648
649 test ${ARITH_BITS} -gt 32 &&
650 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
651 'echo $(( 0x80000000 > 0x7FFFFFFF ))'
652
653 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
654 'echo $(( 0 > 0 ))'
655 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
656 'echo $(( 0 > 1 ))'
657 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
658 'echo $(( -1 > 0 ))'
659 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
660 'echo $(( 0 > 10 ))'
661 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
662 'echo $(( 2015 > 2016 ))'
663 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
664 'echo $(( 0xA1 > 200 ))'
665
666 test ${ARITH_BITS} -ge 44 &&
667 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
668 'echo $(( 0x7F07F07F0 > 34099628014 ))'
669
670 return 0
671 }
672 atf_test_case elementary_ge
673 elementary_ge_head()
674 {
675 atf_set "descr" "Tests that simple greater or equal works as expected"
676 }
677 elementary_ge_body()
678 {
679 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
680 'echo $(( 0 >= 0 ))'
681 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
682 'echo $(( 1 >= 0 ))'
683 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
684 'echo $(( -100 >= -101 ))'
685
686 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
687 'echo $(( -1 >= 0 ))'
688 }
689
690 atf_test_case fiddle_bits_and
691 fiddle_bits_and_head()
692 {
693 atf_set "descr" "Test bitwise and operations in arithmetic expressions"
694 }
695 fiddle_bits_and_body()
696 {
697 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
698 'echo $(( 0 & 0 ))'
699 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
700 'echo $(( 1 & 0 ))'
701 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
702 'echo $(( 0 & 1 ))'
703 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
704 'echo $(( 1 & 1 ))'
705
706 atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
707 'echo $(( 0xFF & 0xFF ))'
708 atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
709 'echo $(( 0xFFFF & 0377 ))'
710
711 test "${ARITH_BITS}" -ge 48 &&
712 atf_check -s exit:0 -o inline:'70377641607203\n' -e empty \
713 ${TEST_SH} -c 'echo $(( 0x5432FEDC0123 & 0x42871357BAB3 ))'
714
715 return 0
716 }
717 atf_test_case fiddle_bits_or
718 fiddle_bits_or_head()
719 {
720 atf_set "descr" "Test bitwise or operations in arithmetic expressions"
721 }
722 fiddle_bits_or_body()
723 {
724 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
725 'echo $(( 0 | 0 ))'
726 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
727 'echo $(( 1 | 0 ))'
728 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
729 'echo $(( 0 | 1 ))'
730 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
731 'echo $(( 1 | 1 ))'
732
733 atf_check -s exit:0 -o inline:'4369\n' -e empty ${TEST_SH} -c \
734 'echo $(( 0x1111 | 0x1111 ))'
735 atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
736 'echo $(( 0xAA | 0125 ))'
737
738 test "${ARITH_BITS}" -ge 48 &&
739 atf_check -s exit:0 -o inline:'95348271856563\n' -e empty \
740 ${TEST_SH} -c 'echo $(( 0x5432FEDC0123 | 0x42871357BAB3 ))'
741
742 return 0
743 }
744 atf_test_case fiddle_bits_xor
745 fiddle_bits_xor_head()
746 {
747 atf_set "descr" "Test bitwise xor operations in arithmetic expressions"
748 }
749 fiddle_bits_xor_body()
750 {
751 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
752 'echo $(( 0 ^ 0 ))'
753 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
754 'echo $(( 1 ^ 0 ))'
755 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
756 'echo $(( 0 ^ 1 ))'
757 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
758 'echo $(( 1 ^ 1 ))'
759
760 atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
761 'echo $(( 0xF0 ^ 0x0F ))'
762 atf_check -s exit:0 -o inline:'15\n' -e empty ${TEST_SH} -c \
763 'echo $(( 0xF0 ^ 0xFF ))'
764
765 test "${ARITH_BITS}" -ge 48 &&
766 atf_check -s exit:0 -o inline:'24970630249360\n' -e empty \
767 ${TEST_SH} -c 'echo $(( 0x5432FEDC0123 ^ 0x42871357BAB3 ))'
768
769 return 0
770 }
771
772 atf_test_case logical_and
773 logical_and_head()
774 {
775 atf_set "descr" "Test logical and operations in arithmetic expressions"
776 }
777 logical_and_body()
778 {
779 # cannot test short-circuit eval until sh implements side effects...
780
781 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
782 'echo $(( 0 && 0 ))'
783 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
784 'echo $(( 1 && 0 ))'
785 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
786 'echo $(( 0 && 1 ))'
787 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
788 'echo $(( 1 && 1 ))'
789
790 # atf_expect_fail "PR bin/50960"
791 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
792 'echo $(( 0x1111 && 01234 ))'
793 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
794 'echo $(( 0xFFFF && 0xF0F0 ))'
795 }
796 atf_test_case logical_or
797 logical_or_head()
798 {
799 atf_set "descr" "Test logical or operations in arithmetic expressions"
800 }
801 logical_or_body()
802 {
803 # cannot test short-circuit eval until sh implements side effects...
804
805 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
806 'echo $(( 0 || 0 ))'
807 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
808 'echo $(( 1 || 0 ))'
809 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
810 'echo $(( 0 || 1 ))'
811 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
812 'echo $(( 1 || 1 ))'
813
814 # atf_expect_fail "PR bin/50960"
815 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
816 'echo $(( 0x1111 || 01234 ))'
817 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
818 'echo $(( 0x33 || 0xF0F0 ))'
819 }
820
821 atf_test_case nested_arith
822 nested_arith_head()
823 {
824 atf_set "descr" 'Test nested arithmetic $(( $(( )) ))'
825 }
826 nested_arith_body()
827 {
828 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
829 'echo $(( $(( 0 )) ))'
830 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
831 'echo $(( 1 + $(( 2 - 2 )) ))'
832 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
833 'echo $(( $(( 3 / 3 )) + $((1*1*1)) - $(( 7 % 6 ))))'
834 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
835 'echo $(($(($(($(($((1))))))))))'
836
837 atf_check -s exit:0 -o inline:'246\n' -e empty ${TEST_SH} -c \
838 'echo $(( 2$((2 * 2))6 ))'
839 atf_check -s exit:0 -o inline:'291117\n' -e empty ${TEST_SH} -c \
840 'echo $(( $((1 + 1))$((3 * 3))$(( 99-88 ))$(( 17))))'
841 atf_check -s exit:0 -o inline:'123456789\n' -e empty ${TEST_SH} -c \
842 'echo $(( 1$((2$((1+2))4$((2 + 2 + 1))6))7$((4 * 2))$(($((81/9))))))'
843 }
844
845 atf_test_case make_selection
846 make_selection_head()
847 {
848 atf_set "descr" "Test ?: operator in arithmetic expressions"
849 }
850 make_selection_body()
851 {
852 # atf_expect_fail "PR bin/50958"
853
854 atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
855 'echo $(( 0 ? 2 : 3 ))'
856 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
857 'echo $(( 1 ? 2 : 3 ))'
858
859 atf_check -s exit:0 -o inline:'111\n' -e empty ${TEST_SH} -c \
860 'echo $(( 0x1234 ? 111 : 222 ))'
861
862 atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
863 'echo $(( 1 < 2 ? -1 : 1 > 2 ? 1 : 0 ))'
864 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
865 'echo $(( 1 < 1 ? -1 : 1 > 1 ? 1 : 0 ))'
866 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
867 'echo $(( 2 < 1 ? -1 : 2 > 1 ? 1 : 0 ))'
868 }
869
870 atf_test_case operator_precedence
871 operator_precedence_head()
872 {
873 atf_set "descr" "Test operator precedence without parentheses"
874 }
875 operator_precedence_body()
876 {
877 # NB: apart from $(( )) ** NO ** parentheses in the expressions.
878
879 atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
880 'echo $(( 1 + 2 + 3 ))'
881 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
882 'echo $(( 1 - 2 + 3 ))'
883 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
884 'echo $(( 3 - 2 - 1 ))'
885 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
886 'echo $(( 3 - 2 + 1 ))'
887
888 atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
889 'echo $(( - 2 + 1 ))'
890 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
891 'echo $(( 2 + -1 ))'
892
893 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
894 'echo $(( ! 2 + 1 ))'
895 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
896 'echo $(( 2 + !1 ))'
897
898 atf_check -s exit:0 -o inline:'8\n' -e empty ${TEST_SH} -c \
899 'echo $(( 3 * 2 + 2 ))'
900 atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \
901 'echo $(( 3 + 2 * 2 ))'
902 atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
903 'echo $(( 3 * 2 * 2 ))'
904
905 atf_check -s exit:0 -o inline:'5\n' -e empty ${TEST_SH} -c \
906 'echo $(( 9 / 3 + 2 ))'
907 atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
908 'echo $(( 9 + 3 / 2 ))'
909 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
910 'echo $(( 9 / 3 / 2 ))'
911
912 atf_check -s exit:0 -o inline:'72\n' -e empty ${TEST_SH} -c \
913 'echo $(( 9 << 1 + 2 ))'
914 atf_check -s exit:0 -o inline:'48\n' -e empty ${TEST_SH} -c \
915 'echo $(( 9 + 3 << 2 ))'
916 atf_check -s exit:0 -o inline:'288\n' -e empty ${TEST_SH} -c \
917 'echo $(( 9 << 3 << 2 ))'
918
919 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
920 'echo $(( 9 >> 1 + 2 ))'
921 atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
922 'echo $(( 9 + 3 >> 2 ))'
923 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
924 'echo $(( 19 >> 3 >> 1 ))'
925
926 atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
927 'echo $(( 19 >> 3 << 1 ))'
928 atf_check -s exit:0 -o inline:'76\n' -e empty ${TEST_SH} -c \
929 'echo $(( 19 << 3 >> 1 ))'
930
931 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
932 'echo $(( 2 + 3 < 3 * 2 ))'
933 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
934 'echo $(( 2 << 3 >= 3 << 2 ))'
935
936 # sh inherits C's crazy operator precedence...
937
938 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
939 'echo $(( 0xfD & 0xF == 0xF ))'
940
941 ${TEST_SH} -c ': $(( 1 , 2 , 3 ))' 2>/dev/null && {
942 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
943 'echo $(( 3 * 7 , 2 << 8 , 9 - 7 ))'
944 atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
945 'echo $(( 1 ? 2 : 3 , 0 ? 1 : 4 ))'
946 }
947
948 return 0
949 }
950
951 atf_test_case optional_comma
952 optional_comma_head()
953 {
954 atf_set "descr" "Test the optional comma operator"
955 }
956 optional_comma_body()
957 {
958 # First, see if it is supported or not.
959 ${TEST_SH} -c ': $(( 1 , 2 , 3 ))' 2>/dev/null || atf_skip \
960 "${TEST_SH} does not implement the ',' operator in"' $(( ))'
961
962
963 # Note ',' should be set off from numbers by spaces, as in some
964 # locales it is a valid chacacter in a number, and we want to
965 # avoid any possibility of confusing the parser.
966
967 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
968 'echo $(( 1 , 2 ))'
969 atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
970 'echo $(( 1 , 2 , 3 ))'
971 atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
972 'echo $(( 1 , 2 , 3 , 4 ))'
973
974 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
975 'echo $(( , 2 ))'
976 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
977 'echo $(( 2 , ))'
978 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
979 'echo $(( 1 , , 2 ))'
980 }
981
982 parentheses_head()
983 {
984 atf_set "descr" "Test use of () to group sub-expressions"
985 }
986 parentheses_body()
987 {
988 atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
989 'echo $(( (1 + 2) + 3 ))'
990 atf_check -s exit:0 -o inline:'-4\n' -e empty ${TEST_SH} -c \
991 'echo $(( 1 - (2 + 3) ))'
992 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
993 'echo $(( 3 - (2 - 1) ))'
994 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
995 'echo $(( 3 - ( 2 + 1 ) ))'
996
997 atf_check -s exit:0 -o inline:'-3\n' -e empty ${TEST_SH} -c \
998 'echo $(( - (2 + 1) ))'
999
1000 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
1001 'echo $(( ! (2 + 1) ))'
1002
1003 atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
1004 'echo $(( 3 * (2 + 2) ))'
1005 atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
1006 'echo $(( (3 + 2) * 2 ))'
1007 atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
1008 'echo $(( 3 * (2 * 2) ))'
1009
1010 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
1011 'echo $(( 9 / (3 + 2) ))'
1012 atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
1013 'echo $(( ( 9 + 3 ) / 2 ))'
1014 atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
1015 'echo $(( 9 / ( 3 / 2 ) ))'
1016
1017 atf_check -s exit:0 -o inline:'20\n' -e empty ${TEST_SH} -c \
1018 'echo $(( ( 9 << 1 ) + 2 ))'
1019 atf_check -s exit:0 -o inline:'21\n' -e empty ${TEST_SH} -c \
1020 'echo $(( 9 + (3 << 2) ))'
1021 atf_check -s exit:0 -o inline:'36864\n' -e empty ${TEST_SH} -c \
1022 'echo $(( 9 << (3 << 2) ))'
1023
1024 atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
1025 'echo $(( (9 >> 1) + 2 ))'
1026 atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
1027 'echo $(( 9 + (3 >> 2) ))'
1028 atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
1029 'echo $(( 19 >> (3 >> 1) ))'
1030
1031 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
1032 'echo $(( 19 >> (3 << 1) ))'
1033 atf_check -s exit:0 -o inline:'38\n' -e empty ${TEST_SH} -c \
1034 'echo $(( 19 << (3 >> 1) ))'
1035
1036 atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
1037 'echo $(( 2 + (3 < 3) * 2 ))'
1038 atf_check -s exit:0 -o inline:'32\n' -e empty ${TEST_SH} -c \
1039 'echo $(( 2 << ((3 >= 3) << 2) ))'
1040
1041 # sh inherits C's crazy operator precedence...
1042 atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
1043 'echo $(( (0xfD & 0xF) == 0xF ))'
1044
1045 ${TEST_SH} -c ': $(( 1 , 2 , 3 ))' 2>/dev/null && {
1046 atf_check -s exit:0 -o inline:'24\n' -e empty ${TEST_SH} -c \
1047 'echo $(( 3 * (7 , 2) << (8 , 9 - 7) ))'
1048 atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
1049 'echo $(( 0 ? 2 : ( ( 0 , 3 ) ? 1 : 4) ))'
1050 }
1051 return 0
1052 }
1053
1054 atf_test_case var_assign
1055 var_assign_head()
1056 {
1057 atf_set "descr" "Test assignment operators in arithmetic expressions"
1058 }
1059 var_assign_body()
1060 {
1061 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1062 'unset x; echo $(( x = 3 )); echo $x'
1063 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1064 'unset x; echo $((x=3)); echo $x'
1065 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1066 'x=5; echo $((x=3)); echo $x'
1067
1068 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1069 'set +u;unset x; echo $((x+=3)); echo $x'
1070 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1071 'x=2; echo $((x+=1)); echo $x'
1072 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1073 'x=4; echo $((x-=1)); echo $x'
1074 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1075 'x=3; echo $((x*=1)); echo $x'
1076 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1077 'x=3; echo $((x/=1)); echo $x'
1078 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1079 'x=28; echo $((x%=5)); echo $x'
1080 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1081 'x=7; echo $((x&=3)); echo $x'
1082 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1083 'x=2; echo $((x|=1)); echo $x'
1084 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1085 'x=6; echo $((x^=5)); echo $x'
1086 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1087 'x=7; echo $((x>>=1)); echo $x'
1088 atf_check -s exit:0 -o inline:'2\n2\n' -e empty ${TEST_SH} -c \
1089 'x=1; echo $((x<<=1)); echo $x'
1090
1091 atf_check -s exit:0 -o inline:'2\n3\n' -e empty ${TEST_SH} -c \
1092 'x=2; echo $(( (x+=1)-1 )); echo $x'
1093 atf_check -s exit:0 -o inline:'4\n3\n' -e empty ${TEST_SH} -c \
1094 'x=4; echo $(( (x-=1)+1 )); echo $x'
1095
1096 atf_check -s exit:0 -o inline:'36\n5 7\n' -e empty ${TEST_SH} -c \
1097 'unset x y; echo $(( (x=5) * (y=7) + 1 )); echo $x $y'
1098 atf_check -s exit:0 -o inline:'36\n5 7\n' -e empty ${TEST_SH} -c \
1099 'x=99; y=17; echo $(( (x=5) * (y=7) + 1 )); echo $x $y'
1100 atf_check -s exit:0 -o inline:'36\n5 7\n' -e empty ${TEST_SH} -c \
1101 'x=4; y=9; echo $(( (x+=1) * (y-=2) + 1 )); echo $x $y'
1102
1103 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1104 'set -u; unset x; echo $(( x = 3 )); echo $x'
1105 atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
1106 'set -u; unset x; echo $(( x + 3 )); echo $x'
1107 atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
1108 'set -u; unset x; echo $(( x+=3 )); echo $x'
1109
1110 ${TEST_SH} -c ': $(( 1 , 2 , 3 ))' 2>/dev/null && {
1111 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1112 'echo $((x=2 , x|=1)); echo $x'
1113 atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1114 'set -u; echo $((x = 2 ,x |= 1)); echo $x'
1115 atf_check -s exit:0 -o inline:'6\n1:2:3:6\n' -e empty \
1116 ${TEST_SH} -c \
1117 'echo $((a=1 , b=2 , c = 3 , x=a+b + c)); echo $a:$b:$c:$x'
1118 atf_check -s exit:0 -o inline:'6\n1:2:3:6\n' -e empty \
1119 ${TEST_SH} -c \
1120 'set -u;echo $((a=1 ,b=2 ,c=3 ,x=a+b+c)); echo $a:$b:$c:$x'
1121 }
1122 return 0
1123 }
1124
1125 atf_test_case var_postinc
1126 var_postinc_head()
1127 {
1128 atf_set "descr" "Test suffix ++ operator"
1129 }
1130 var_postinc_body()
1131 {
1132 ${TEST_SH} -c 'X=1; : $(( X++ ))' 2>/dev/null ||
1133 atf_skip "${TEST_SH} does not support the suffix ++ operator"
1134
1135 unset X ; # just in case ...
1136
1137 atf_check -s exit:0 -o inline:'1\n2\n' -e empty ${TEST_SH} -c \
1138 'X=1; echo $(( X++ )); echo $X'
1139 atf_check -s exit:0 -o inline:'0\n1\n' -e empty ${TEST_SH} -c \
1140 'echo $(( X++ )); echo $X'
1141
1142 atf_check -s exit:0 -o inline:'0\n1:0\n' -e empty ${TEST_SH} -c \
1143 'unset Y; echo $(( Y = X++ )); echo $X:$Y'
1144 atf_check -s exit:0 -o inline:'12\n4:5\n' -e empty ${TEST_SH} -c \
1145 'X=3 Y=4; echo $(( Y++*X++ )); echo $X:$Y'
1146
1147 atf_check -s exit:0 -o inline:'1\n2\n' -e empty ${TEST_SH} -c \
1148 'set -u; X=1; echo $(( X++ )); echo $X'
1149 atf_check -s exit:0 -o inline:'0\n1:0\n' -e empty ${TEST_SH} -c \
1150 'set -u; X=0; unset Y; echo $(( Y = X++ )); echo $X:$Y'
1151 atf_check -s exit:0 -o inline:'12\n4:5\n' -e empty ${TEST_SH} -c \
1152 'set -u; X=3 Y=4; echo $(( Y++*X++ )); echo $X:$Y'
1153
1154 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1155 'set -u; echo $(( X++ ))'
1156 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1157 'set -u; unset Y; echo $(( X = Y++ ))'
1158
1159 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1160 'X=3; readonly X; echo $(( X++ ))'
1161
1162 }
1163 atf_test_case var_postdec
1164 var_postdec_head()
1165 {
1166 atf_set "descr" "Test suffix -- operator"
1167 }
1168 var_postdec_body()
1169 {
1170 ${TEST_SH} -c 'X=1; : $(( X-- ))' 2>/dev/null ||
1171 atf_skip "${TEST_SH} does not support the suffix -- operator"
1172
1173 unset X ; # just in case ...
1174
1175 atf_check -s exit:0 -o inline:'1\n0\n' -e empty ${TEST_SH} -c \
1176 'X=1; echo $(( X-- )); echo $X'
1177 atf_check -s exit:0 -o inline:'0\n-1\n' -e empty ${TEST_SH} -c \
1178 'echo $(( X-- )); echo $X'
1179
1180 atf_check -s exit:0 -o inline:'0\n-1:0\n' -e empty ${TEST_SH} -c \
1181 'unset Y; echo $(( Y = X-- )); echo $X:$Y'
1182 atf_check -s exit:0 -o inline:'12\n2:3\n' -e empty ${TEST_SH} -c \
1183 'X=3 Y=4; echo $(( Y--*X-- )); echo $X:$Y'
1184
1185 atf_check -s exit:0 -o inline:'1\n0\n' -e empty ${TEST_SH} -c \
1186 'set -u; X=1; echo $(( X-- )); echo $X'
1187 atf_check -s exit:0 -o inline:'0\n-1:0\n' -e empty ${TEST_SH} -c \
1188 'set -u; X=0; unset Y; echo $(( Y = X-- )); echo $X:$Y'
1189 atf_check -s exit:0 -o inline:'12\n2:3\n' -e empty ${TEST_SH} -c \
1190 'set -u; X=3 Y=4; echo $(( Y--*X-- )); echo $X:$Y'
1191
1192 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1193 'set -u; echo $(( X-- ))'
1194 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1195 'set -u; unset Y; echo $(( X = Y-- ))'
1196
1197 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1198 'X=3; readonly X; echo $(( X-- ))'
1199
1200 }
1201 atf_test_case var_preinc
1202 var_preinc_head()
1203 {
1204 atf_set "descr" "Test prefix ++ operator"
1205 }
1206 var_preinc_body()
1207 {
1208 ${TEST_SH} -c 'X=1; : $(( ++X ))' 2>/dev/null ||
1209 atf_skip "${TEST_SH} does not support the prefix ++ operator"
1210
1211 unset X ; # just in case ...
1212
1213 atf_check -s exit:0 -o inline:'2\n2\n' -e empty ${TEST_SH} -c \
1214 'X=1; echo $(( ++X )); echo $X'
1215 atf_check -s exit:0 -o inline:'1\n1\n' -e empty ${TEST_SH} -c \
1216 'echo $(( ++X )); echo $X'
1217
1218 atf_check -s exit:0 -o inline:'1\n1:1\n' -e empty ${TEST_SH} -c \
1219 'unset Y; echo $(( Y = ++X )); echo $X:$Y'
1220 atf_check -s exit:0 -o inline:'20\n4:5\n' -e empty ${TEST_SH} -c \
1221 'X=3 Y=4; echo $(( ++Y*++X )); echo $X:$Y'
1222
1223 atf_check -s exit:0 -o inline:'2\n2\n' -e empty ${TEST_SH} -c \
1224 'set -u; X=1; echo $(( ++X )); echo $X'
1225 atf_check -s exit:0 -o inline:'1\n1:1\n' -e empty ${TEST_SH} -c \
1226 'set -u; X=0; unset Y; echo $(( Y = ++X )); echo $X:$Y'
1227 atf_check -s exit:0 -o inline:'20\n4:5\n' -e empty ${TEST_SH} -c \
1228 'set -u; X=3 Y=4; echo $(( ++Y*++X )); echo $X:$Y'
1229
1230 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1231 'set -u; echo $(( ++X ))'
1232 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1233 'set -u; unset Y; echo $(( X = ++Y ))'
1234
1235 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1236 'X=3; readonly X; echo $(( ++X ))'
1237
1238 }
1239 atf_test_case var_predec
1240 var_predec_head()
1241 {
1242 atf_set "descr" "Test prefix -- operator"
1243 }
1244 var_predec_body()
1245 {
1246 ${TEST_SH} -c 'X=1; : $(( --X ))' 2>/dev/null ||
1247 atf_skip "${TEST_SH} does not support the prefix -- operator"
1248
1249 unset X ; # just in case ...
1250
1251 atf_check -s exit:0 -o inline:'0\n0\n' -e empty ${TEST_SH} -c \
1252 'X=1; echo $(( --X )); echo $X'
1253 atf_check -s exit:0 -o inline:'-1\n-1\n' -e empty ${TEST_SH} -c \
1254 'echo $(( --X )); echo $X'
1255
1256 atf_check -s exit:0 -o inline:'-1\n-1:-1\n' -e empty ${TEST_SH} -c \
1257 'unset Y; echo $(( Y = --X )); echo $X:$Y'
1258 atf_check -s exit:0 -o inline:'6\n2:3\n' -e empty ${TEST_SH} -c \
1259 'X=3 Y=4; echo $(( --Y*--X )); echo $X:$Y'
1260
1261 atf_check -s exit:0 -o inline:'0\n0\n' -e empty ${TEST_SH} -c \
1262 'set -u; X=1; echo $(( --X )); echo $X'
1263 atf_check -s exit:0 -o inline:'-1\n-1:-1\n' -e empty ${TEST_SH} -c \
1264 'set -u; X=0; unset Y; echo $(( Y = --X )); echo $X:$Y'
1265 atf_check -s exit:0 -o inline:'6\n2:3\n' -e empty ${TEST_SH} -c \
1266 'set -u; X=3 Y=4; echo $(( --Y*--X )); echo $X:$Y'
1267
1268 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1269 'set -u; echo $(( --X ))'
1270 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1271 'set -u; unset Y; echo $(( X = --Y ))'
1272
1273 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1274 'X=3; readonly X; echo $(( --X ))'
1275
1276 }
1277
1278 atf_test_case arithmetic_fails
1279 arithmetic_fails_head()
1280 {
1281 atf_set "descr" "Dummy test to force failure"
1282 }
1283 arithmetic_fails_body()
1284 {
1285 atf_fail "Cannot estimate number of bits supported by $(( ))"
1286 }
1287
1288 atf_init_test_cases() {
1289
1290 discover_range
1291
1292 test "${ARITH_BITS}" = '?' && {
1293 atf_add_test_case arithmetic_fails
1294 return 0
1295 }
1296
1297 # odd names are to get atf's sort order semi-rational
1298
1299 atf_add_test_case constants
1300 atf_add_test_case do_unary_plus
1301 atf_add_test_case do_unary_minus
1302 atf_add_test_case do_unary_not
1303 atf_add_test_case do_unary_tilde
1304 atf_add_test_case elementary_add
1305 atf_add_test_case elementary_sub
1306 atf_add_test_case elementary_mul
1307 atf_add_test_case elementary_div
1308 atf_add_test_case elementary_rem
1309 atf_add_test_case elementary_shl
1310 atf_add_test_case elementary_shr
1311 atf_add_test_case elementary_eq
1312 atf_add_test_case elementary_ne
1313 atf_add_test_case elementary_lt
1314 atf_add_test_case elementary_le
1315 atf_add_test_case elementary_gt
1316 atf_add_test_case elementary_ge
1317 atf_add_test_case fiddle_bits_and
1318 atf_add_test_case fiddle_bits_or
1319 atf_add_test_case fiddle_bits_xor
1320 atf_add_test_case logical_and
1321 atf_add_test_case logical_or
1322 atf_add_test_case make_selection
1323 atf_add_test_case nested_arith
1324 atf_add_test_case operator_precedence
1325 atf_add_test_case optional_comma
1326 atf_add_test_case parentheses
1327 # atf_add_test_case progressive # build up big expr
1328 # atf_add_test_case test_errors # erroneous input
1329 # atf_add_test_case torture # hard stuff (if there is any)
1330 atf_add_test_case var_assign # assignment ops
1331 atf_add_test_case var_postinc # var++
1332 atf_add_test_case var_postdec # var--
1333 atf_add_test_case var_preinc # ++var
1334 atf_add_test_case var_predec # --var
1335 # atf_add_test_case vulgarity # truly evil inputs (syntax in vars...)
1336 }
1337