NAME basic tuple
PROG BEGIN { $v = 99; $t = (0, 1, "str", (5, 6), $v); printf("%d %d %s %d %d %d\n", $t.0, $t.1, $t.2, $t.3.0, $t.3.1, $t.4); exit(); }
EXPECT 0 1 str 5 6 99

NAME basic tuple map
PROG BEGIN { $v = 99; @t = (0, 1, "str"); printf("%d %d %s\n", @t.0, @t.1, @t.2); exit(); }
EXPECT 0 1 str

NAME mixed int tuple map
PROG BEGIN { @ = ( (int32) -100, (int8) 10, 50 ); exit();}
EXPECT @: (-100, 10, 50)

NAME mixed int tuple map 2
PROG BEGIN { @ = ( -100, (int8) 10, (int32) 50 ); exit();}
EXPECT @: (-100, 10, 50)

NAME mixed int tuple map 3
PROG BEGIN { @ = ( -100, (int8) 10, (int32) 50, 100 ); exit();}
EXPECT @: (-100, 10, 50, 100)

NAME tuple map key
PROG BEGIN { @[(1, "hello")] = 1; exit();}
EXPECT @[1, hello]: 1

NAME tuple map key and value
PROG BEGIN { @[(1, 2)] = (3, 4); exit();}
EXPECT @[1, 2]: (3, 4)

NAME implicit conversion of multi map key to tuple
PROG BEGIN { @["abcd", 2] = (3, 4, 5); exit();}
EXPECT @[abcd, 2]: (3, 4, 5)

NAME tuple map key same as assoc array
PROG BEGIN { @[(1, "hello")] = 1;  @[2, "hello"] = 2; delete(@, (1, "hello")); exit();}
EXPECT @[2, hello]: 2

NAME tuple map key variable
PROG BEGIN { $a = (1, "hello"); @[(1, "hello")] = 1; @[$a] = 2; exit();}
EXPECT @[1, hello]: 2

NAME tuple map key string resize
PROG BEGIN { @a["hellotherelongstr", 4] = 1; @a["by", 6] = 2; exit(); }
EXPECT @a[hellotherelongstr, 4]: 1
EXPECT @a[by, 6]: 2

NAME tuple map key compatible int sizes
PROG BEGIN { $a = (1,(123,(uint64)1234)); $b = (4,(1234,(uint8)123)); @a[$a] = 1; @a[$b] = 2; exit(); }
EXPECT @a[1, (123, 1234)]: 1
EXPECT @a[4, (1234, 123)]: 2

NAME complex tuple 1
PROG BEGIN { print(((int8)-100, (int8) 100, "abcdef", 3, (int32) 1, (int64)-10, (int8)10, (int16)-555)); exit(); }
EXPECT (-100, 100, abcdef, 3, 1, -10, 10, -555)

NAME tuple struct sizing 1
PROG BEGIN { $t = ((int8) 1, (int64) 1, (int8) 1, (int64) 1); print(sizeof($t)); exit() }
EXPECT 32

NAME tuple struct sizing 2
PROG BEGIN { $t = ((int8) 1, (int16) 1, (int32) 1); print(sizeof($t)); exit() }
EXPECT 8

NAME tuple struct sizing 3
PROG BEGIN { $t = ((int32) 1, (int16) 1, (int8) 1); print(sizeof($t)); exit() }
EXPECT 8

NAME complex tuple 4
PROG BEGIN { $a = ((int8)-100, (int8) 100, "abcdef", 3, (int32) 1, (int64)-10, (int8)10, (int16)-555, "abc"); print(sizeof($a)); exit(); }
EXPECT 48

NAME struct in tuple
PROG struct Foo { int m; int n; } u:./testprogs/simple_struct:func { @t = (1, *((struct Foo *)arg0)); exit(); }
EXPECT @t: (1, { .m = 2, .n = 3 })
AFTER ./testprogs/simple_struct

NAME struct in tuple sizing
PROG struct Foo { int m; int n; } u:./testprogs/simple_struct:func { $t = ((int32)1, *((struct Foo *)arg0)); print(sizeof($t)); exit(); }
EXPECT 12
AFTER ./testprogs/simple_struct

NAME array in tuple
PROG struct A { int x[4]; } u:./testprogs/array_access:test_struct { @t = (1, ((struct A *)arg0)->x); exit(); }
EXPECT @t: (1, [1,2,3,4])
AFTER ./testprogs/array_access

NAME array in tuple sizing
PROG struct A { int x[4]; } u:./testprogs/array_access:test_struct { $t = ((int32)1, ((struct A *)arg0)->x); print(sizeof($t)); exit(); }
EXPECT 20
AFTER ./testprogs/array_access

NAME nested tuple
PROG BEGIN{ @ = ((int8)1, ((int8)-20, (int8)30)); exit(); }
EXPECT @: (1, (-20, 30))

# Careful with '(' and ')', they are read by the test engine as a regex group,
# so make sure to escape them.
NAME tuple print
PROG BEGIN { @ = (1, 2, "string", (4, 5)); exit(); }
EXPECT @: (1, 2, string, (4, 5))

NAME tuple strftime type is packed
PROG BEGIN { @ = (nsecs, strftime("%M:%S", nsecs)); exit(); }
EXPECT_REGEX ^@: \(\d+, \d+:\d+\)$

NAME bytearray in tuple
PROG uprobe:./testprogs/uprobe_test:uprobeFunction1 { @ = ((int8)1, usym(reg("ip")), 10); exit(); }
EXPECT_REGEX ^@: \(1, 0x[0-9a-f]+, 10\)$
ARCH x86_64
AFTER ./testprogs/uprobe_test

NAME bytearray in tuple
PROG uprobe:./testprogs/uprobe_test:uprobeFunction1 { @ = ((int8)1, usym(reg("nip")), 10); exit(); }
EXPECT_REGEX ^@: \(1, 0x[0-9a-f]+, 10\)$
ARCH ppc64|ppc64le
AFTER ./testprogs/uprobe_test
