xref: /netbsd-src/tests/bin/sh/t_arith.sh (revision 8d48762db3b5cc8b9524f0a670569c9f7fe840a0)
1*8d48762dSkre# $NetBSD: t_arith.sh,v 1.8 2017/07/15 18:50:42 kre Exp $
296320c17Schristos#
396320c17Schristos# Copyright (c) 2016 The NetBSD Foundation, Inc.
496320c17Schristos# All rights reserved.
596320c17Schristos#
696320c17Schristos# Redistribution and use in source and binary forms, with or without
796320c17Schristos# modification, are permitted provided that the following conditions
896320c17Schristos# are met:
996320c17Schristos# 1. Redistributions of source code must retain the above copyright
1096320c17Schristos#    notice, this list of conditions and the following disclaimer.
1196320c17Schristos# 2. Redistributions in binary form must reproduce the above copyright
1296320c17Schristos#    notice, this list of conditions and the following disclaimer in the
1396320c17Schristos#    documentation and/or other materials provided with the distribution.
1496320c17Schristos#
1596320c17Schristos# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1696320c17Schristos# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1796320c17Schristos# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1896320c17Schristos# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1996320c17Schristos# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2096320c17Schristos# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2196320c17Schristos# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2296320c17Schristos# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2396320c17Schristos# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2496320c17Schristos# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2596320c17Schristos# POSSIBILITY OF SUCH DAMAGE.
2696320c17Schristos#
2796320c17Schristos# the implementation of "sh" to test
2896320c17Schristos: ${TEST_SH:="/bin/sh"}
2996320c17Schristos
3096320c17Schristos# Requirement is to support at least "signed long" whatever that means
31487f18f8Schristos# (number of bits in "long" is not specified - but should be at least 32).
3296320c17Schristos
3396320c17Schristos# These tests use -o inline:"..." rather than -o match:'...' as we have
34487f18f8Schristos# only digits to examine, and it is good to be sure that 1 + 1 really gives 2
3596320c17Schristos# and that 42 or 123 don't look like success because there is a 2 in them.
3696320c17Schristos
3796320c17SchristosARITH_BITS='?'
3896320c17Schristosdiscover_range()
3996320c17Schristos{
4096320c17Schristos	# cannot use arithmetic "test" operators, range of test in
4196320c17Schristos	# ATF_SHELL (or even TEST_SH) might not be as big as that
4296320c17Schristos	# supported by $(( )) in TEST_SH
4396320c17Schristos
4496320c17Schristos	if ! ${TEST_SH} -c ': $(( 0x10000 ))' 2>/dev/null
4596320c17Schristos	then
4696320c17Schristos		# 16 bits or less, or hex unsupported, just give up...
4796320c17Schristos		return
4896320c17Schristos	fi
4996320c17Schristos	test $( ${TEST_SH} -c 'echo $(( 0x1FFFF ))' ) = 131071 || return
5096320c17Schristos
5196320c17Schristos	# when attempting to exceed the number of available bits
5296320c17Schristos	# the shell may react in any of 3 (rational) ways
5396320c17Schristos	# 1. syntax error (maybe even core dump...) and fail
5496320c17Schristos	# 2. represent a positive number input as negative value
5596320c17Schristos	# 3. keep the number positive, but not the value expected
5696320c17Schristos	#    (perhaps pegged at the max possible value)
5796320c17Schristos	# any of those may be accompanied by a message to stderr
5896320c17Schristos
5996320c17Schristos	# Must check all 3 possibilities for each plausible size
6096320c17Schristos	# Tests do not use 0x8000... because that value can have weird
6196320c17Schristos	# other side effects that are not relevant to discover here.
6296320c17Schristos	# But we do want to try and force the sign bit set.
6396320c17Schristos
6496320c17Schristos	if ! ${TEST_SH} -c ': $(( 0xC0000000 ))' 2>/dev/null
6596320c17Schristos	then
6696320c17Schristos		# proobably shell detected overflow and complained
6796320c17Schristos		ARITH_BITS=32
6896320c17Schristos		return
6996320c17Schristos	fi
7096320c17Schristos	if ${TEST_SH} 2>/dev/null \
7196320c17Schristos	    -c 'case $(( 0xC0000000 )); in (-*) exit 0;; esac; exit 1'
7296320c17Schristos	then
7396320c17Schristos		ARITH_BITS=32
7496320c17Schristos		return
7596320c17Schristos	fi
7696320c17Schristos	if ${TEST_SH} -c '[ $(( 0xC0000000 )) != 3221225472 ]' 2>/dev/null
7796320c17Schristos	then
7896320c17Schristos		ARITH_BITS=32
7996320c17Schristos		return
8096320c17Schristos	fi
8196320c17Schristos
8296320c17Schristos	if ! ${TEST_SH} -c ': $(( 0xC000000000000000 ))' 2>/dev/null
8396320c17Schristos	then
8496320c17Schristos		ARITH_BITS=64
8596320c17Schristos		return
8696320c17Schristos	fi
8796320c17Schristos	if ${TEST_SH} 2>/dev/null \
8896320c17Schristos	    -c 'case $(( 0xC000000000000000 )); in (-*) exit 0;; esac; exit 1'
8996320c17Schristos	then
9096320c17Schristos		ARITH_BITS=64
9196320c17Schristos		return
9296320c17Schristos	fi
9396320c17Schristos	if ${TEST_SH} 2>/dev/null \
9496320c17Schristos	    -c '[ $((0xC000000000000000)) != 13835058055282163712 ]'
9596320c17Schristos	then
9696320c17Schristos		ARITH_BITS=64
9796320c17Schristos		return
9896320c17Schristos	fi
9996320c17Schristos
10096320c17Schristos	if ${TEST_SH} 2>/dev/null -c \
10196320c17Schristos	   '[ $((0x123456781234567812345678)) = 5634002657842756053938493048 ]'
10296320c17Schristos	then
10396320c17Schristos		# just assume... (for now anyway, revisit when it happens...)
10496320c17Schristos		ARITH_BITS=96
10596320c17Schristos		return
10696320c17Schristos	fi
10796320c17Schristos}
10896320c17Schristos
10996320c17Schristosatf_test_case constants
11096320c17Schristosconstants_head()
11196320c17Schristos{
11296320c17Schristos        atf_set "descr" "Tests that arithmetic expansion can handle constants"
11396320c17Schristos}
11496320c17Schristosconstants_body()
11596320c17Schristos{
11696320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
11796320c17Schristos		'echo $(( 1 ))'
11896320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
11996320c17Schristos		'echo $(( 0 ))'
12096320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
12196320c17Schristos		'echo $((0x0))'
12296320c17Schristos
12396320c17Schristos	# atf_expect_fail "PR bin/50959"
12496320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
12596320c17Schristos		'echo $((0X0))'
12696320c17Schristos	# atf_expect_pass
12796320c17Schristos
12896320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
12996320c17Schristos		'echo $((000))'
13096320c17Schristos
13196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty \
13296320c17Schristos		${TEST_SH} -c 'echo $(( 000000001 ))'
13396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty \
13496320c17Schristos		${TEST_SH} -c 'echo $(( 0x000000 ))'
13596320c17Schristos
13696320c17Schristos	atf_check -s exit:0 -o inline:'99999\n' -e empty \
13796320c17Schristos		${TEST_SH} -c 'echo $((99999))'
13896320c17Schristos
13996320c17Schristos	[ ${ARITH_BITS} -gt 44 ] &&
14096320c17Schristos		atf_check -s exit:0 -o inline:'9191919191919\n' -e empty \
14196320c17Schristos			${TEST_SH} -c 'echo $((9191919191919))'
14296320c17Schristos
14396320c17Schristos	atf_check -s exit:0 -o inline:'13\n' -e empty ${TEST_SH} -c \
14496320c17Schristos		'echo $(( 0xD ))'
14596320c17Schristos	atf_check -s exit:0 -o inline:'11\n' -e empty ${TEST_SH} -c \
14696320c17Schristos		'echo $(( 013 ))'
14796320c17Schristos	atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \
14896320c17Schristos		'x=7;echo $(($x))'
14996320c17Schristos	atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
15096320c17Schristos		'x=9;echo $((x))'
15196320c17Schristos
15296320c17Schristos	atf_check -s exit:0 -o inline:'11\n' -e empty \
15396320c17Schristos		${TEST_SH} -c 'x=0xB; echo $(( $x ))'
15496320c17Schristos	atf_check -s exit:0 -o inline:'27\n' -e empty \
15596320c17Schristos		${TEST_SH} -c 'x=0X1B; echo $(( x ))'
15696320c17Schristos	atf_check -s exit:0 -o inline:'27\n' -e empty \
15796320c17Schristos		${TEST_SH} -c 'X=033; echo $(( $X ))'
15896320c17Schristos	atf_check -s exit:0 -o inline:'219\n' -e empty \
15996320c17Schristos		${TEST_SH} -c 'X=0333; echo $(( X ))'
16096320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty \
16196320c17Schristos		${TEST_SH} -c 'NULL=; echo $(( NULL ))'
16296320c17Schristos
16396320c17Schristos	# Not clear if this is 0, nothing, or an error, so omit for now
16496320c17Schristos	# atf_check -s exit:0 -o inline:'0\n' -e empty \
16596320c17Schristos	# 	${TEST_SH} -c 'echo $(( ))'
16696320c17Schristos
16796320c17Schristos	# not clear whether this should return 0 or an error, so omit for now
16896320c17Schristos	# atf_check -s exit:0 -o inline:'0\n' -e empty \
16996320c17Schristos	# 	${TEST_SH} -c 'echo $(( UNDEFINED_VAR ))'
17096320c17Schristos}
17196320c17Schristos
17296320c17Schristos
17396320c17Schristosatf_test_case do_unary_plus
17496320c17Schristosdo_unary_plus_head()
17596320c17Schristos{
17696320c17Schristos        atf_set "descr" "Tests that unary plus works as expected"
17796320c17Schristos}
17896320c17Schristosdo_unary_plus_body()
17996320c17Schristos{
18096320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
18196320c17Schristos		'echo $(( +0 ))'
18296320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
18396320c17Schristos		'echo $(( +1 ))'
18496320c17Schristos	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
18596320c17Schristos		'echo $(( + 6 ))'
18696320c17Schristos	atf_check -s exit:0 -o inline:'4321\n' -e empty ${TEST_SH} -c \
18796320c17Schristos		'echo $(( + 4321 ))'
18896320c17Schristos	atf_check -s exit:0 -o inline:'17185\n' -e empty ${TEST_SH} -c \
18996320c17Schristos		'echo $(( + 0x4321 ))'
19096320c17Schristos}
19196320c17Schristos
19296320c17Schristosatf_test_case do_unary_minus
19396320c17Schristosdo_unary_minus_head()
19496320c17Schristos{
19596320c17Schristos        atf_set "descr" "Tests that unary minus works as expected"
19696320c17Schristos}
19796320c17Schristosdo_unary_minus_body()
19896320c17Schristos{
19996320c17Schristos	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
20096320c17Schristos		'echo $(( -1 ))'
20196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
20296320c17Schristos		'echo $(( - 0 ))'
20396320c17Schristos	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
20496320c17Schristos		'echo $(( - 1 ))'
20596320c17Schristos	atf_check -s exit:0 -o inline:'-6\n' -e empty ${TEST_SH} -c \
20696320c17Schristos		'echo $(( - 6 ))'
20796320c17Schristos	atf_check -s exit:0 -o inline:'-4321\n' -e empty ${TEST_SH} -c \
20896320c17Schristos		'echo $(( - 4321 ))'
20996320c17Schristos	atf_check -s exit:0 -o inline:'-2257\n' -e empty ${TEST_SH} -c \
21096320c17Schristos		'echo $(( - 04321 ))'
21196320c17Schristos	atf_check -s exit:0 -o inline:'-7\n' -e empty ${TEST_SH} -c \
21296320c17Schristos		'echo $((-7))'
21396320c17Schristos}
21496320c17Schristos
21596320c17Schristosatf_test_case do_unary_not
21696320c17Schristosdo_unary_not_head()
21796320c17Schristos{
21896320c17Schristos        atf_set "descr" "Tests that unary not (boolean) works as expected"
21996320c17Schristos}
22096320c17Schristosdo_unary_not_body()
22196320c17Schristos{
22296320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
22396320c17Schristos		'echo $(( ! 1 ))'
22496320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
22596320c17Schristos		'echo $(( ! 0 ))'
22696320c17Schristos
22796320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
22896320c17Schristos		'echo $(( !1234 ))'
22996320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
23096320c17Schristos		'echo $(( !0xFFFF ))'
23196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
23296320c17Schristos		'echo $(( ! 000000 ))'
23396320c17Schristos}
23496320c17Schristos
23596320c17Schristosatf_test_case do_unary_tilde
23696320c17Schristosdo_unary_tilde_head()
23796320c17Schristos{
23896320c17Schristos        atf_set "descr" "Tests that unary not (bitwise) works as expected"
23996320c17Schristos}
24096320c17Schristosdo_unary_tilde_body()
24196320c17Schristos{
24296320c17Schristos	# definitely 2's complement arithmetic here...
24396320c17Schristos
24496320c17Schristos	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
24596320c17Schristos		'echo $(( ~ 0 ))'
24696320c17Schristos	atf_check -s exit:0 -o inline:'-2\n' -e empty ${TEST_SH} -c \
24796320c17Schristos		'echo $(( ~ 1 ))'
24896320c17Schristos
24996320c17Schristos	atf_check -s exit:0 -o inline:'-1235\n' -e empty ${TEST_SH} -c \
25096320c17Schristos		'echo $(( ~1234 ))'
25196320c17Schristos	atf_check -s exit:0 -o inline:'-256\n' -e empty ${TEST_SH} -c \
25296320c17Schristos		'echo $(( ~0xFF ))'
25396320c17Schristos}
25496320c17Schristos
25596320c17Schristosatf_test_case elementary_add
25696320c17Schristoselementary_add_head()
25796320c17Schristos{
25896320c17Schristos        atf_set "descr" "Tests that simple addition works as expected"
25996320c17Schristos}
26096320c17Schristoselementary_add_body()
26196320c17Schristos{
26296320c17Schristos	# some of these tests actually test unary ops &  op precedence...
26396320c17Schristos
26496320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
26596320c17Schristos		'echo $(( 0 + 0 ))'
26696320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
26796320c17Schristos		'echo $(( 1 + 0 ))'
26896320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
26996320c17Schristos		'echo $(( 0 + 1 ))'
27096320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
27196320c17Schristos		'echo $(( 1 + 1 ))'
27296320c17Schristos	atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
27396320c17Schristos		'echo $(( 4 + 6 ))'
27496320c17Schristos	atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
27596320c17Schristos		'echo $(( 6 + 4 ))'
27696320c17Schristos	atf_check -s exit:0 -o inline:'5555\n' -e empty ${TEST_SH} -c \
27796320c17Schristos		'echo $(( 1234 + 4321 ))'
27896320c17Schristos	atf_check -s exit:0 -o inline:'3333\n' -e empty ${TEST_SH} -c \
27996320c17Schristos		'echo $((1111+2222))'
28096320c17Schristos	atf_check -s exit:0 -o inline:'5555\n' -e empty ${TEST_SH} -c \
28196320c17Schristos		'echo $((+3333+2222))'
28296320c17Schristos	atf_check -s exit:0 -o inline:'7777\n' -e empty ${TEST_SH} -c \
28396320c17Schristos		'echo $((+3333 + +4444))'
28496320c17Schristos	atf_check -s exit:0 -o inline:'-7777\n' -e empty ${TEST_SH} -c \
28596320c17Schristos		'echo -$((+4125+ +3652))'
28696320c17Schristos}
28796320c17Schristos
28896320c17Schristosatf_test_case elementary_sub
28996320c17Schristoselementary_sub_head()
29096320c17Schristos{
29196320c17Schristos        atf_set "descr" "Tests that simple subtraction works as expected"
29296320c17Schristos}
29396320c17Schristoselementary_sub_body()
29496320c17Schristos{
29596320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
29696320c17Schristos		'echo $(( 0 - 0 ))'
29796320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
29896320c17Schristos		'echo $(( 1 - 0 ))'
29996320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
30096320c17Schristos		'echo $(( 1 - 1 ))'
30196320c17Schristos	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
30296320c17Schristos		'echo $(( 0 - 1 ))'
30396320c17Schristos	atf_check -s exit:0 -o inline:'488\n' -e empty ${TEST_SH} -c \
30496320c17Schristos		'echo $(( 1066 - 578 ))'
30596320c17Schristos	atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
30696320c17Schristos		'echo $(( 2016-5678 ))'
30796320c17Schristos	atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
30896320c17Schristos		'echo $(( 2016+-5678 ))'
30996320c17Schristos	atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \
31096320c17Schristos		'echo $(( 2016-+5678 ))'
31196320c17Schristos	atf_check -s exit:0 -o inline:'-7694\n' -e empty ${TEST_SH} -c \
31296320c17Schristos		'echo $(( -2016-5678 ))'
31396320c17Schristos	atf_check -s exit:0 -o inline:'--1\n' -e empty ${TEST_SH} -c \
31496320c17Schristos		'echo -$(( -1018 - -1017 ))'
31596320c17Schristos}
31696320c17Schristos
31796320c17Schristosatf_test_case elementary_mul
31896320c17Schristoselementary_mul_head()
31996320c17Schristos{
32096320c17Schristos        atf_set "descr" "Tests that simple multiplication works as expected"
32196320c17Schristos}
32296320c17Schristoselementary_mul_body()
32396320c17Schristos{
32496320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
32596320c17Schristos		'echo $(( 0 * 0 ))'
32696320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
32796320c17Schristos		'echo $(( 1 * 0 ))'
32896320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
32996320c17Schristos		'echo $(( 0 * 1 ))'
33096320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
33196320c17Schristos		'echo $(( 1 * 1 ))'
33296320c17Schristos	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
33396320c17Schristos		'echo $(( -1 * 1 ))'
33496320c17Schristos	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
33596320c17Schristos		'echo $(( 1 * -1 ))'
33696320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
33796320c17Schristos		'echo $(( -1 * -1 ))'
33896320c17Schristos	atf_check -s exit:0 -o inline:'391\n' -e empty ${TEST_SH} -c \
33996320c17Schristos		'echo $(( 17 * 23 ))'
34096320c17Schristos	atf_check -s exit:0 -o inline:'169\n' -e empty ${TEST_SH} -c \
34196320c17Schristos		'echo $(( 13*13 ))'
34296320c17Schristos	atf_check -s exit:0 -o inline:'-11264\n' -e empty ${TEST_SH} -c \
34396320c17Schristos		'echo $(( -11 *1024 ))'
34496320c17Schristos	atf_check -s exit:0 -o inline:'-16983\n' -e empty ${TEST_SH} -c \
34596320c17Schristos		'echo $(( 17* -999 ))'
34696320c17Schristos	atf_check -s exit:0 -o inline:'9309\n' -e empty ${TEST_SH} -c \
34796320c17Schristos		'echo $(( -29*-321 ))'
34896320c17Schristos}
34996320c17Schristos
35096320c17Schristosatf_test_case elementary_div
35196320c17Schristoselementary_div_head()
35296320c17Schristos{
35396320c17Schristos        atf_set "descr" "Tests that simple division works as expected"
35496320c17Schristos}
35596320c17Schristoselementary_div_body()
35696320c17Schristos{
35796320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
35896320c17Schristos		'echo $(( 0 / 1 ))'
35996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
36096320c17Schristos		'echo $(( 1 / 1 ))'
36196320c17Schristos	test ${ARITH_BITS} -ge 38 &&
36296320c17Schristos	    atf_check -s exit:0 -o inline:'99999999999\n' -e empty \
36396320c17Schristos		${TEST_SH} -c 'echo $(( 99999999999 / 1 ))'
36496320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
36596320c17Schristos		'echo $(( 2 / 1 ))'
36696320c17Schristos
36796320c17Schristos	atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
36896320c17Schristos		'echo $(( 3 / 1 ))'
36996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
37096320c17Schristos		'echo $(( 3 / 2 ))'
37196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
37296320c17Schristos		'echo $(( 3 / 3 ))'
37396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
37496320c17Schristos		'echo $(( 3 / 4 ))'
37596320c17Schristos
37696320c17Schristos	atf_check -s exit:0 -o inline:'173\n' -e empty ${TEST_SH} -c \
37796320c17Schristos		'echo $(( 123456 / 713 ))'
37896320c17Schristos	atf_check -s exit:0 -o inline:'13\n' -e empty ${TEST_SH} -c \
37996320c17Schristos		'echo $(( 169 / 13 ))'
38096320c17Schristos}
38196320c17Schristos
38296320c17Schristosatf_test_case elementary_rem
38396320c17Schristoselementary_rem_head()
38496320c17Schristos{
38596320c17Schristos        atf_set "descr" "Tests that simple modulus works as expected"
38696320c17Schristos}
38796320c17Schristoselementary_rem_body()
38896320c17Schristos{
38996320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
39096320c17Schristos		'echo $(( 0 % 1 ))'
39196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
39296320c17Schristos		'echo $(( 1 % 1 ))'
39396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
39496320c17Schristos		'echo $(( 2 % 1 ))'
39596320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
39696320c17Schristos		'echo $(( 9999 % 1 ))'
39796320c17Schristos
39896320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
39996320c17Schristos		'echo $(( 0 % 2 ))'
40096320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
40196320c17Schristos		'echo $(( 1 % 2 ))'
40296320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
40396320c17Schristos		'echo $(( 2 % 2 ))'
40496320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
40596320c17Schristos		'echo $(( 0xFFFF % 2 ))'
40696320c17Schristos
40796320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
40896320c17Schristos		'echo $(( 0 % 3 ))'
40996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
41096320c17Schristos		'echo $(( 1 % 3 ))'
41196320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
41296320c17Schristos		'echo $(( 2 % 3 ))'
41396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
41496320c17Schristos		'echo $(( 3 % 3 ))'
41596320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
41696320c17Schristos		'echo $(( 3123 % 3 ))'
41796320c17Schristos
41896320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
41996320c17Schristos		'echo $(( 9999 % 2 ))'
42096320c17Schristos
42196320c17Schristos	atf_check -s exit:0 -o inline:'107\n' -e empty ${TEST_SH} -c \
42296320c17Schristos		'echo $(( 123456%173 ))'
42396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
42496320c17Schristos		'echo $((169%13))'
42596320c17Schristos}
42696320c17Schristos
42796320c17Schristosatf_test_case elementary_shl
42896320c17Schristoselementary_shl_head()
42996320c17Schristos{
430487f18f8Schristos        atf_set "descr" "Tests that simple shift left works as expected"
43196320c17Schristos}
43296320c17Schristoselementary_shl_body()
43396320c17Schristos{
43496320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
43596320c17Schristos		'echo $(( 0 << 0 ))'
43696320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
43796320c17Schristos		'echo $(( 0 << 1 ))'
43896320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
43996320c17Schristos		'echo $(( 0 << 17 ))'
44096320c17Schristos
44196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
44296320c17Schristos		'echo $(( 1 << 0 ))'
44396320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
44496320c17Schristos		'echo $(( 1 << 1 ))'
44596320c17Schristos	atf_check -s exit:0 -o inline:'131072\n' -e empty ${TEST_SH} -c \
44696320c17Schristos		'echo $(( 1 << 17 ))'
44796320c17Schristos
44896320c17Schristos	atf_check -s exit:0 -o inline:'2021161080\n' -e empty ${TEST_SH} -c \
44996320c17Schristos		'echo $(( 0x3C3C3C3C << 1 ))'
45096320c17Schristos
45196320c17Schristos	test "${ARITH_BITS}" -ge 40 &&
45296320c17Schristos	    atf_check -s exit:0 -o inline:'129354309120\n' -e empty \
45396320c17Schristos		${TEST_SH} -c 'echo $(( 0x3C3C3C3C << 7 ))'
45496320c17Schristos	test "${ARITH_BITS}" -ge 72 &&
45596320c17Schristos	    atf_check -s exit:0 -o inline:'1111145054534149079040\n' \
45696320c17Schristos		-e empty ${TEST_SH} -c 'echo $(( 0x3C3C3C3C << 40 ))'
45796320c17Schristos
45896320c17Schristos	return 0
45996320c17Schristos}
46096320c17Schristos
46196320c17Schristosatf_test_case elementary_shr
46296320c17Schristoselementary_shr_head()
46396320c17Schristos{
464487f18f8Schristos        atf_set "descr" "Tests that simple shift right works as expected"
46596320c17Schristos}
46696320c17Schristoselementary_shr_body()
46796320c17Schristos{
46896320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
46996320c17Schristos		'echo $(( 0 >> 0 ))'
47096320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
47196320c17Schristos		'echo $(( 0 >> 1 ))'
47296320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
47396320c17Schristos		'echo $(( 0 >> 17 ))'
47496320c17Schristos
47596320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
47696320c17Schristos		'echo $(( 1 >> 0 ))'
47796320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
47896320c17Schristos		'echo $(( 1 >> 1 ))'
47996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
48096320c17Schristos		'echo $(( 2 >> 1 ))'
48196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
48296320c17Schristos		'echo $(( 3 >> 1 ))'
48396320c17Schristos
48496320c17Schristos	atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
48596320c17Schristos		'echo $(( 0x10 >> 2 ))'
48696320c17Schristos	atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
48796320c17Schristos		'echo $(( 022 >> 2 ))'
48896320c17Schristos
48996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
49096320c17Schristos		'echo $(( 131072 >> 17 ))'
49196320c17Schristos
49296320c17Schristos	test ${ARITH_BITS} -ge 40 &&
49396320c17Schristos		atf_check -s exit:0 -o inline:'8\n' -e empty ${TEST_SH} -c \
49496320c17Schristos			'echo $(( 0x4000000000 >> 35 ))'
49596320c17Schristos	test ${ARITH_BITS} -ge 80 &&
49696320c17Schristos		atf_check -s exit:0 -o inline:'4464\n' -e empty ${TEST_SH} -c \
49796320c17Schristos			'echo $(( 0x93400FACE005C871000 >> 64 ))'
49896320c17Schristos
49996320c17Schristos	return 0
50096320c17Schristos}
50196320c17Schristos
50296320c17Schristosatf_test_case elementary_eq
50396320c17Schristoselementary_eq_head()
50496320c17Schristos{
50596320c17Schristos        atf_set "descr" "Tests that simple equality test works as expected"
50696320c17Schristos}
50796320c17Schristoselementary_eq_body()
50896320c17Schristos{
50996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
51096320c17Schristos		'echo $(( 0 == 0 ))'
51196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
51296320c17Schristos		'echo $(( 0 == 0000 ))'
51396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
51496320c17Schristos		'echo $(( 0 == 0x00 ))'
51596320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
51696320c17Schristos		'echo $(( 1 == 1 ))'
51796320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
51896320c17Schristos		'X=30; Y=0x1E; echo $(( X == Y ))'
51996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
52096320c17Schristos		'echo $(( 0x1234 == 4660 ))'
52196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
52296320c17Schristos		'echo $(( 0x1234 == 011064 ))'
52396320c17Schristos
52496320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
52596320c17Schristos		'echo $(( 0 == 1 ))'
52696320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
52796320c17Schristos		'echo $(( 0 == 0000000000000001 ))'
52896320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
52996320c17Schristos		'echo $(( 0 == 0x10000000000000 ))'
53096320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
53196320c17Schristos		'echo $(( 1 == 2 ))'
53296320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
53396320c17Schristos		'X=3; Y=7; echo $(( X == Y ))'
53496320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
53596320c17Schristos		'echo $(( 1234 == 0x4660 ))'
53696320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
53796320c17Schristos		'echo $(( 01234 == 0x11064 ))'
53896320c17Schristos}
53996320c17Schristosatf_test_case elementary_ne
54096320c17Schristoselementary_ne_head()
54196320c17Schristos{
54296320c17Schristos        atf_set "descr" "Tests that simple inequality test works as expected"
54396320c17Schristos}
54496320c17Schristoselementary_ne_body()
54596320c17Schristos{
54696320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
54796320c17Schristos		'echo $(( 1 != 0 ))'
54896320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
54996320c17Schristos		'echo $(( 0x71 != 17 ))'
55096320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
55196320c17Schristos		'echo $(( 1234 != 01234 ))'
55296320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
55396320c17Schristos		'echo $(( 0x1234 != 01234 ))'
55496320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
55596320c17Schristos		'X=3; echo $(( X != 0 ))'
55696320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
55796320c17Schristos		'X=3; Y=0x11; echo $(( X != Y ))'
55896320c17Schristos
55996320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
56096320c17Schristos		'echo $(( 3 != 3 ))'
56196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
56296320c17Schristos		'echo $(( 0 != 0x0 ))'
56396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
56496320c17Schristos		'echo $(( 0xA != 012 ))'
56596320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
56696320c17Schristos		'X=1; echo $(( X != 1 ))'
56796320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
56896320c17Schristos		'X=0xC; Y=014; echo $(( X != Y ))'
56996320c17Schristos}
57096320c17Schristosatf_test_case elementary_lt
57196320c17Schristoselementary_lt_head()
57296320c17Schristos{
57396320c17Schristos        atf_set "descr" "Tests that simple less than test works as expected"
57496320c17Schristos}
57596320c17Schristoselementary_lt_body()
57696320c17Schristos{
57796320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
57896320c17Schristos		'echo $(( 0 < 1 ))'
57996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
58096320c17Schristos		'echo $(( -1 < 0 ))'
58196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
58296320c17Schristos		'echo $(( 0 < 10 ))'
58396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
58496320c17Schristos		'echo $(( 100 < 101 ))'
58596320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
58696320c17Schristos		'echo $(( 0xA1 < 200 ))'
58796320c17Schristos
58896320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
58996320c17Schristos		'echo $(( 0 < 0 ))'
59096320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
59196320c17Schristos		'echo $(( 1 < 0 ))'
59296320c17Schristos
59396320c17Schristos	test ${ARITH_BITS} -ge 40 &&
59496320c17Schristos	    atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
59596320c17Schristos		'echo $(( 0x1BEEFF00D < 0x1FACECAFE ))'
59696320c17Schristos
59796320c17Schristos	return 0
59896320c17Schristos}
59996320c17Schristosatf_test_case elementary_le
60096320c17Schristoselementary_le_head()
60196320c17Schristos{
60296320c17Schristos        atf_set "descr" "Tests that simple less or equal test works as expected"
60396320c17Schristos}
60496320c17Schristoselementary_le_body()
60596320c17Schristos{
60696320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
60796320c17Schristos		'echo $(( 0 <= 1 ))'
60896320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
60996320c17Schristos		'echo $(( -1 <= 0 ))'
61096320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
61196320c17Schristos		'echo $(( 0 <= 0 ))'
61296320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
61396320c17Schristos		'echo $(( 0 <= 10 ))'
61496320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
61596320c17Schristos		'echo $(( 100 <= 101 ))'
61696320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
61796320c17Schristos		'echo $(( 0xA1 <= 161 ))'
61896320c17Schristos
61996320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
62096320c17Schristos		'echo $(( 1 <= 0 ))'
62196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
62296320c17Schristos		'echo $(( -100 <= -200 ))'
62396320c17Schristos
62496320c17Schristos	test ${ARITH_BITS} -ge 40 &&
62596320c17Schristos	    atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
62696320c17Schristos		'cost=; AUD=; echo $(( $cost 0x2FEEDBABE <= $AUD 12866927294 ))'
62796320c17Schristos
62896320c17Schristos	return 0
62996320c17Schristos}
63096320c17Schristosatf_test_case elementary_gt
63196320c17Schristoselementary_gt_head()
63296320c17Schristos{
63396320c17Schristos        atf_set "descr" "Tests that simple greater than works as expected"
63496320c17Schristos}
63596320c17Schristoselementary_gt_body()
63696320c17Schristos{
63796320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
63896320c17Schristos		'echo $(( 1 > 0 ))'
63996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
64096320c17Schristos		'echo $(( 1 > -1 ))'
64196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
64296320c17Schristos		'echo $(( 11 > 012 ))'
64396320c17Schristos
64496320c17Schristos	# atf_expect_fail "PR bin/50959"
64596320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
64696320c17Schristos		'echo $(( 2147483647 > 0X7FFFFF0 ))'
64796320c17Schristos	# atf_expect_pass
64896320c17Schristos
64996320c17Schristos	test ${ARITH_BITS} -gt 32 &&
65096320c17Schristos	    atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
65196320c17Schristos		'echo $(( 0x80000000 > 0x7FFFFFFF ))'
65296320c17Schristos
65396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
65496320c17Schristos		'echo $(( 0 > 0 ))'
65596320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
65696320c17Schristos		'echo $(( 0 > 1 ))'
65796320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
65896320c17Schristos		'echo $(( -1 > 0 ))'
65996320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
66096320c17Schristos		'echo $(( 0 > 10 ))'
66196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
66296320c17Schristos		'echo $(( 2015 > 2016 ))'
66396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
66496320c17Schristos		'echo $(( 0xA1 > 200 ))'
66596320c17Schristos
66696320c17Schristos	test ${ARITH_BITS} -ge 44 &&
66796320c17Schristos	    atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
66896320c17Schristos		'echo $(( 0x7F07F07F0 > 34099628014 ))'
66996320c17Schristos
67096320c17Schristos	return 0
67196320c17Schristos}
67296320c17Schristosatf_test_case elementary_ge
67396320c17Schristoselementary_ge_head()
67496320c17Schristos{
67596320c17Schristos        atf_set "descr" "Tests that simple greater or equal works as expected"
67696320c17Schristos}
67796320c17Schristoselementary_ge_body()
67896320c17Schristos{
67996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
68096320c17Schristos		'echo $(( 0 >= 0 ))'
68196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
68296320c17Schristos		'echo $(( 1 >= 0 ))'
68396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
68496320c17Schristos		'echo $(( -100 >= -101 ))'
68596320c17Schristos
68696320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
68796320c17Schristos		'echo $(( -1 >= 0 ))'
68896320c17Schristos}
68996320c17Schristos
69096320c17Schristosatf_test_case fiddle_bits_and
69196320c17Schristosfiddle_bits_and_head()
69296320c17Schristos{
69396320c17Schristos	atf_set "descr" "Test bitwise and operations in arithmetic expressions"
69496320c17Schristos}
69596320c17Schristosfiddle_bits_and_body()
69696320c17Schristos{
69796320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
69896320c17Schristos		'echo $(( 0 & 0 ))'
69996320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
70096320c17Schristos		'echo $(( 1 & 0 ))'
70196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
70296320c17Schristos		'echo $(( 0 & 1 ))'
70396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
70496320c17Schristos		'echo $(( 1 & 1 ))'
70596320c17Schristos
70696320c17Schristos	atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
70796320c17Schristos		'echo $(( 0xFF & 0xFF ))'
70896320c17Schristos	atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
70996320c17Schristos		'echo $(( 0xFFFF & 0377 ))'
71096320c17Schristos
71196320c17Schristos	test "${ARITH_BITS}" -ge 48 &&
71296320c17Schristos	    atf_check -s exit:0 -o inline:'70377641607203\n' -e empty \
71396320c17Schristos		${TEST_SH} -c 'echo $(( 0x5432FEDC0123 & 0x42871357BAB3 ))'
71496320c17Schristos
71596320c17Schristos	return 0
71696320c17Schristos}
71796320c17Schristosatf_test_case fiddle_bits_or
71896320c17Schristosfiddle_bits_or_head()
71996320c17Schristos{
72096320c17Schristos	atf_set "descr" "Test bitwise or operations in arithmetic expressions"
72196320c17Schristos}
72296320c17Schristosfiddle_bits_or_body()
72396320c17Schristos{
72496320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
72596320c17Schristos		'echo $(( 0 | 0 ))'
72696320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
72796320c17Schristos		'echo $(( 1 | 0 ))'
72896320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
72996320c17Schristos		'echo $(( 0 | 1 ))'
73096320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
73196320c17Schristos		'echo $(( 1 | 1 ))'
73296320c17Schristos
73396320c17Schristos	atf_check -s exit:0 -o inline:'4369\n' -e empty ${TEST_SH} -c \
73496320c17Schristos		'echo $(( 0x1111 | 0x1111 ))'
73596320c17Schristos	atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
73696320c17Schristos		'echo $(( 0xAA | 0125 ))'
73796320c17Schristos
73896320c17Schristos	test "${ARITH_BITS}" -ge 48 &&
73996320c17Schristos	    atf_check -s exit:0 -o inline:'95348271856563\n' -e empty \
74096320c17Schristos		${TEST_SH} -c 'echo $(( 0x5432FEDC0123 | 0x42871357BAB3 ))'
74196320c17Schristos
74296320c17Schristos	return 0
74396320c17Schristos}
74496320c17Schristosatf_test_case fiddle_bits_xor
74596320c17Schristosfiddle_bits_xor_head()
74696320c17Schristos{
74796320c17Schristos	atf_set "descr" "Test bitwise xor operations in arithmetic expressions"
74896320c17Schristos}
74996320c17Schristosfiddle_bits_xor_body()
75096320c17Schristos{
75196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
75296320c17Schristos		'echo $(( 0 ^ 0 ))'
75396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
75496320c17Schristos		'echo $(( 1 ^ 0 ))'
75596320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
75696320c17Schristos		'echo $(( 0 ^ 1 ))'
75796320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
75896320c17Schristos		'echo $(( 1 ^ 1 ))'
75996320c17Schristos
76096320c17Schristos	atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \
76196320c17Schristos		'echo $(( 0xF0 ^ 0x0F ))'
76296320c17Schristos	atf_check -s exit:0 -o inline:'15\n' -e empty ${TEST_SH} -c \
76396320c17Schristos		'echo $(( 0xF0 ^ 0xFF ))'
76496320c17Schristos
76596320c17Schristos	test "${ARITH_BITS}" -ge 48 &&
76696320c17Schristos	    atf_check -s exit:0 -o inline:'24970630249360\n' -e empty \
76796320c17Schristos		${TEST_SH} -c 'echo $(( 0x5432FEDC0123 ^ 0x42871357BAB3 ))'
76896320c17Schristos
76996320c17Schristos	return 0
77096320c17Schristos}
77196320c17Schristos
77296320c17Schristosatf_test_case logical_and
77396320c17Schristoslogical_and_head()
77496320c17Schristos{
775487f18f8Schristos	atf_set "descr" "Test logical and operations in arithmetic expressions"
77696320c17Schristos}
77796320c17Schristoslogical_and_body()
77896320c17Schristos{
77996320c17Schristos	# cannot test short-circuit eval until sh implements side effects...
78096320c17Schristos
78196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
78296320c17Schristos		'echo $(( 0 && 0 ))'
78396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
78496320c17Schristos		'echo $(( 1 && 0 ))'
78596320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
78696320c17Schristos		'echo $(( 0 && 1 ))'
78796320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
78896320c17Schristos		'echo $(( 1 && 1 ))'
78996320c17Schristos
79096320c17Schristos	# atf_expect_fail "PR bin/50960"
79196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
79296320c17Schristos		'echo $(( 0x1111 && 01234 ))'
79396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
79496320c17Schristos		'echo $(( 0xFFFF && 0xF0F0 ))'
79596320c17Schristos}
79696320c17Schristosatf_test_case logical_or
79796320c17Schristoslogical_or_head()
79896320c17Schristos{
799487f18f8Schristos	atf_set "descr" "Test logical or operations in arithmetic expressions"
80096320c17Schristos}
80196320c17Schristoslogical_or_body()
80296320c17Schristos{
80396320c17Schristos	# cannot test short-circuit eval until sh implements side effects...
80496320c17Schristos
80596320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
80696320c17Schristos		'echo $(( 0 || 0 ))'
80796320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
80896320c17Schristos		'echo $(( 1 || 0 ))'
80996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
81096320c17Schristos		'echo $(( 0 || 1 ))'
81196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
81296320c17Schristos		'echo $(( 1 || 1 ))'
81396320c17Schristos
81496320c17Schristos	# atf_expect_fail "PR bin/50960"
81596320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
81696320c17Schristos		'echo $(( 0x1111 || 01234 ))'
81796320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
81896320c17Schristos		'echo $(( 0x33 || 0xF0F0 ))'
81996320c17Schristos}
82096320c17Schristos
821f0acc68eSkreatf_test_case nested_arith
822f0acc68eSkrenested_arith_head()
823f0acc68eSkre{
824f0acc68eSkre	atf_set "descr" 'Test nested arithmetic $(( $(( )) ))'
825f0acc68eSkre}
826f0acc68eSkrenested_arith_body()
827f0acc68eSkre{
828f0acc68eSkre	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
829f0acc68eSkre		'echo $(( $(( 0 )) ))'
830f0acc68eSkre	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
831f0acc68eSkre		'echo $(( 1 + $(( 2 - 2 )) ))'
832f0acc68eSkre	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
833f0acc68eSkre		'echo $(( $(( 3 / 3 )) + $((1*1*1)) - $(( 7 % 6 ))))'
834f0acc68eSkre	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
835f0acc68eSkre		'echo $(($(($(($(($((1))))))))))'
836f0acc68eSkre
837f0acc68eSkre	atf_check -s exit:0 -o inline:'246\n' -e empty ${TEST_SH} -c \
838f0acc68eSkre		'echo $(( 2$((2 * 2))6 ))'
839f0acc68eSkre	atf_check -s exit:0 -o inline:'291117\n' -e empty ${TEST_SH} -c \
840f0acc68eSkre		'echo $(( $((1 + 1))$((3 * 3))$(( 99-88 ))$(( 17))))'
841f0acc68eSkre	atf_check -s exit:0 -o inline:'123456789\n' -e empty ${TEST_SH} -c \
842f0acc68eSkre	  'echo $(( 1$((2$((1+2))4$((2 + 2 + 1))6))7$((4 * 2))$(($((81/9))))))'
843f0acc68eSkre}
844f0acc68eSkre
84596320c17Schristosatf_test_case make_selection
84696320c17Schristosmake_selection_head()
84796320c17Schristos{
84896320c17Schristos	atf_set "descr" "Test ?: operator in arithmetic expressions"
84996320c17Schristos}
85096320c17Schristosmake_selection_body()
85196320c17Schristos{
85296320c17Schristos	# atf_expect_fail "PR bin/50958"
85396320c17Schristos
85496320c17Schristos	atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
85596320c17Schristos		'echo $(( 0 ? 2 : 3 ))'
85696320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
85796320c17Schristos		'echo $(( 1 ? 2 : 3 ))'
85896320c17Schristos
85996320c17Schristos	atf_check -s exit:0 -o inline:'111\n' -e empty ${TEST_SH} -c \
86096320c17Schristos		'echo $(( 0x1234 ? 111 : 222 ))'
8612f35ca41Skre
8622f35ca41Skre	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
863e588572bSkre		'echo $(( 1 < 2 ? -1 : 1 > 2 ? 1 : 0 ))'
8642f35ca41Skre	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
865e588572bSkre		'echo $(( 1 < 1 ? -1 : 1 > 1 ? 1 : 0 ))'
8662f35ca41Skre	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
8672f35ca41Skre		'echo $(( 2 < 1 ? -1 : 2 > 1 ? 1 : 0 ))'
86896320c17Schristos}
86996320c17Schristos
87096320c17Schristosatf_test_case operator_precedence
87196320c17Schristosoperator_precedence_head()
87296320c17Schristos{
87396320c17Schristos	atf_set "descr" "Test operator precedence without parentheses"
87496320c17Schristos}
87596320c17Schristosoperator_precedence_body()
87696320c17Schristos{
87796320c17Schristos	# NB: apart from $(( ))  ** NO ** parentheses in the expressions.
87896320c17Schristos
87996320c17Schristos	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
88096320c17Schristos		'echo $(( 1 + 2 + 3 ))'
88196320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
88296320c17Schristos		'echo $(( 1 - 2 + 3 ))'
88396320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
88496320c17Schristos		'echo $(( 3 - 2 - 1 ))'
88596320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
88696320c17Schristos		'echo $(( 3 - 2 + 1 ))'
88796320c17Schristos
88896320c17Schristos	atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \
88996320c17Schristos		'echo $(( - 2 + 1 ))'
89096320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
89196320c17Schristos		'echo $(( 2 + -1 ))'
89296320c17Schristos
89396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
89496320c17Schristos		'echo $(( ! 2 + 1 ))'
89596320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
89696320c17Schristos		'echo $(( 2 + !1 ))'
89796320c17Schristos
89896320c17Schristos	atf_check -s exit:0 -o inline:'8\n' -e empty ${TEST_SH} -c \
89996320c17Schristos		'echo $(( 3 * 2 + 2 ))'
90096320c17Schristos	atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \
90196320c17Schristos		'echo $(( 3 + 2 * 2 ))'
90296320c17Schristos	atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
90396320c17Schristos		'echo $(( 3 * 2 * 2 ))'
90496320c17Schristos
90596320c17Schristos	atf_check -s exit:0 -o inline:'5\n' -e empty ${TEST_SH} -c \
90696320c17Schristos		'echo $(( 9 / 3 + 2 ))'
90796320c17Schristos	atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
90896320c17Schristos		'echo $(( 9 + 3 / 2 ))'
90996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
91096320c17Schristos		'echo $(( 9 / 3 / 2 ))'
91196320c17Schristos
91296320c17Schristos	atf_check -s exit:0 -o inline:'72\n' -e empty ${TEST_SH} -c \
91396320c17Schristos		'echo $(( 9 << 1 + 2 ))'
91496320c17Schristos	atf_check -s exit:0 -o inline:'48\n' -e empty ${TEST_SH} -c \
91596320c17Schristos		'echo $(( 9 + 3 << 2 ))'
91696320c17Schristos	atf_check -s exit:0 -o inline:'288\n' -e empty ${TEST_SH} -c \
91796320c17Schristos		'echo $(( 9 << 3 << 2 ))'
91896320c17Schristos
91996320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
92096320c17Schristos		'echo $(( 9 >> 1 + 2 ))'
92196320c17Schristos	atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
92296320c17Schristos		'echo $(( 9 + 3 >> 2 ))'
92396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
92496320c17Schristos		'echo $(( 19 >> 3 >> 1 ))'
92596320c17Schristos
92696320c17Schristos	atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
92796320c17Schristos		'echo $(( 19 >> 3 << 1 ))'
92896320c17Schristos	atf_check -s exit:0 -o inline:'76\n' -e empty ${TEST_SH} -c \
92996320c17Schristos		'echo $(( 19 << 3 >> 1 ))'
93096320c17Schristos
93196320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
93296320c17Schristos		'echo $(( 2 + 3 < 3 * 2 ))'
93396320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
93496320c17Schristos		'echo $(( 2 << 3 >= 3 << 2 ))'
93596320c17Schristos
93696320c17Schristos	# sh inherits C's crazy operator precedence...
93796320c17Schristos
93896320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
93996320c17Schristos		'echo $(( 0xfD & 0xF == 0xF ))'
940*8d48762dSkre
941*8d48762dSkre	${TEST_SH} -c ': $(( 1 , 2 , 3 ))' 2>/dev/null  && {
942*8d48762dSkre		atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
943*8d48762dSkre			'echo $(( 3 * 7 , 2 << 8 ,  9 - 7 ))'
944*8d48762dSkre		atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
945*8d48762dSkre			'echo $(( 1 ? 2 : 3 , 0 ? 1 : 4 ))'
946*8d48762dSkre	}
947*8d48762dSkre
948*8d48762dSkre	return 0
949*8d48762dSkre}
950*8d48762dSkre
951*8d48762dSkreatf_test_case optional_comma
952*8d48762dSkreoptional_comma_head()
953*8d48762dSkre{
954*8d48762dSkre	atf_set "descr" "Test the optional comma operator"
955*8d48762dSkre}
956*8d48762dSkreoptional_comma_body()
957*8d48762dSkre{
958*8d48762dSkre	# First, see if it is supported or not.
959*8d48762dSkre	${TEST_SH} -c ': $(( 1 , 2 , 3 ))' 2>/dev/null  || atf_skip \
960*8d48762dSkre	    "${TEST_SH} does not implement the ',' operator in"' $(( ))'
961*8d48762dSkre
962*8d48762dSkre
963*8d48762dSkre	# Note ',' should be set off from numbers by spaces, as in some
964*8d48762dSkre	# locales it is a valid chacacter in a number, and we want to
965*8d48762dSkre	# avoid any possibility of confusing the parser.
966*8d48762dSkre
967*8d48762dSkre	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
968*8d48762dSkre		'echo $(( 1 , 2 ))'
969*8d48762dSkre	atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \
970*8d48762dSkre		'echo $(( 1 , 2 , 3 ))'
971*8d48762dSkre	atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \
972*8d48762dSkre		'echo $(( 1 , 2 , 3 , 4 ))'
973*8d48762dSkre
974*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
975*8d48762dSkre		'echo $(( , 2 ))'
976*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
977*8d48762dSkre		'echo $(( 2 , ))'
978*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
979*8d48762dSkre		'echo $(( 1 , , 2 ))'
98096320c17Schristos}
98196320c17Schristos
98296320c17Schristosparentheses_head()
98396320c17Schristos{
98496320c17Schristos	atf_set "descr" "Test use of () to group sub-expressions"
98596320c17Schristos}
98696320c17Schristosparentheses_body()
98796320c17Schristos{
98896320c17Schristos	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
98996320c17Schristos		'echo $(( (1 + 2) + 3 ))'
99096320c17Schristos	atf_check -s exit:0 -o inline:'-4\n' -e empty ${TEST_SH} -c \
99196320c17Schristos		'echo $(( 1 - (2 + 3) ))'
99296320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
99396320c17Schristos		'echo $(( 3 - (2 - 1) ))'
99496320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
99596320c17Schristos		'echo $(( 3 - ( 2 + 1 ) ))'
99696320c17Schristos
99796320c17Schristos	atf_check -s exit:0 -o inline:'-3\n' -e empty ${TEST_SH} -c \
99896320c17Schristos		'echo $(( - (2 + 1) ))'
99996320c17Schristos
100096320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
100196320c17Schristos		'echo $(( ! (2 + 1) ))'
100296320c17Schristos
100396320c17Schristos	atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
100496320c17Schristos		'echo $(( 3 * (2 + 2) ))'
100596320c17Schristos	atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \
100696320c17Schristos		'echo $(( (3 + 2) * 2 ))'
100796320c17Schristos	atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \
100896320c17Schristos		'echo $(( 3 * (2 * 2) ))'
100996320c17Schristos
101096320c17Schristos	atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
101196320c17Schristos		'echo $(( 9 / (3 + 2) ))'
101296320c17Schristos	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
101396320c17Schristos		'echo $(( ( 9 + 3 ) / 2 ))'
101496320c17Schristos	atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
101596320c17Schristos		'echo $(( 9 / ( 3 / 2 ) ))'
101696320c17Schristos
101796320c17Schristos	atf_check -s exit:0 -o inline:'20\n' -e empty ${TEST_SH} -c \
101896320c17Schristos		'echo $(( ( 9 << 1 ) + 2 ))'
101996320c17Schristos	atf_check -s exit:0 -o inline:'21\n' -e empty ${TEST_SH} -c \
102096320c17Schristos		'echo $(( 9 + (3 << 2) ))'
102196320c17Schristos	atf_check -s exit:0 -o inline:'36864\n' -e empty ${TEST_SH} -c \
102296320c17Schristos		'echo $(( 9 << (3 << 2) ))'
102396320c17Schristos
102496320c17Schristos	atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \
102596320c17Schristos		'echo $(( (9 >> 1) + 2 ))'
102696320c17Schristos	atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
102796320c17Schristos		'echo $(( 9 + (3 >> 2) ))'
102896320c17Schristos	atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \
102996320c17Schristos		'echo $(( 19 >> (3 >> 1) ))'
103096320c17Schristos
103196320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
103296320c17Schristos		'echo $(( 19 >> (3 << 1) ))'
103396320c17Schristos	atf_check -s exit:0 -o inline:'38\n' -e empty ${TEST_SH} -c \
103496320c17Schristos		'echo $(( 19 << (3 >> 1) ))'
103596320c17Schristos
103696320c17Schristos	atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \
103796320c17Schristos		'echo $(( 2 + (3 < 3) * 2 ))'
103896320c17Schristos	atf_check -s exit:0 -o inline:'32\n' -e empty ${TEST_SH} -c \
103996320c17Schristos		'echo $(( 2 << ((3 >= 3) << 2) ))'
104096320c17Schristos
104196320c17Schristos	# sh inherits C's crazy operator precedence...
104296320c17Schristos	atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
104396320c17Schristos		'echo $(( (0xfD & 0xF) == 0xF ))'
1044*8d48762dSkre
1045*8d48762dSkre	${TEST_SH} -c ': $(( 1 , 2 , 3 ))' 2>/dev/null  && {
1046*8d48762dSkre		atf_check -s exit:0 -o inline:'24\n' -e empty ${TEST_SH} -c \
1047*8d48762dSkre			'echo $(( 3 * (7 , 2) << (8 ,  9 - 7) ))'
1048*8d48762dSkre		atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \
1049*8d48762dSkre			'echo $(( 0 ? 2 : ( ( 0 , 3 ) ? 1 : 4) ))'
1050*8d48762dSkre	}
1051*8d48762dSkre	return 0
105296320c17Schristos}
105396320c17Schristos
10540c0af3f5Skreatf_test_case var_assign
10550c0af3f5Skrevar_assign_head()
10560c0af3f5Skre{
10570c0af3f5Skre	atf_set "descr" "Test assignment operators in arithmetic expressions"
10580c0af3f5Skre}
10590c0af3f5Skrevar_assign_body()
10600c0af3f5Skre{
10610c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10620c0af3f5Skre		'unset x; echo $(( x = 3 )); echo $x'
10630c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10640c0af3f5Skre		'unset x; echo $((x=3)); echo $x'
10650c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10660c0af3f5Skre		'x=5; echo $((x=3)); echo $x'
10670c0af3f5Skre
10680c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10690c0af3f5Skre		'set +u;unset x; echo $((x+=3)); echo $x'
10700c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10710c0af3f5Skre		'x=2; echo $((x+=1)); echo $x'
10720c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10730c0af3f5Skre		'x=4; echo $((x-=1)); echo $x'
10740c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10750c0af3f5Skre		'x=3; echo $((x*=1)); echo $x'
10760c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10770c0af3f5Skre		'x=3; echo $((x/=1)); echo $x'
10780c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10790c0af3f5Skre		'x=28; echo $((x%=5)); echo $x'
10800c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10810c0af3f5Skre		'x=7; echo $((x&=3)); echo $x'
10820c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10830c0af3f5Skre		'x=2; echo $((x|=1)); echo $x'
10840c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10850c0af3f5Skre		'x=6; echo $((x^=5)); echo $x'
10860c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
10870c0af3f5Skre		'x=7; echo $((x>>=1)); echo $x'
10880c0af3f5Skre	atf_check -s exit:0 -o inline:'2\n2\n' -e empty ${TEST_SH} -c \
10890c0af3f5Skre		'x=1; echo $((x<<=1)); echo $x'
10900c0af3f5Skre
10910c0af3f5Skre	atf_check -s exit:0 -o inline:'2\n3\n' -e empty ${TEST_SH} -c \
10920c0af3f5Skre		'x=2; echo $(( (x+=1)-1 )); echo $x'
10930c0af3f5Skre	atf_check -s exit:0 -o inline:'4\n3\n' -e empty ${TEST_SH} -c \
10940c0af3f5Skre		'x=4; echo $(( (x-=1)+1 )); echo $x'
10950c0af3f5Skre
10960c0af3f5Skre	atf_check -s exit:0 -o inline:'36\n5 7\n' -e empty ${TEST_SH} -c \
10970c0af3f5Skre		'unset x y; echo $(( (x=5) * (y=7) + 1 )); echo $x $y'
10980c0af3f5Skre	atf_check -s exit:0 -o inline:'36\n5 7\n' -e empty ${TEST_SH} -c \
10990c0af3f5Skre		'x=99; y=17; echo $(( (x=5) * (y=7) + 1 )); echo $x $y'
11000c0af3f5Skre	atf_check -s exit:0 -o inline:'36\n5 7\n' -e empty ${TEST_SH} -c \
11010c0af3f5Skre		'x=4; y=9; echo $(( (x+=1) * (y-=2) + 1 )); echo $x $y'
11020c0af3f5Skre
11030c0af3f5Skre	atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
11040c0af3f5Skre		'set -u; unset x; echo $(( x = 3 )); echo $x'
11050c0af3f5Skre	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
11060c0af3f5Skre		'set -u; unset x; echo $(( x + 3 )); echo $x'
11070c0af3f5Skre	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
11080c0af3f5Skre		'set -u; unset x; echo $(( x+=3 )); echo $x'
1109*8d48762dSkre
1110*8d48762dSkre	${TEST_SH} -c ': $(( 1 , 2 , 3 ))' 2>/dev/null  && {
1111*8d48762dSkre		atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1112*8d48762dSkre			'echo $((x=2 , x|=1)); echo $x'
1113*8d48762dSkre		atf_check -s exit:0 -o inline:'3\n3\n' -e empty ${TEST_SH} -c \
1114*8d48762dSkre			'set -u; echo $((x = 2   ,x |= 1)); echo $x'
1115*8d48762dSkre		atf_check -s exit:0 -o inline:'6\n1:2:3:6\n' -e empty \
1116*8d48762dSkre			${TEST_SH} -c \
1117*8d48762dSkre		    'echo $((a=1 , b=2 , c = 3 , x=a+b + c)); echo $a:$b:$c:$x'
1118*8d48762dSkre		atf_check -s exit:0 -o inline:'6\n1:2:3:6\n' -e empty \
1119*8d48762dSkre			${TEST_SH} -c \
1120*8d48762dSkre		    'set -u;echo $((a=1 ,b=2 ,c=3 ,x=a+b+c)); echo $a:$b:$c:$x'
1121*8d48762dSkre	}
1122*8d48762dSkre	return 0
1123*8d48762dSkre}
1124*8d48762dSkre
1125*8d48762dSkreatf_test_case var_postinc
1126*8d48762dSkrevar_postinc_head()
1127*8d48762dSkre{
1128*8d48762dSkre	atf_set "descr" "Test suffix ++ operator"
1129*8d48762dSkre}
1130*8d48762dSkrevar_postinc_body()
1131*8d48762dSkre{
1132*8d48762dSkre	${TEST_SH} -c 'X=1; : $(( X++ ))' 2>/dev/null ||
1133*8d48762dSkre		atf_skip "${TEST_SH} does not support the suffix ++ operator"
1134*8d48762dSkre
1135*8d48762dSkre	unset X		; # just in case ...
1136*8d48762dSkre
1137*8d48762dSkre	atf_check -s exit:0 -o inline:'1\n2\n' -e empty ${TEST_SH} -c \
1138*8d48762dSkre		'X=1; echo $(( X++ )); echo $X'
1139*8d48762dSkre	atf_check -s exit:0 -o inline:'0\n1\n' -e empty ${TEST_SH} -c \
1140*8d48762dSkre		'echo $(( X++ )); echo $X'
1141*8d48762dSkre
1142*8d48762dSkre	atf_check -s exit:0 -o inline:'0\n1:0\n' -e empty ${TEST_SH} -c \
1143*8d48762dSkre		'unset Y; echo $(( Y = X++ )); echo $X:$Y'
1144*8d48762dSkre	atf_check -s exit:0 -o inline:'12\n4:5\n' -e empty ${TEST_SH} -c \
1145*8d48762dSkre		'X=3 Y=4; echo $(( Y++*X++ )); echo $X:$Y'
1146*8d48762dSkre
1147*8d48762dSkre	atf_check -s exit:0 -o inline:'1\n2\n' -e empty ${TEST_SH} -c \
1148*8d48762dSkre		'set -u; X=1; echo $(( X++ )); echo $X'
1149*8d48762dSkre	atf_check -s exit:0 -o inline:'0\n1:0\n' -e empty ${TEST_SH} -c \
1150*8d48762dSkre		'set -u; X=0; unset Y; echo $(( Y = X++ )); echo $X:$Y'
1151*8d48762dSkre	atf_check -s exit:0 -o inline:'12\n4:5\n' -e empty ${TEST_SH} -c \
1152*8d48762dSkre		'set -u; X=3 Y=4; echo $(( Y++*X++ )); echo $X:$Y'
1153*8d48762dSkre
1154*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1155*8d48762dSkre		'set -u; echo $(( X++ ))'
1156*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1157*8d48762dSkre		'set -u; unset Y; echo $(( X = Y++ ))'
1158*8d48762dSkre
1159*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1160*8d48762dSkre		'X=3; readonly X; echo $(( X++ ))'
1161*8d48762dSkre
1162*8d48762dSkre}
1163*8d48762dSkreatf_test_case var_postdec
1164*8d48762dSkrevar_postdec_head()
1165*8d48762dSkre{
1166*8d48762dSkre	atf_set "descr" "Test suffix -- operator"
1167*8d48762dSkre}
1168*8d48762dSkrevar_postdec_body()
1169*8d48762dSkre{
1170*8d48762dSkre	${TEST_SH} -c 'X=1; : $(( X-- ))' 2>/dev/null ||
1171*8d48762dSkre		atf_skip "${TEST_SH} does not support the suffix -- operator"
1172*8d48762dSkre
1173*8d48762dSkre	unset X		; # just in case ...
1174*8d48762dSkre
1175*8d48762dSkre	atf_check -s exit:0 -o inline:'1\n0\n' -e empty ${TEST_SH} -c \
1176*8d48762dSkre		'X=1; echo $(( X-- )); echo $X'
1177*8d48762dSkre	atf_check -s exit:0 -o inline:'0\n-1\n' -e empty ${TEST_SH} -c \
1178*8d48762dSkre		'echo $(( X-- )); echo $X'
1179*8d48762dSkre
1180*8d48762dSkre	atf_check -s exit:0 -o inline:'0\n-1:0\n' -e empty ${TEST_SH} -c \
1181*8d48762dSkre		'unset Y; echo $(( Y = X-- )); echo $X:$Y'
1182*8d48762dSkre	atf_check -s exit:0 -o inline:'12\n2:3\n' -e empty ${TEST_SH} -c \
1183*8d48762dSkre		'X=3 Y=4; echo $(( Y--*X-- )); echo $X:$Y'
1184*8d48762dSkre
1185*8d48762dSkre	atf_check -s exit:0 -o inline:'1\n0\n' -e empty ${TEST_SH} -c \
1186*8d48762dSkre		'set -u; X=1; echo $(( X-- )); echo $X'
1187*8d48762dSkre	atf_check -s exit:0 -o inline:'0\n-1:0\n' -e empty ${TEST_SH} -c \
1188*8d48762dSkre		'set -u; X=0; unset Y; echo $(( Y = X-- )); echo $X:$Y'
1189*8d48762dSkre	atf_check -s exit:0 -o inline:'12\n2:3\n' -e empty ${TEST_SH} -c \
1190*8d48762dSkre		'set -u; X=3 Y=4; echo $(( Y--*X-- )); echo $X:$Y'
1191*8d48762dSkre
1192*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1193*8d48762dSkre		'set -u; echo $(( X-- ))'
1194*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1195*8d48762dSkre		'set -u; unset Y; echo $(( X = Y-- ))'
1196*8d48762dSkre
1197*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1198*8d48762dSkre		'X=3; readonly X; echo $(( X-- ))'
1199*8d48762dSkre
1200*8d48762dSkre}
1201*8d48762dSkreatf_test_case var_preinc
1202*8d48762dSkrevar_preinc_head()
1203*8d48762dSkre{
1204*8d48762dSkre	atf_set "descr" "Test prefix ++ operator"
1205*8d48762dSkre}
1206*8d48762dSkrevar_preinc_body()
1207*8d48762dSkre{
1208*8d48762dSkre	${TEST_SH} -c 'X=1; : $(( ++X ))' 2>/dev/null ||
1209*8d48762dSkre		atf_skip "${TEST_SH} does not support the prefix ++ operator"
1210*8d48762dSkre
1211*8d48762dSkre	unset X		; # just in case ...
1212*8d48762dSkre
1213*8d48762dSkre	atf_check -s exit:0 -o inline:'2\n2\n' -e empty ${TEST_SH} -c \
1214*8d48762dSkre		'X=1; echo $(( ++X )); echo $X'
1215*8d48762dSkre	atf_check -s exit:0 -o inline:'1\n1\n' -e empty ${TEST_SH} -c \
1216*8d48762dSkre		'echo $(( ++X )); echo $X'
1217*8d48762dSkre
1218*8d48762dSkre	atf_check -s exit:0 -o inline:'1\n1:1\n' -e empty ${TEST_SH} -c \
1219*8d48762dSkre		'unset Y; echo $(( Y = ++X )); echo $X:$Y'
1220*8d48762dSkre	atf_check -s exit:0 -o inline:'20\n4:5\n' -e empty ${TEST_SH} -c \
1221*8d48762dSkre		'X=3 Y=4; echo $(( ++Y*++X )); echo $X:$Y'
1222*8d48762dSkre
1223*8d48762dSkre	atf_check -s exit:0 -o inline:'2\n2\n' -e empty ${TEST_SH} -c \
1224*8d48762dSkre		'set -u; X=1; echo $(( ++X )); echo $X'
1225*8d48762dSkre	atf_check -s exit:0 -o inline:'1\n1:1\n' -e empty ${TEST_SH} -c \
1226*8d48762dSkre		'set -u; X=0; unset Y; echo $(( Y = ++X )); echo $X:$Y'
1227*8d48762dSkre	atf_check -s exit:0 -o inline:'20\n4:5\n' -e empty ${TEST_SH} -c \
1228*8d48762dSkre		'set -u; X=3 Y=4; echo $(( ++Y*++X )); echo $X:$Y'
1229*8d48762dSkre
1230*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1231*8d48762dSkre		'set -u; echo $(( ++X ))'
1232*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1233*8d48762dSkre		'set -u; unset Y; echo $(( X = ++Y ))'
1234*8d48762dSkre
1235*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1236*8d48762dSkre		'X=3; readonly X; echo $(( ++X ))'
1237*8d48762dSkre
1238*8d48762dSkre}
1239*8d48762dSkreatf_test_case var_predec
1240*8d48762dSkrevar_predec_head()
1241*8d48762dSkre{
1242*8d48762dSkre	atf_set "descr" "Test prefix -- operator"
1243*8d48762dSkre}
1244*8d48762dSkrevar_predec_body()
1245*8d48762dSkre{
1246*8d48762dSkre	${TEST_SH} -c 'X=1; : $(( --X ))' 2>/dev/null ||
1247*8d48762dSkre		atf_skip "${TEST_SH} does not support the prefix -- operator"
1248*8d48762dSkre
1249*8d48762dSkre	unset X		; # just in case ...
1250*8d48762dSkre
1251*8d48762dSkre	atf_check -s exit:0 -o inline:'0\n0\n' -e empty ${TEST_SH} -c \
1252*8d48762dSkre		'X=1; echo $(( --X )); echo $X'
1253*8d48762dSkre	atf_check -s exit:0 -o inline:'-1\n-1\n' -e empty ${TEST_SH} -c \
1254*8d48762dSkre		'echo $(( --X )); echo $X'
1255*8d48762dSkre
1256*8d48762dSkre	atf_check -s exit:0 -o inline:'-1\n-1:-1\n' -e empty ${TEST_SH} -c \
1257*8d48762dSkre		'unset Y; echo $(( Y = --X )); echo $X:$Y'
1258*8d48762dSkre	atf_check -s exit:0 -o inline:'6\n2:3\n' -e empty ${TEST_SH} -c \
1259*8d48762dSkre		'X=3 Y=4; echo $(( --Y*--X )); echo $X:$Y'
1260*8d48762dSkre
1261*8d48762dSkre	atf_check -s exit:0 -o inline:'0\n0\n' -e empty ${TEST_SH} -c \
1262*8d48762dSkre		'set -u; X=1; echo $(( --X )); echo $X'
1263*8d48762dSkre	atf_check -s exit:0 -o inline:'-1\n-1:-1\n' -e empty ${TEST_SH} -c \
1264*8d48762dSkre		'set -u; X=0; unset Y; echo $(( Y = --X )); echo $X:$Y'
1265*8d48762dSkre	atf_check -s exit:0 -o inline:'6\n2:3\n' -e empty ${TEST_SH} -c \
1266*8d48762dSkre		'set -u; X=3 Y=4; echo $(( --Y*--X )); echo $X:$Y'
1267*8d48762dSkre
1268*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1269*8d48762dSkre		'set -u; echo $(( --X ))'
1270*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1271*8d48762dSkre		'set -u; unset Y; echo $(( X = --Y ))'
1272*8d48762dSkre
1273*8d48762dSkre	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
1274*8d48762dSkre		'X=3; readonly X; echo $(( --X ))'
1275*8d48762dSkre
12760c0af3f5Skre}
12770c0af3f5Skre
127896320c17Schristosatf_test_case arithmetic_fails
127996320c17Schristosarithmetic_fails_head()
128096320c17Schristos{
128196320c17Schristos	atf_set "descr" "Dummy test to force failure"
128296320c17Schristos}
128396320c17Schristosarithmetic_fails_body()
128496320c17Schristos{
128596320c17Schristos	atf_fail "Cannot estimate number of bits supported by $(( ))"
128696320c17Schristos}
128796320c17Schristos
128896320c17Schristosatf_init_test_cases() {
128996320c17Schristos
129096320c17Schristos	discover_range
129196320c17Schristos
129296320c17Schristos	test "${ARITH_BITS}" = '?' && {
129396320c17Schristos		atf_add_test_case arithmetic_fails
129496320c17Schristos		return 0
129596320c17Schristos	}
129696320c17Schristos
129796320c17Schristos	# odd names are to get atf's sort order semi-rational
129896320c17Schristos
129996320c17Schristos	atf_add_test_case constants
130096320c17Schristos	atf_add_test_case do_unary_plus
130196320c17Schristos	atf_add_test_case do_unary_minus
130296320c17Schristos	atf_add_test_case do_unary_not
130396320c17Schristos	atf_add_test_case do_unary_tilde
130496320c17Schristos	atf_add_test_case elementary_add
130596320c17Schristos	atf_add_test_case elementary_sub
130696320c17Schristos	atf_add_test_case elementary_mul
130796320c17Schristos	atf_add_test_case elementary_div
130896320c17Schristos	atf_add_test_case elementary_rem
130996320c17Schristos	atf_add_test_case elementary_shl
131096320c17Schristos	atf_add_test_case elementary_shr
131196320c17Schristos	atf_add_test_case elementary_eq
131296320c17Schristos	atf_add_test_case elementary_ne
131396320c17Schristos	atf_add_test_case elementary_lt
131496320c17Schristos	atf_add_test_case elementary_le
131596320c17Schristos	atf_add_test_case elementary_gt
131696320c17Schristos	atf_add_test_case elementary_ge
131796320c17Schristos	atf_add_test_case fiddle_bits_and
131896320c17Schristos	atf_add_test_case fiddle_bits_or
131996320c17Schristos	atf_add_test_case fiddle_bits_xor
132096320c17Schristos	atf_add_test_case logical_and
132196320c17Schristos	atf_add_test_case logical_or
132296320c17Schristos	atf_add_test_case make_selection
1323f0acc68eSkre	atf_add_test_case nested_arith
132496320c17Schristos	atf_add_test_case operator_precedence
1325*8d48762dSkre	atf_add_test_case optional_comma
132696320c17Schristos	atf_add_test_case parentheses
132796320c17Schristos	# atf_add_test_case progressive			# build up big expr
132896320c17Schristos	# atf_add_test_case test_errors			# erroneous input
132996320c17Schristos	# atf_add_test_case torture		# hard stuff (if there is any)
13300c0af3f5Skre	atf_add_test_case var_assign			# assignment ops
1331*8d48762dSkre	atf_add_test_case var_postinc			# var++
1332*8d48762dSkre	atf_add_test_case var_postdec			# var--
1333*8d48762dSkre	atf_add_test_case var_preinc			# ++var
1334*8d48762dSkre	atf_add_test_case var_predec			# --var
133596320c17Schristos	# atf_add_test_case vulgarity	# truly evil inputs (syntax in vars...)
133696320c17Schristos}
1337