NAME global_int
PROG i:ms:1 {@a = 10; printf("%d\n", @a); exit();}
EXPECT @a: 10

NAME global_string
PROG i:ms:1 {@a = "hi"; printf("%s\n", @a); exit();}
EXPECT @a: hi

NAME global_buf
PROG i:ms:1 {@a = buf("hi", 2); printf("%r\n", @a); exit();}
EXPECT @a: hi

NAME local_int
PROG i:ms:1  {$a = 10; printf("a=%d\n", $a); exit();}
EXPECT a=10

NAME local_string
PROG i:ms:1  {$a = "hi"; printf("a=%s\n", $a); exit();}
EXPECT a=hi

NAME local_buf
PROG i:ms:1 {$a = buf("hi", 2); printf("a=%r\n", $a); exit();}
EXPECT a=hi

NAME buf_equality
PROG i:ms:1 {$a = buf("hi", 2); $b = buf("bye", 3); printf("equal=%d, unequal=%d\n", $a == $a, $a != $b); exit();}
EXPECT equal=1, unequal=1

NAME global_associative_arrays
PROG begin { @map[123] = 456; } end { printf("val: %d\n", @map[123]);  }
EXPECT val: 456

NAME scratch
PROG begin { @map[123] = 456; } end { $val = @map[123]; printf("val: %d\n", $val);  }
EXPECT val: 456

NAME 32-bit tracepoint arg
PROG tracepoint:syscalls:sys_enter_openat /comm == "syscall"/ { $i = args.flags; printf("openflags: %d\n", $i); if ($i == 64) { exit() } }
EXPECT openflags: 64
AFTER ./testprogs/syscall openat

NAME tracepoint arg casts in predicates
RUN {{BPFTRACE}} -e 'tracepoint:syscalls:sys_enter_wait4 /args.ru/ { @ru[tid] = args.ru; } tracepoint:syscalls:sys_exit_wait4 /@ru[tid]/ { @++; exit(); }' -c ./testprogs/wait4_ru
EXPECT_REGEX @: [1-9][0-9]*

NAME variable string type resize
PROG begin { $x = "hello"; $x = "hi"; printf("%s\n", $x);  }
EXPECT hi
TIMEOUT 2

NAME map string type resize
PROG begin { @ = "hello"; } i:ms:1 { @ = "hi";  }
EXPECT @: hi
TIMEOUT 2

NAME map key string type resize
PROG begin { @["hello"] = 0; } i:ms:1 { @["hi"] = 1;  }
EXPECT @[hi]: 1
TIMEOUT 2

NAME map multi-key string type resize
PROG begin { @["hello", 0] = 0; } i:ms:1 { @["hi", 1] = 1;  }
EXPECT @[hi, 1]: 1
TIMEOUT 2

NAME map tuple string resize
PROG begin { @[1] = ("hi", 1); @[1] = ("hellolongstr", 2); @[1] = ("by", 3);  }
EXPECT @[1]: (by, 3)
TIMEOUT 2

NAME map key tuple string resize
PROG begin { @["hi", 1] = 1; @["hellolongstr", 2] = 2; @["by", 3] = 3;  }
EXPECT @[hi, 1]: 1
EXPECT @[hellolongstr, 2]: 2
EXPECT @[by, 3]: 3
TIMEOUT 2

NAME variable tuple string resize
PROG begin { $a = ("hi", 1); print(($a)); $a = ("hellolongstr", 2); print(($a)); $a = ("by", 3); print(($a));  }
EXPECT (hi, 1)
EXPECT (hellolongstr, 2)
EXPECT (by, 3)
TIMEOUT 2

NAME variable nested tuple string resize
PROG begin { $a = ("hi", ("hellolongstr", 2)); print(($a)); $a = ("hellolongstr", ("hi", 5)); print(($a));  }
EXPECT (hi, (hellolongstr, 2))
EXPECT (hellolongstr, (hi, 5))
TIMEOUT 2

NAME map nested tuple string resize
PROG begin { @[1] = ("hi", ("hellolongstr", 2)); @[1] = ("hellolongstr", ("hi", 5));  }
EXPECT @[1]: (hellolongstr, (hi, 5))
TIMEOUT 2

NAME map key nested tuple string resize
PROG begin { @["hi", ("hellolongstr", 2)] = 1; @["hellolongstr", ("hi", 5)] = 2;  }
EXPECT @[hi, (hellolongstr, 2)]: 1
EXPECT @[hellolongstr, (hi, 5)]: 2
TIMEOUT 2

NAME map key tuple with casted ints
PROG begin { @a[(int16)-1, ((int32)-2, 3)] = 10; @a[5, (6, 7)] = 11; $c = ((int8)-4, ((int16)-5, -6)); @a[$c] = 12;  }
EXPECT @a[-4, (-5, -6)]: 12
EXPECT @a[-1, (-2, 3)]: 10
EXPECT @a[5, (6, 7)]: 11
TIMEOUT 2

NAME variable declaration
PROG begin { let $a; $a = 10; printf("a=%d\n", $a); }
EXPECT a=10

NAME variable declaration with builtin
PROG begin { let $f: struct task_struct *; $f = curtask; print($f->pid); }
EXPECT_REGEX [0-9]+

NAME variable declaration with unresolved type
PROG begin { let $x: struct Foo[1];  }
EXPECT Attached 1 probe

NAME variable declaration not initialized
PROG begin { let $a; if (false) { $a = 1; } @b = $a; }
EXPECT @b: 0

NAME variable doesn't escape scope
RUN {{BPFTRACE}} runtime/scripts/variable_scope.bt
EXPECT 0

NAME late variable declaration
RUN {{BPFTRACE}} runtime/scripts/variable_scope_late_decl.bt
EXPECT (a, 1)
EXPECT (b, 2)
EXPECT (c, 0)

NAME late map evaluation with ctx capture
RUN {{BPFTRACE}} -e 'interval:ms:100 { $x = 1; for ($kv : @a) { print(($x, $kv.0, $kv.1)); exit(); } @a[1] = 1; }'
EXPECT (1, 1, 1)

NAME variable address with int
PROG begin { $a = 1; $b = &$a; print(($b, *$b)); }
EXPECT_REGEX (0x[0-9a-f]+, 1)

NAME variable address with tuple
PROG begin { $a = (1, "hello", 2); print(*(&$a)); }
EXPECT (1, hello, 2)

NAME variable address with string
PROG begin { $a = "hello"; $b = (int8 *)&$a; printf("%c %c\n", *$b, *++$b); }
EXPECT h e

NAME variable address with builtin
PROG begin { $a = username; $b = &$a; printf("SUCCESS %s\n", *$b); }
EXPECT_REGEX SUCCESS .*
