v4 / vlib / v3 / tests / c_variadic_call_codegen_test.v
86 lines · 76 sloc · 2.57 KB · 288feee4702b35beadb4037d02b96b5c8674156b
Raw
1import os
2
3const c_variadic_vexe = @VEXE
4const c_variadic_tests_dir = os.dir(@FILE)
5const c_variadic_v3_dir = os.dir(c_variadic_tests_dir)
6const c_variadic_vlib_dir = os.dir(c_variadic_v3_dir)
7const c_variadic_v3_src = os.join_path(c_variadic_v3_dir, 'v3.v')
8
9fn c_variadic_build_v3() string {
10 v3_bin := os.join_path(os.temp_dir(), 'v3_c_variadic_test_${os.getpid()}')
11 os.rm(v3_bin) or {}
12 build :=
13 os.execute('${c_variadic_vexe} -gc none -path "${c_variadic_vlib_dir}|@vlib|@vmodules" -o ${v3_bin} ${c_variadic_v3_src}')
14 assert build.exit_code == 0, build.output
15 return v3_bin
16}
17
18fn c_variadic_call_lines(generated string, names []string) []string {
19 mut lines := []string{}
20 for line in generated.split_into_lines() {
21 for name in names {
22 if line.contains('${name}(') {
23 lines << line
24 break
25 }
26 }
27 }
28 return lines
29}
30
31fn test_c_variadic_calls_emit_real_args_without_v_pack_array() {
32 v3_bin := c_variadic_build_v3()
33 src := os.join_path(os.temp_dir(), 'v3_c_variadic_${os.getpid()}.v')
34 os.write_file(src, "module main
35
36struct C.FILE {}
37
38fn C.printf(fmt &char, args ...voidptr) int
39fn C.fprintf(stream &C.FILE, fmt &char, args ...voidptr) int
40fn C.sscanf(input &char, fmt &char, args ...voidptr) int
41fn C.fflush(stream &C.FILE) int
42
43__global C.stderr &C.FILE
44
45fn sum(xs ...int) int {
46 mut total := 0
47 for x in xs {
48 total += x
49 }
50 return total
51}
52
53fn main() {
54 C.printf(&c'plain\\n')
55 C.printf(&c'name=%s count=%d\\n', &c'ok', 7)
56 C.fprintf(C.stderr, &c'err=%d\\n', 9)
57 C.fflush(C.stderr)
58 mut a := 0
59 mut b := 0
60 C.sscanf(&c'12 34', &c'%d %d', &a, &b)
61 println(int_str(a + b + sum(1, 2, 3)))
62}
63") or {
64 panic(err)
65 }
66 bin := os.join_path(os.temp_dir(), 'v3_c_variadic_${os.getpid()}')
67 compile := os.execute('${v3_bin} ${src} -b c -o ${bin}')
68 assert compile.exit_code == 0, compile.output
69 run := os.execute(bin)
70 assert run.exit_code == 0, run.output
71 assert run.output.contains('plain'), run.output
72 assert run.output.contains('name=ok count=7'), run.output
73 assert run.output.trim_space().ends_with('52'), run.output
74
75 generated := os.read_file(bin + '.c') or { panic(err) }
76 c_lines := c_variadic_call_lines(generated, ['printf', 'fprintf', 'sscanf'])
77 assert c_lines.len >= 4, generated
78 for line in c_lines {
79 assert !line.contains('__varargs_'), line
80 }
81 assert generated.contains('printf("plain\\n");'), generated
82 assert generated.contains('printf("name=%s count=%d\\n", "ok", 7);'), generated
83 assert generated.contains('fprintf(stderr, "err=%d\\n", 9);'), generated
84 assert generated.contains('sscanf("12 34", "%d %d", &a, &b);'), generated
85 assert generated.contains('__varargs_'), generated
86}
87