Home | History | Annotate | Line # | Download | only in sh
t_arith.sh revision 1.1
      1 # $NetBSD: t_arith.sh,v 1.1 2016/03/16 15:49:19 christos 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 lease 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 + 2 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 		# (if it does not support hex, we will discover that later)
     68 		ARITH_BITS=32
     69 		return
     70 	fi
     71 	if ${TEST_SH} 2>/dev/null \
     72 	    -c 'case $(( 0xC0000000 )); in (-*) exit 0;; esac; exit 1'
     73 	then
     74 		ARITH_BITS=32
     75 		return
     76 	fi
     77 	if ${TEST_SH} -c '[ $(( 0xC0000000 )) != 3221225472 ]' 2>/dev/null
     78 	then
     79 		ARITH_BITS=32
     80 		return
     81 	fi
     82 
     83 	if ! ${TEST_SH} -c ': $(( 0xC000000000000000 ))' 2>/dev/null
     84 	then
     85 		ARITH_BITS=64
     86 		return
     87 	fi
     88 	if ${TEST_SH} 2>/dev/null \
     89 	    -c 'case $(( 0xC000000000000000 )); in (-*) exit 0;; esac; exit 1'
     90 	then
     91 		ARITH_BITS=64
     92 		return
     93 	fi
     94 	if ${TEST_SH} 2>/dev/null \
     95 	    -c '[ $((0xC000000000000000)) != 13835058055282163712 ]'
     96 	then
     97 		ARITH_BITS=64
     98 		return
     99 	fi
    100 
    101 	if ${TEST_SH} 2>/dev/null -c \
    102 	   '[ $((0x123456781234567812345678)) = 5634002657842756053938493048 ]'
    103 	then
    104 		# just assume... (for now anyway, revisit when it happens...)
    105 		ARITH_BITS=96
    106 		return
    107 	fi
    108 }
    109 
    110 atf_test_case constants
    111 constants_head()
    112 {
    113         atf_set "descr" "Tests that arithmetic expansion can handle constants"
    114 }
    115 constants_body()
    116 {
    117 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    118 		'echo $(( 1 ))'
    119 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    120 		'echo $(( 0 ))'
    121 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    122 		'echo $((0x0))'
    123 
    124 	# atf_expect_fail "PR bin/50959"
    125 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    126 		'echo $((0X0))'
    127 	# atf_expect_pass
    128 
    129 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    130 		'echo $((000))'
    131 
    132 	atf_check -s exit:0 -o inline:'1\n' -e empty \
    133 		${TEST_SH} -c 'echo $(( 000000001 ))'
    134 	atf_check -s exit:0 -o inline:'0\n' -e empty \
    135 		${TEST_SH} -c 'echo $(( 0x000000 ))'
    136 
    137 	atf_check -s exit:0 -o inline:'99999\n' -e empty \
    138 		${TEST_SH} -c 'echo $((99999))'
    139 
    140 	[ ${ARITH_BITS} -gt 44 ] &&
    141 		atf_check -s exit:0 -o inline:'9191919191919\n' -e empty \
    142 			${TEST_SH} -c 'echo $((9191919191919))'
    143 
    144 	atf_check -s exit:0 -o inline:'13\n' -e empty ${TEST_SH} -c \
    145 		'echo $(( 0xD ))'
    146 	atf_check -s exit:0 -o inline:'11\n' -e empty ${TEST_SH} -c \
    147 		'echo $(( 013 ))'
    148 	atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \
    149 		'x=7;echo $(($x))'
    150 	atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
    151 		'x=9;echo $((x))'
    152 
    153 	atf_check -s exit:0 -o inline:'11\n' -e empty \
    154 		${TEST_SH} -c 'x=0xB; echo $(( $x ))'
    155 	atf_check -s exit:0 -o inline:'27\n' -e empty \
    156 		${TEST_SH} -c 'x=0X1B; echo $(( x ))'
    157 	atf_check -s exit:0 -o inline:'27\n' -e empty \
    158 		${TEST_SH} -c 'X=033; echo $(( $X ))'
    159 	atf_check -s exit:0 -o inline:'219\n' -e empty \
    160 		${TEST_SH} -c 'X=0333; echo $(( X ))'
    161 	atf_check -s exit:0 -o inline:'0\n' -e empty \
    162 		${TEST_SH} -c 'NULL=; echo $(( NULL ))'
    163 
    164 	# Not clear if this is 0, nothing, or an error, so omit for now
    165 	# atf_check -s exit:0 -o inline:'0\n' -e empty \
    166 	# 	${TEST_SH} -c 'echo $(( ))'
    167 
    168 	# not clear whether this should return 0 or an error, so omit for now
    169 	# atf_check -s exit:0 -o inline:'0\n' -e empty \
    170 	# 	${TEST_SH} -c 'echo $(( UNDEFINED_VAR ))'
    171 }
    172 
    173 atf_test_case constants_binary
    174 constants_binary_head()
    175 {
    176         atf_set "descr" "Optional tests that binary constants work as expected"
    177 }
    178 constants_binary_body()
    179 {
    180 	if ! ${TEST_SH} -c '[ $(( 0b0101 )) = 5 ]' 2>/dev/null
    181 	then
    182 		atf_skip "Binary constants (0b0101) not implemented"
    183 	fi
    184 
    185 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    186 		'echo $((0b0))'
    187 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    188 		'echo $((0b01))'
    189 	atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
    190 		'echo $((0b11))'
    191 	atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \
    192 		'echo $((0b111))'
    193 	atf_check -s exit:0 -o inline:'1398101\n' -e empty ${TEST_SH} -c \
    194 		'echo $(( 0b101010101010101010101 ))'
    195 	atf_check -s exit:0 -o inline:'119097103\n' -e empty ${TEST_SH} -c \
    196 		'echo $(( 0b111000110010100011100001111 ))'
    197 }
    198 
    199 atf_test_case do_unary_plus
    200 do_unary_plus_head()
    201 {
    202         atf_set "descr" "Tests that unary plus works as expected"
    203 }
    204 do_unary_plus_body()
    205 {
    206 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    207 		'echo $(( +0 ))'
    208 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    209 		'echo $(( +1 ))'
    210 	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
    211 		'echo $(( + 6 ))'
    212 	atf_check -s exit:0 -o inline:'4321\n' -e empty ${TEST_SH} -c \
    213 		'echo $(( + 4321 ))'
    214 	atf_check -s exit:0 -o inline:'17185\n' -e empty ${TEST_SH} -c \
    215 		'echo $(( + 0x4321 ))'
    216 }
    217 
    218 atf_test_case do_unary_minus
    219 do_unary_minus_head()
    220 {
    221         atf_set "descr" "Tests that unary minus works as expected"
    222 }
    223 do_unary_minus_body()
    224 {
    225 	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
    226 		'echo $(( -1 ))'
    227 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    228 		'echo $(( - 0 ))'
    229 	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
    230 		'echo $(( - 1 ))'
    231 	atf_check -s exit:0 -o inline:'-6\n' -e empty ${TEST_SH} -c \
    232 		'echo $(( - 6 ))'
    233 	atf_check -s exit:0 -o inline:'-4321\n' -e empty ${TEST_SH} -c \
    234 		'echo $(( - 4321 ))'
    235 	atf_check -s exit:0 -o inline:'-2257\n' -e empty ${TEST_SH} -c \
    236 		'echo $(( - 04321 ))'
    237 	atf_check -s exit:0 -o inline:'-7\n' -e empty ${TEST_SH} -c \
    238 		'echo $((-7))'
    239 }
    240 
    241 atf_test_case do_unary_not
    242 do_unary_not_head()
    243 {
    244         atf_set "descr" "Tests that unary not (boolean) works as expected"
    245 }
    246 do_unary_not_body()
    247 {
    248 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    249 		'echo $(( ! 1 ))'
    250 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    251 		'echo $(( ! 0 ))'
    252 
    253 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    254 		'echo $(( !1234 ))'
    255 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    256 		'echo $(( !0xFFFF ))'
    257 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    258 		'echo $(( ! 000000 ))'
    259 }
    260 
    261 atf_test_case do_unary_tilde
    262 do_unary_tilde_head()
    263 {
    264         atf_set "descr" "Tests that unary not (bitwise) works as expected"
    265 }
    266 do_unary_tilde_body()
    267 {
    268 	# definitely 2's complement arithmetic here...
    269 
    270 	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
    271 		'echo $(( ~ 0 ))'
    272 	atf_check -s exit:0 -o inline:'-2\n' -e empty ${TEST_SH} -c \
    273 		'echo $(( ~ 1 ))'
    274 
    275 	atf_check -s exit:0 -o inline:'-1235\n' -e empty ${TEST_SH} -c \
    276 		'echo $(( ~1234 ))'
    277 	atf_check -s exit:0 -o inline:'-256\n' -e empty ${TEST_SH} -c \
    278 		'echo $(( ~0xFF ))'
    279 }
    280 
    281 atf_test_case elementary_add
    282 elementary_add_head()
    283 {
    284         atf_set "descr" "Tests that simple addition works as expected"
    285 }
    286 elementary_add_body()
    287 {
    288 	# some of these tests actually test unary ops &  op precedence...
    289 
    290 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    291 		'echo $(( 0 + 0 ))'
    292 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    293 		'echo $(( 1 + 0 ))'
    294 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    295 		'echo $(( 0 + 1 ))'
    296 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    297 		'echo $(( 1 + 1 ))'
    298 	atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
    299 		'echo $(( 4 + 6 ))'
    300 	atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
    301 		'echo $(( 6 + 4 ))'
    302 	atf_check -s exit:0 -o inline:'5555\n' -e empty ${TEST_SH} -c \
    303 		'echo $(( 1234 + 4321 ))'
    304 	atf_check -s exit:0 -o inline:'3333\n' -e empty ${TEST_SH} -c \
    305 		'echo $((1111+2222))'
    306 	atf_check -s exit:0 -o inline:'5555\n' -e empty ${TEST_SH} -c \
    307 		'echo $((+3333+2222))'
    308 	atf_check -s exit:0 -o inline:'7777\n' -e empty ${TEST_SH} -c \
    309 		'echo $((+3333++4444))'
    310 	atf_check -s exit:0 -o inline:'-7777\n' -e empty ${TEST_SH} -c \
    311 		'echo -$((+4125++3652))'
    312 }
    313 
    314 atf_test_case elementary_sub
    315 elementary_sub_head()
    316 {
    317         atf_set "descr" "Tests that simple subtraction works as expected"
    318 }
    319 elementary_sub_body()
    320 {
    321 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    322 		'echo $(( 0 - 0 ))'
    323 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    324 		'echo $(( 1 - 0 ))'
    325 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    326 		'echo $(( 1 - 1 ))'
    327 	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
    328 		'echo $(( 0 - 1 ))'
    329 	atf_check -s exit:0 -o inline:'488\n' -e empty ${TEST_SH} -c \
    330 		'echo $(( 1066 - 578 ))'
    331 	atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
    332 		'echo $(( 2016-5678 ))'
    333 	atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
    334 		'echo $(( 2016+-5678 ))'
    335 	atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
    336 		'echo $(( 2016-+5678 ))'
    337 	atf_check -s exit:0 -o inline:'-7694\n' -e empty ${TEST_SH} -c \
    338 		'echo $(( -2016-5678 ))'
    339 	atf_check -s exit:0 -o inline:'--1\n' -e empty ${TEST_SH} -c \
    340 		'echo -$(( -1018--1017 ))'
    341 }
    342 
    343 atf_test_case elementary_mul
    344 elementary_mul_head()
    345 {
    346         atf_set "descr" "Tests that simple multiplication works as expected"
    347 }
    348 elementary_mul_body()
    349 {
    350 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    351 		'echo $(( 0 * 0 ))'
    352 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    353 		'echo $(( 1 * 0 ))'
    354 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    355 		'echo $(( 0 * 1 ))'
    356 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    357 		'echo $(( 1 * 1 ))'
    358 	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
    359 		'echo $(( -1 * 1 ))'
    360 	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
    361 		'echo $(( 1 * -1 ))'
    362 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    363 		'echo $(( -1 * -1 ))'
    364 	atf_check -s exit:0 -o inline:'391\n' -e empty ${TEST_SH} -c \
    365 		'echo $(( 17 * 23 ))'
    366 	atf_check -s exit:0 -o inline:'169\n' -e empty ${TEST_SH} -c \
    367 		'echo $(( 13*13 ))'
    368 	atf_check -s exit:0 -o inline:'-11264\n' -e empty ${TEST_SH} -c \
    369 		'echo $(( -11 *1024 ))'
    370 	atf_check -s exit:0 -o inline:'-16983\n' -e empty ${TEST_SH} -c \
    371 		'echo $(( 17* -999 ))'
    372 	atf_check -s exit:0 -o inline:'9309\n' -e empty ${TEST_SH} -c \
    373 		'echo $(( -29*-321 ))'
    374 }
    375 
    376 atf_test_case elementary_div
    377 elementary_div_head()
    378 {
    379         atf_set "descr" "Tests that simple division works as expected"
    380 }
    381 elementary_div_body()
    382 {
    383 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    384 		'echo $(( 0 / 1 ))'
    385 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    386 		'echo $(( 1 / 1 ))'
    387 	test ${ARITH_BITS} -ge 38 &&
    388 	    atf_check -s exit:0 -o inline:'99999999999\n' -e empty \
    389 		${TEST_SH} -c 'echo $(( 99999999999 / 1 ))'
    390 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    391 		'echo $(( 2 / 1 ))'
    392 
    393 	atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
    394 		'echo $(( 3 / 1 ))'
    395 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    396 		'echo $(( 3 / 2 ))'
    397 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    398 		'echo $(( 3 / 3 ))'
    399 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    400 		'echo $(( 3 / 4 ))'
    401 
    402 	atf_check -s exit:0 -o inline:'173\n' -e empty ${TEST_SH} -c \
    403 		'echo $(( 123456 / 713 ))'
    404 	atf_check -s exit:0 -o inline:'13\n' -e empty ${TEST_SH} -c \
    405 		'echo $(( 169 / 13 ))'
    406 }
    407 
    408 atf_test_case elementary_rem
    409 elementary_rem_head()
    410 {
    411         atf_set "descr" "Tests that simple modulus works as expected"
    412 }
    413 elementary_rem_body()
    414 {
    415 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    416 		'echo $(( 0 % 1 ))'
    417 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    418 		'echo $(( 1 % 1 ))'
    419 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    420 		'echo $(( 2 % 1 ))'
    421 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    422 		'echo $(( 9999 % 1 ))'
    423 
    424 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    425 		'echo $(( 0 % 2 ))'
    426 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    427 		'echo $(( 1 % 2 ))'
    428 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    429 		'echo $(( 2 % 2 ))'
    430 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    431 		'echo $(( 0xFFFF % 2 ))'
    432 
    433 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    434 		'echo $(( 0 % 3 ))'
    435 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    436 		'echo $(( 1 % 3 ))'
    437 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    438 		'echo $(( 2 % 3 ))'
    439 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    440 		'echo $(( 3 % 3 ))'
    441 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    442 		'echo $(( 3123 % 3 ))'
    443 
    444 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    445 		'echo $(( 9999 % 2 ))'
    446 
    447 	atf_check -s exit:0 -o inline:'107\n' -e empty ${TEST_SH} -c \
    448 		'echo $(( 123456%173 ))'
    449 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    450 		'echo $((169%13))'
    451 }
    452 
    453 atf_test_case elementary_shl
    454 elementary_shl_head()
    455 {
    456         atf_set "descr" "Tests that simple modulus works as expected"
    457 }
    458 elementary_shl_body()
    459 {
    460 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    461 		'echo $(( 0 << 0 ))'
    462 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    463 		'echo $(( 0 << 1 ))'
    464 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    465 		'echo $(( 0 << 17 ))'
    466 
    467 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    468 		'echo $(( 1 << 0 ))'
    469 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    470 		'echo $(( 1 << 1 ))'
    471 	atf_check -s exit:0 -o inline:'131072\n' -e empty ${TEST_SH} -c \
    472 		'echo $(( 1 << 17 ))'
    473 
    474 	atf_check -s exit:0 -o inline:'2021161080\n' -e empty ${TEST_SH} -c \
    475 		'echo $(( 0x3C3C3C3C << 1 ))'
    476 
    477 	test "${ARITH_BITS}" -ge 40 &&
    478 	    atf_check -s exit:0 -o inline:'129354309120\n' -e empty \
    479 		${TEST_SH} -c 'echo $(( 0x3C3C3C3C << 7 ))'
    480 	test "${ARITH_BITS}" -ge 72 &&
    481 	    atf_check -s exit:0 -o inline:'1111145054534149079040\n' \
    482 		-e empty ${TEST_SH} -c 'echo $(( 0x3C3C3C3C << 40 ))'
    483 
    484 	return 0
    485 }
    486 
    487 atf_test_case elementary_shr
    488 elementary_shr_head()
    489 {
    490         atf_set "descr" "Tests that simple modulus works as expected"
    491 }
    492 elementary_shr_body()
    493 {
    494 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    495 		'echo $(( 0 >> 0 ))'
    496 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    497 		'echo $(( 0 >> 1 ))'
    498 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    499 		'echo $(( 0 >> 17 ))'
    500 
    501 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    502 		'echo $(( 1 >> 0 ))'
    503 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    504 		'echo $(( 1 >> 1 ))'
    505 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    506 		'echo $(( 2 >> 1 ))'
    507 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    508 		'echo $(( 3 >> 1 ))'
    509 
    510 	atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
    511 		'echo $(( 0x10 >> 2 ))'
    512 	atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
    513 		'echo $(( 022 >> 2 ))'
    514 
    515 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    516 		'echo $(( 131072 >> 17 ))'
    517 
    518 	test ${ARITH_BITS} -ge 40 &&
    519 		atf_check -s exit:0 -o inline:'8\n' -e empty ${TEST_SH} -c \
    520 			'echo $(( 0x4000000000 >> 35 ))'
    521 	test ${ARITH_BITS} -ge 80 &&
    522 		atf_check -s exit:0 -o inline:'4464\n' -e empty ${TEST_SH} -c \
    523 			'echo $(( 0x93400FACE005C871000 >> 64 ))'
    524 
    525 	return 0
    526 }
    527 
    528 atf_test_case elementary_eq
    529 elementary_eq_head()
    530 {
    531         atf_set "descr" "Tests that simple equality test works as expected"
    532 }
    533 elementary_eq_body()
    534 {
    535 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    536 		'echo $(( 0 == 0 ))'
    537 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    538 		'echo $(( 0 == 0000 ))'
    539 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    540 		'echo $(( 0 == 0x00 ))'
    541 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    542 		'echo $(( 1 == 1 ))'
    543 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    544 		'X=30; Y=0x1E; echo $(( X == Y ))'
    545 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    546 		'echo $(( 0x1234 == 4660 ))'
    547 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    548 		'echo $(( 0x1234 == 011064 ))'
    549 
    550 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    551 		'echo $(( 0 == 1 ))'
    552 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    553 		'echo $(( 0 == 0000000000000001 ))'
    554 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    555 		'echo $(( 0 == 0x10000000000000 ))'
    556 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    557 		'echo $(( 1 == 2 ))'
    558 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    559 		'X=3; Y=7; echo $(( X == Y ))'
    560 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    561 		'echo $(( 1234 == 0x4660 ))'
    562 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    563 		'echo $(( 01234 == 0x11064 ))'
    564 }
    565 atf_test_case elementary_ne
    566 elementary_ne_head()
    567 {
    568         atf_set "descr" "Tests that simple inequality test works as expected"
    569 }
    570 elementary_ne_body()
    571 {
    572 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    573 		'echo $(( 1 != 0 ))'
    574 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    575 		'echo $(( 0x71 != 17 ))'
    576 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    577 		'echo $(( 1234 != 01234 ))'
    578 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    579 		'echo $(( 0x1234 != 01234 ))'
    580 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    581 		'X=3; echo $(( X != 0 ))'
    582 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    583 		'X=3; Y=0x11; echo $(( X != Y ))'
    584 
    585 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    586 		'echo $(( 3 != 3 ))'
    587 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    588 		'echo $(( 0 != 0x0 ))'
    589 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    590 		'echo $(( 0xA != 012 ))'
    591 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    592 		'X=1; echo $(( X != 1 ))'
    593 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    594 		'X=0xC; Y=014; echo $(( X != Y ))'
    595 }
    596 atf_test_case elementary_lt
    597 elementary_lt_head()
    598 {
    599         atf_set "descr" "Tests that simple less than test works as expected"
    600 }
    601 elementary_lt_body()
    602 {
    603 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    604 		'echo $(( 0 < 1 ))'
    605 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    606 		'echo $(( -1 < 0 ))'
    607 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    608 		'echo $(( 0 < 10 ))'
    609 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    610 		'echo $(( 100 < 101 ))'
    611 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    612 		'echo $(( 0xA1 < 200 ))'
    613 
    614 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    615 		'echo $(( 0 < 0 ))'
    616 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    617 		'echo $(( 1 < 0 ))'
    618 
    619 	test ${ARITH_BITS} -ge 40 &&
    620 	    atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    621 		'echo $(( 0x1BEEFF00D < 0x1FACECAFE ))'
    622 
    623 	return 0
    624 }
    625 atf_test_case elementary_le
    626 elementary_le_head()
    627 {
    628         atf_set "descr" "Tests that simple less or equal test works as expected"
    629 }
    630 elementary_le_body()
    631 {
    632 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    633 		'echo $(( 0 <= 1 ))'
    634 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    635 		'echo $(( -1 <= 0 ))'
    636 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    637 		'echo $(( 0 <= 0 ))'
    638 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    639 		'echo $(( 0 <= 10 ))'
    640 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    641 		'echo $(( 100 <= 101 ))'
    642 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    643 		'echo $(( 0xA1 <= 161 ))'
    644 
    645 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    646 		'echo $(( 1 <= 0 ))'
    647 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    648 		'echo $(( -100 <= -200 ))'
    649 
    650 	test ${ARITH_BITS} -ge 40 &&
    651 	    atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    652 		'cost=; AUD=; echo $(( $cost 0x2FEEDBABE <= $AUD 12866927294 ))'
    653 
    654 	return 0
    655 }
    656 atf_test_case elementary_gt
    657 elementary_gt_head()
    658 {
    659         atf_set "descr" "Tests that simple greater than works as expected"
    660 }
    661 elementary_gt_body()
    662 {
    663 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    664 		'echo $(( 1 > 0 ))'
    665 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    666 		'echo $(( 1 > -1 ))'
    667 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    668 		'echo $(( 11 > 012 ))'
    669 
    670 	# atf_expect_fail "PR bin/50959"
    671 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    672 		'echo $(( 2147483647 > 0X7FFFFF0 ))'
    673 	# atf_expect_pass
    674 
    675 	test ${ARITH_BITS} -gt 32 &&
    676 	    atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    677 		'echo $(( 0x80000000 > 0x7FFFFFFF ))'
    678 
    679 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    680 		'echo $(( 0 > 0 ))'
    681 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    682 		'echo $(( 0 > 1 ))'
    683 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    684 		'echo $(( -1 > 0 ))'
    685 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    686 		'echo $(( 0 > 10 ))'
    687 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    688 		'echo $(( 2015 > 2016 ))'
    689 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    690 		'echo $(( 0xA1 > 200 ))'
    691 
    692 	test ${ARITH_BITS} -ge 44 &&
    693 	    atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    694 		'echo $(( 0x7F07F07F0 > 34099628014 ))'
    695 
    696 	return 0
    697 }
    698 atf_test_case elementary_ge
    699 elementary_ge_head()
    700 {
    701         atf_set "descr" "Tests that simple greater or equal works as expected"
    702 }
    703 elementary_ge_body()
    704 {
    705 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    706 		'echo $(( 0 >= 0 ))'
    707 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    708 		'echo $(( 1 >= 0 ))'
    709 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    710 		'echo $(( -100 >= -101 ))'
    711 
    712 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    713 		'echo $(( -1 >= 0 ))'
    714 }
    715 
    716 atf_test_case fiddle_bits_and
    717 fiddle_bits_and_head()
    718 {
    719 	atf_set "descr" "Test bitwise and operations in arithmetic expressions"
    720 }
    721 fiddle_bits_and_body()
    722 {
    723 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    724 		'echo $(( 0 & 0 ))'
    725 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    726 		'echo $(( 1 & 0 ))'
    727 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    728 		'echo $(( 0 & 1 ))'
    729 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    730 		'echo $(( 1 & 1 ))'
    731 
    732 	atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
    733 		'echo $(( 0xFF & 0xFF ))'
    734 	atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
    735 		'echo $(( 0xFFFF & 0377 ))'
    736 
    737 	test "${ARITH_BITS}" -ge 48 &&
    738 	    atf_check -s exit:0 -o inline:'70377641607203\n' -e empty \
    739 		${TEST_SH} -c 'echo $(( 0x5432FEDC0123 & 0x42871357BAB3 ))'
    740 
    741 	return 0
    742 }
    743 atf_test_case fiddle_bits_or
    744 fiddle_bits_or_head()
    745 {
    746 	atf_set "descr" "Test bitwise or operations in arithmetic expressions"
    747 }
    748 fiddle_bits_or_body()
    749 {
    750 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    751 		'echo $(( 0 | 0 ))'
    752 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    753 		'echo $(( 1 | 0 ))'
    754 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    755 		'echo $(( 0 | 1 ))'
    756 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    757 		'echo $(( 1 | 1 ))'
    758 
    759 	atf_check -s exit:0 -o inline:'4369\n' -e empty ${TEST_SH} -c \
    760 		'echo $(( 0x1111 | 0x1111 ))'
    761 	atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
    762 		'echo $(( 0xAA | 0125 ))'
    763 
    764 	test "${ARITH_BITS}" -ge 48 &&
    765 	    atf_check -s exit:0 -o inline:'95348271856563\n' -e empty \
    766 		${TEST_SH} -c 'echo $(( 0x5432FEDC0123 | 0x42871357BAB3 ))'
    767 
    768 	return 0
    769 }
    770 atf_test_case fiddle_bits_xor
    771 fiddle_bits_xor_head()
    772 {
    773 	atf_set "descr" "Test bitwise xor operations in arithmetic expressions"
    774 }
    775 fiddle_bits_xor_body()
    776 {
    777 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    778 		'echo $(( 0 ^ 0 ))'
    779 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    780 		'echo $(( 1 ^ 0 ))'
    781 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    782 		'echo $(( 0 ^ 1 ))'
    783 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    784 		'echo $(( 1 ^ 1 ))'
    785 
    786 	atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
    787 		'echo $(( 0xF0 ^ 0x0F ))'
    788 	atf_check -s exit:0 -o inline:'15\n' -e empty ${TEST_SH} -c \
    789 		'echo $(( 0xF0 ^ 0xFF ))'
    790 
    791 	test "${ARITH_BITS}" -ge 48 &&
    792 	    atf_check -s exit:0 -o inline:'24970630249360\n' -e empty \
    793 		${TEST_SH} -c 'echo $(( 0x5432FEDC0123 ^ 0x42871357BAB3 ))'
    794 
    795 	return 0
    796 }
    797 
    798 atf_test_case logical_and
    799 logical_and_head()
    800 {
    801 	atf_set "descr" "Test bitwise and operations in arithmetic expressions"
    802 }
    803 logical_and_body()
    804 {
    805 	# cannot test short-circuit eval until sh implements side effects...
    806 
    807 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    808 		'echo $(( 0 && 0 ))'
    809 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    810 		'echo $(( 1 && 0 ))'
    811 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    812 		'echo $(( 0 && 1 ))'
    813 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    814 		'echo $(( 1 && 1 ))'
    815 
    816 	# atf_expect_fail "PR bin/50960"
    817 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    818 		'echo $(( 0x1111 && 01234 ))'
    819 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    820 		'echo $(( 0xFFFF && 0xF0F0 ))'
    821 }
    822 atf_test_case logical_or
    823 logical_or_head()
    824 {
    825 	atf_set "descr" "Test bitwise or operations in arithmetic expressions"
    826 }
    827 logical_or_body()
    828 {
    829 	# cannot test short-circuit eval until sh implements side effects...
    830 
    831 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    832 		'echo $(( 0 || 0 ))'
    833 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    834 		'echo $(( 1 || 0 ))'
    835 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    836 		'echo $(( 0 || 1 ))'
    837 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    838 		'echo $(( 1 || 1 ))'
    839 
    840 	# atf_expect_fail "PR bin/50960"
    841 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    842 		'echo $(( 0x1111 || 01234 ))'
    843 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    844 		'echo $(( 0x33 || 0xF0F0 ))'
    845 }
    846 
    847 atf_test_case make_selection
    848 make_selection_head()
    849 {
    850 	atf_set "descr" "Test ?: operator in arithmetic expressions"
    851 }
    852 make_selection_body()
    853 {
    854 	# atf_expect_fail "PR bin/50958"
    855 
    856 	atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
    857 		'echo $(( 0 ? 2 : 3 ))'
    858 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    859 		'echo $(( 1 ? 2 : 3 ))'
    860 
    861 	atf_check -s exit:0 -o inline:'111\n' -e empty ${TEST_SH} -c \
    862 		'echo $(( 0x1234 ? 111 : 222 ))'
    863 }
    864 
    865 atf_test_case operator_precedence
    866 operator_precedence_head()
    867 {
    868 	atf_set "descr" "Test operator precedence without parentheses"
    869 }
    870 operator_precedence_body()
    871 {
    872 	# NB: apart from $(( ))  ** NO ** parentheses in the expressions.
    873 
    874 	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
    875 		'echo $(( 1 + 2 + 3 ))'
    876 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    877 		'echo $(( 1 - 2 + 3 ))'
    878 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    879 		'echo $(( 3 - 2 - 1 ))'
    880 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    881 		'echo $(( 3 - 2 + 1 ))'
    882 
    883 	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
    884 		'echo $(( - 2 + 1 ))'
    885 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    886 		'echo $(( 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:'2\n' -e empty ${TEST_SH} -c \
    891 		'echo $(( 2 + !1 ))'
    892 
    893 	atf_check -s exit:0 -o inline:'8\n' -e empty ${TEST_SH} -c \
    894 		'echo $(( 3 * 2 + 2 ))'
    895 	atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \
    896 		'echo $(( 3 + 2 * 2 ))'
    897 	atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
    898 		'echo $(( 3 * 2 * 2 ))'
    899 
    900 	atf_check -s exit:0 -o inline:'5\n' -e empty ${TEST_SH} -c \
    901 		'echo $(( 9 / 3 + 2 ))'
    902 	atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
    903 		'echo $(( 9 + 3 / 2 ))'
    904 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    905 		'echo $(( 9 / 3 / 2 ))'
    906 
    907 	atf_check -s exit:0 -o inline:'72\n' -e empty ${TEST_SH} -c \
    908 		'echo $(( 9 << 1 + 2 ))'
    909 	atf_check -s exit:0 -o inline:'48\n' -e empty ${TEST_SH} -c \
    910 		'echo $(( 9 + 3 << 2 ))'
    911 	atf_check -s exit:0 -o inline:'288\n' -e empty ${TEST_SH} -c \
    912 		'echo $(( 9 << 3 << 2 ))'
    913 
    914 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    915 		'echo $(( 9 >> 1 + 2 ))'
    916 	atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
    917 		'echo $(( 9 + 3 >> 2 ))'
    918 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    919 		'echo $(( 19 >> 3 >> 1 ))'
    920 
    921 	atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
    922 		'echo $(( 19 >> 3 << 1 ))'
    923 	atf_check -s exit:0 -o inline:'76\n' -e empty ${TEST_SH} -c \
    924 		'echo $(( 19 << 3 >> 1 ))'
    925 
    926 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    927 		'echo $(( 2 + 3 < 3 * 2 ))'
    928 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    929 		'echo $(( 2 << 3 >= 3 << 2 ))'
    930 
    931 	# sh inherits C's crazy operator precedence...
    932 
    933 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    934 		'echo $(( 0xfD & 0xF == 0xF ))'
    935 }
    936 
    937 parentheses_head()
    938 {
    939 	atf_set "descr" "Test use of () to group sub-expressions"
    940 }
    941 parentheses_body()
    942 {
    943 	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
    944 		'echo $(( (1 + 2) + 3 ))'
    945 	atf_check -s exit:0 -o inline:'-4\n' -e empty ${TEST_SH} -c \
    946 		'echo $(( 1 - (2 + 3) ))'
    947 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    948 		'echo $(( 3 - (2 - 1) ))'
    949 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    950 		'echo $(( 3 - ( 2 + 1 ) ))'
    951 
    952 	atf_check -s exit:0 -o inline:'-3\n' -e empty ${TEST_SH} -c \
    953 		'echo $(( - (2 + 1) ))'
    954 
    955 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    956 		'echo $(( ! (2 + 1) ))'
    957 
    958 	atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
    959 		'echo $(( 3 * (2 + 2) ))'
    960 	atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
    961 		'echo $(( (3 + 2) * 2 ))'
    962 	atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
    963 		'echo $(( 3 * (2 * 2) ))'
    964 
    965 	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
    966 		'echo $(( 9 / (3 + 2) ))'
    967 	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
    968 		'echo $(( ( 9 + 3 ) / 2 ))'
    969 	atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
    970 		'echo $(( 9 / ( 3 / 2 ) ))'
    971 
    972 	atf_check -s exit:0 -o inline:'20\n' -e empty ${TEST_SH} -c \
    973 		'echo $(( ( 9 << 1 ) + 2 ))'
    974 	atf_check -s exit:0 -o inline:'21\n' -e empty ${TEST_SH} -c \
    975 		'echo $(( 9 + (3 << 2) ))'
    976 	atf_check -s exit:0 -o inline:'36864\n' -e empty ${TEST_SH} -c \
    977 		'echo $(( 9 << (3 << 2) ))'
    978 
    979 	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
    980 		'echo $(( (9 >> 1) + 2 ))'
    981 	atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
    982 		'echo $(( 9 + (3 >> 2) ))'
    983 	atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
    984 		'echo $(( 19 >> (3 >> 1) ))'
    985 
    986 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    987 		'echo $(( 19 >> (3 << 1) ))'
    988 	atf_check -s exit:0 -o inline:'38\n' -e empty ${TEST_SH} -c \
    989 		'echo $(( 19 << (3 >> 1) ))'
    990 
    991 	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
    992 		'echo $(( 2 + (3 < 3) * 2 ))'
    993 	atf_check -s exit:0 -o inline:'32\n' -e empty ${TEST_SH} -c \
    994 		'echo $(( 2 << ((3 >= 3) << 2) ))'
    995 
    996 	# sh inherits C's crazy operator precedence...
    997 
    998 	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
    999 		'echo $(( (0xfD & 0xF) == 0xF ))'
   1000 }
   1001 
   1002 atf_test_case arithmetic_fails
   1003 arithmetic_fails_head()
   1004 {
   1005 	atf_set "descr" "Dummy test to force failure"
   1006 }
   1007 arithmetic_fails_body()
   1008 {
   1009 	atf_fail "Cannot estimate number of bits supported by $(( ))"
   1010 }
   1011 
   1012 atf_init_test_cases() {
   1013 
   1014 	discover_range
   1015 
   1016 	test "${ARITH_BITS}" = '?' && {
   1017 		atf_add_test_case arithmetic_fails
   1018 		return 0
   1019 	}
   1020 
   1021 	# odd names are to get atf's sort order semi-rational
   1022 
   1023 	atf_add_test_case constants
   1024 	atf_add_test_case constants_binary
   1025 	atf_add_test_case do_unary_plus
   1026 	atf_add_test_case do_unary_minus
   1027 	atf_add_test_case do_unary_not
   1028 	atf_add_test_case do_unary_tilde
   1029 	atf_add_test_case elementary_add
   1030 	atf_add_test_case elementary_sub
   1031 	atf_add_test_case elementary_mul
   1032 	atf_add_test_case elementary_div
   1033 	atf_add_test_case elementary_rem
   1034 	atf_add_test_case elementary_shl
   1035 	atf_add_test_case elementary_shr
   1036 	atf_add_test_case elementary_eq
   1037 	atf_add_test_case elementary_ne
   1038 	atf_add_test_case elementary_lt
   1039 	atf_add_test_case elementary_le
   1040 	atf_add_test_case elementary_gt
   1041 	atf_add_test_case elementary_ge
   1042 	atf_add_test_case fiddle_bits_and
   1043 	atf_add_test_case fiddle_bits_or
   1044 	atf_add_test_case fiddle_bits_xor
   1045 	atf_add_test_case logical_and
   1046 	atf_add_test_case logical_or
   1047 	atf_add_test_case make_selection
   1048 	atf_add_test_case operator_precedence
   1049 	atf_add_test_case parentheses
   1050 	# atf_add_test_case progressive			# build up big expr
   1051 	# atf_add_test_case test_errors			# erroneous input
   1052 	# atf_add_test_case torture		# hard stuff (if there is any)
   1053 	# atf_add_test_case var_assign			# assignment ops
   1054 	# atf_add_test_case vulgarity	# truly evil inputs (syntax in vars...)
   1055 }
   1056