v2 / vlib / v / gen / c / cheaders_manual_stdlib_decls_test.v
298 lines · 276 sloc · 19.64 KB · d398402707ab2298a12fbeabefe274eba5b1c2cd
Raw
1import os
2
3const cheaders_manual_stdlib_vexe = @VEXE
4
5const cheaders_manual_stdlib_vroot = os.real_path(@VMODROOT)
6
7const cheaders_manual_stdlib_varargs_source = os.join_path(cheaders_manual_stdlib_vroot,
8 'vlib/v/gen/c/testdata/c_varargs.vv')
9
10const cheaders_manual_stdlib_stdio_source = os.join_path(cheaders_manual_stdlib_vroot,
11 'vlib/v/tests/c_shadowed_c_fn_call_test.v')
12
13fn test_default_c_prelude_uses_manual_stdio_stdlib_string_and_stdarg_decls() {
14 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -o - ${os.quoted_path(cheaders_manual_stdlib_varargs_source)}'
15 res := os.execute(cmd)
16 assert res.exit_code == 0, '${cmd}\n${res.output}'
17 generated_c := res.output.replace('\r\n', '\n')
18 assert generated_c.contains('typedef struct _iobuf FILE;'), generated_c
19 assert generated_c.contains('typedef struct __sFILE FILE;'), generated_c
20 assert generated_c.contains('typedef struct _IO_FILE FILE;'), generated_c
21 assert generated_c.contains('typedef __builtin_va_list va_list;'), generated_c
22 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL vfprintf(FILE *stream, const char *format, va_list ap);'), generated_c
23
24 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL vsnprintf(char *str, size_t size, const char *format, va_list ap);'), generated_c
25 assert generated_c.contains('#if defined(_WIN32) || defined(_WIN64)\nV_CRT_LINKAGE int V_CRT_CALL _fileno(FILE *stream);\nV_CRT_LINKAGE FILE * V_CRT_CALL _wfopen(const unsigned short *filename, const unsigned short *mode);\nV_CRT_LINKAGE int V_CRT_CALL _wremove(const unsigned short *path);\nV_CRT_LINKAGE void * V_CRT_CALL _aligned_malloc(size_t size, size_t alignment);\nV_CRT_LINKAGE void * V_CRT_CALL _aligned_realloc(void *memory, size_t size, size_t alignment);\nV_CRT_LINKAGE void V_CRT_CALL _aligned_free(void *memory);\nV_CRT_LINKAGE unsigned short * V_CRT_CALL _wgetenv(const unsigned short *varname);\nV_CRT_LINKAGE int V_CRT_CALL _wputenv(const unsigned short *envstring);\n#endif'), generated_c
26
27 assert generated_c.contains('V_CRT_LINKAGE void V_CRT_CALL perror(const char *str);'), generated_c
28 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL mkstemp(char *stemplate);'), generated_c
29 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL strcmp(const char *left, const char *right);'), generated_c
30 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL strncmp(const char *left, const char *right, size_t n);'), generated_c
31 assert generated_c.contains('V_CRT_LINKAGE char * V_CRT_CALL strstr(const char *haystack, const char *needle);'), generated_c
32 assert generated_c.contains('#if !defined(_WIN32) && !defined(_WIN64) && !defined(__BIONIC__)'), generated_c
33 assert generated_c.contains('V_CRT_LINKAGE char * V_CRT_CALL strdup(const char *str);'), generated_c
34 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL rand(void);'), generated_c
35 assert generated_c.contains('V_CRT_LINKAGE void V_CRT_CALL srand(unsigned int seed);'), generated_c
36 assert generated_c.contains('RAND_MAX = 2147483647'), generated_c
37 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL abs(int n);'), generated_c
38 assert generated_c.contains('V_CRT_LINKAGE double V_CRT_CALL atof(const char *str);'), generated_c
39 assert generated_c.contains('extern FILE* stdout;'), generated_c
40 assert generated_c.contains('#define stdout (__acrt_iob_func(1))'), generated_c
41 assert generated_c.contains('#if (defined(_MSC_VER) && !defined(__clang__)) || defined(__cplusplus)\n// Under C++ (g++/clang++), let libc declare FILE/stdio/string/stdlib to keep\n// noexcept specifiers consistent'), generated_c
42 assert generated_c.contains('#if defined(_MSC_VER) && !defined(__clang__)\n\t#define V_CRT_LINKAGE __declspec(dllimport)\n\t#define V_CRT_CALL VCALLCONV(cdecl)\n#else\n\t#define V_CRT_LINKAGE\n\t#define V_CRT_CALL\n#endif'), generated_c
43 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL _vscprintf(const char *format, va_list ap);'), generated_c
44 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL _vsnprintf_s(char *buffer, size_t size, size_t count, const char *format, va_list ap);'), generated_c
45 assert generated_c.contains('V_CRT_LINKAGE void * V_CRT_CALL _aligned_malloc(size_t size, size_t alignment);'), generated_c
46 assert generated_c.contains('V_CRT_LINKAGE void * V_CRT_CALL _aligned_realloc(void *memory, size_t size, size_t alignment);'), generated_c
47 assert generated_c.contains('V_CRT_LINKAGE void V_CRT_CALL _aligned_free(void *memory);'), generated_c
48 assert generated_c.contains('V_CRT_LINKAGE unsigned short * V_CRT_CALL _wgetenv(const unsigned short *varname);'), generated_c
49 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL _wputenv(const unsigned short *envstring);'), generated_c
50 assert generated_c.contains('#elif defined(__MINGW32__) || defined(__MINGW64__) || (defined(__clang__) && (defined(_WIN32) || defined(_WIN64)))\ntypedef struct _iobuf FILE;\nFILE* __cdecl __acrt_iob_func(unsigned index);\n#define stdin (__acrt_iob_func(0))\n#define stdout (__acrt_iob_func(1))\n#define stderr (__acrt_iob_func(2))'), generated_c
51 assert generated_c.contains('#elif defined(__TINYC__) && (defined(_WIN32) || defined(_WIN64))'), generated_c
52 assert generated_c.contains('#ifndef _FILE_DEFINED\nstruct _iobuf {\n\tchar *_ptr;\n\tint _cnt;\n\tchar *_base;\n\tint _flag;\n\tint _file;\n\tint _charbuf;\n\tint _bufsiz;\n\tchar *_tmpfname;\n};\ntypedef struct _iobuf FILE;\n#define _FILE_DEFINED'), generated_c
53 assert generated_c.contains('FILE* __cdecl __iob_func(void);'), generated_c
54 assert generated_c.contains('extern FILE (*_imp___iob)[];'), generated_c
55 assert generated_c.contains('#define stdout (&__iob_func()[1])'), generated_c
56 assert generated_c.contains('#elif defined(__vinix__)\ntypedef struct __file FILE;\nextern FILE* stdin;\nextern FILE* stdout;\nextern FILE* stderr;\nstruct __thread_data;\nstruct __threadattr;'), generated_c
57 assert generated_c.contains('#if defined(__STDC_HOSTED__) && __STDC_HOSTED__ && defined(__has_include) && __has_include(<pthread.h>)\n#include <pthread.h>\n#else\ntypedef struct __thread_data *pthread_t;\n#endif\ntypedef __builtin_va_list va_list;'), generated_c
58 assert generated_c.contains('#if defined(__APPLE__) || defined(__FreeBSD__)\ntypedef struct __sFILE FILE;\nextern FILE* __stdinp;\nextern FILE* __stdoutp;\nextern FILE* __stderrp;\n#define stdin __stdinp\n#define stdout __stdoutp\n#define stderr __stderrp'), generated_c
59 assert generated_c.contains('#elif defined(__NetBSD__) || defined(__DragonFly__)\ntypedef struct __sFILE FILE;\nextern FILE* __stdinp;\nextern FILE* __stdoutp;\nextern FILE* __stderrp;\n#define stdin __stdinp\n#define stdout __stdoutp\n#define stderr __stderrp'), generated_c
60 assert generated_c.contains('#elif defined(__OpenBSD__)\ntypedef struct __sFILE FILE;\n#ifndef _STDFILES_DECLARED\n\t#define _STDFILES_DECLARED\nstruct __sFstub { long _stub; };\nextern struct __sFstub __stdin[];\nextern struct __sFstub __stdout[];\nextern struct __sFstub __stderr[];\n#endif\n#define stdin ((struct __sFILE *)__stdin)\n#define stdout ((struct __sFILE *)__stdout)\n#define stderr ((struct __sFILE *)__stderr)'), generated_c
61 assert generated_c.contains('#elif defined(__linux__) && !defined(__GLIBC__) && !defined(__GNU_LIBRARY__) && !defined(__BIONIC__) && !defined(__UCLIBC__)\ntypedef struct _IO_FILE FILE;\n// musl exposes the stdio streams as `FILE *const`, so match that to stay\n// compatible with later <stdio.h> includes from headers like miniz.h.\nextern FILE* const stdin;\nextern FILE* const stdout;\nextern FILE* const stderr'), generated_c
62 assert generated_c.contains('#if (!defined(_MSC_VER) || defined(__clang__)) && !defined(__cplusplus)'), generated_c
63 assert generated_c.contains('#if defined(__vinix__)\nV_CRT_LINKAGE char * V_CRT_CALL fgets(char *str, size_t size, FILE *stream);\n#else\nV_CRT_LINKAGE char * V_CRT_CALL fgets(char *str, int size, FILE *stream);'), generated_c
64 assert generated_c.contains('#if defined(__vinix__)\nV_CRT_LINKAGE int V_CRT_CALL strcmp(char *left, char *right);\nV_CRT_LINKAGE int V_CRT_CALL strncmp(char *left, char *right, size_t n);\n#else\nV_CRT_LINKAGE int V_CRT_CALL strcmp(const char *left, const char *right);'), generated_c
65}
66
67fn test_android_prelude_uses_bionic_file_decls() {
68 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_android_${os.getpid()}')
69 os.mkdir_all(tmp_dir)!
70 defer {
71 os.rmdir_all(tmp_dir) or {}
72 }
73 source_path := os.join_path(tmp_dir, 'android.v')
74 output_path := os.join_path(tmp_dir, 'android.c')
75 os.write_file(source_path, 'fn main() {\n\tprintln("hi")\n}\n')!
76 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -os android -apk -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
77 res := os.execute(cmd)
78 assert res.exit_code == 0, '${cmd}\n${res.output}'
79 generated_c := os.read_file(output_path)!.replace('\r\n', '\n')
80 assert generated_c.contains('#elif defined(__BIONIC__)\nstruct __sFILE;\ntypedef struct __sFILE FILE;\nextern FILE* stdin;\nextern FILE* stdout;\nextern FILE* stderr;'), generated_c
81 assert !generated_c.contains('extern FILE __sF[];'), generated_c
82 assert !generated_c.contains('#elif defined(__BIONIC__)\ntypedef struct _IO_FILE FILE;'), generated_c
83}
84
85fn test_vinix_prelude_leaves_stdio_and_stdlib_to_vinix_stubs() {
86 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_vinix_${os.getpid()}')
87 os.mkdir_all(tmp_dir)!
88 defer {
89 os.rmdir_all(tmp_dir) or {}
90 }
91 source_path := os.join_path(tmp_dir, 'vinix.v')
92 output_path := os.join_path(tmp_dir, 'vinix.c')
93 os.write_file(source_path,
94 ['fn C.printf_panic(charptr, ...voidptr)', 'fn C.text_start()', 'fn C.__builtin_return_address(int) voidptr', '', 'fn main() {', "\tC.printf_panic(c'%d', voidptr(1))", '\t_ = voidptr(C.text_start)', '\t_ = C.__builtin_return_address(0)', '}'].join('\n') +
95 '\n')!
96 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -os vinix -d no_backtrace -gc none -manualfree -enable-globals -nofloat -experimental -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
97 res := os.execute(cmd)
98 assert res.exit_code == 0, '${cmd}\n${res.output}'
99 generated_c := os.read_file(output_path)!.replace('\r\n', '\n')
100 assert generated_c.contains('#elif defined(__vinix__)\ntypedef struct __file FILE;\nextern FILE* stdin;\nextern FILE* stdout;\nextern FILE* stderr;\nstruct __thread_data;\nstruct __threadattr;'), generated_c
101 assert generated_c.contains('#if defined(__STDC_HOSTED__) && __STDC_HOSTED__ && defined(__has_include) && __has_include(<pthread.h>)\n#include <pthread.h>\n#else\ntypedef struct __thread_data *pthread_t;\n#endif\ntypedef __builtin_va_list va_list;'), generated_c
102 assert generated_c.contains('#if (!defined(_MSC_VER) || defined(__clang__)) && !defined(__cplusplus)'), generated_c
103 assert generated_c.contains('extern void printf_panic(charptr _d1, ... );'), generated_c
104 assert !generated_c.contains('extern void printf_panic(charptr _d1, Array_voidptr _d2);'), generated_c
105 assert !generated_c.contains('extern void text_start();'), generated_c
106 assert !generated_c.contains('extern voidptr __builtin_return_address(int _d1);'), generated_c
107 assert !generated_c.contains('builtin__unbuffer_stdout();'), generated_c
108}
109
110fn test_msvc_windows_prelude_uses_msvc_crt_headers() {
111 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_msvc_windows_${os.getpid()}')
112 os.mkdir_all(tmp_dir)!
113 defer {
114 os.rmdir_all(tmp_dir) or {}
115 }
116 source_path := os.join_path(tmp_dir, 'hello.v')
117 output_path := os.join_path(tmp_dir, 'hello.c')
118 os.write_file(source_path, 'fn main() {\n\tprintln("hi")\n}\n')!
119 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -cc msvc -os windows -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
120 res := os.execute(cmd)
121 assert res.exit_code == 0, '${cmd}\n${res.output}'
122 generated_c := os.read_file(output_path)!.replace('\r\n', '\n')
123 assert generated_c.contains('#if (defined(_MSC_VER) && !defined(__clang__)) || defined(__cplusplus)\n// Under C++ (g++/clang++), let libc declare FILE/stdio/string/stdlib to keep\n// noexcept specifiers consistent'), generated_c
124 assert !generated_c.contains('V_CRT_IMPORT'), generated_c
125 assert !generated_c.contains('#if defined(_MSC_VER) && !defined(__clang__)\ntypedef struct _iobuf FILE;'), generated_c
126 assert generated_c.contains('#ifndef va_copy\n\t#define va_copy(dest, src) ((dest) = (src))\n#endif\n#ifndef _TRUNCATE'), generated_c
127 assert generated_c.contains('#if defined(_MSC_VER) && !defined(__clang__)\n\t#define V_CRT_LINKAGE __declspec(dllimport)\n\t#define V_CRT_CALL VCALLCONV(cdecl)\n#else\n\t#define V_CRT_LINKAGE\n\t#define V_CRT_CALL\n#endif'), generated_c
128 assert generated_c.contains('#if (!defined(_MSC_VER) || defined(__clang__)) && !defined(__cplusplus)\n// mingw-w64 stdio.h declares these as static __mingw_ovr inline overrides'), generated_c
129 assert generated_c.contains('#if !((defined(__MINGW32__) || defined(__MINGW64__)) && !defined(__clang__))\nV_CRT_LINKAGE int V_CRT_CALL vfprintf(FILE *stream, const char *format, va_list ap);'), generated_c
130 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL _vscprintf(const char *format, va_list ap);'), generated_c
131 assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL _vsnprintf_s(char *buffer, size_t size, size_t count, const char *format, va_list ap);'), generated_c
132 assert generated_c.contains('#include <windows.h>'), generated_c
133}
134
135fn test_msvc_windows_splits_large_string_const_literals() {
136 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_msvc_long_string_${os.getpid()}')
137 os.mkdir_all(tmp_dir)!
138 defer {
139 os.rmdir_all(tmp_dir) or {}
140 }
141 long_text := 'a'.repeat(25000)
142 source_path := os.join_path(tmp_dir, 'long_string.v')
143 output_path := os.join_path(tmp_dir, 'long_string.c')
144 os.write_file(source_path,
145 "const long_literal = '${long_text}'\n\nfn main() {\n\tassert long_literal.len == ${long_text.len}\n}\n")!
146 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -cc msvc -os windows -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
147 res := os.execute(cmd)
148 assert res.exit_code == 0, '${cmd}\n${res.output}'
149 generated_c := os.read_file(output_path)!.replace('\r\n', '\n')
150 marker := 'long_literal = _S('
151 start := generated_c.index(marker) or {
152 assert false, generated_c
153 return
154 }
155 line := generated_c[start..].all_before(');')
156 assert line.contains('" "'), line
157 assert !line.contains('a'.repeat(20000)), line
158}
159
160fn test_manual_stdio_decls_do_not_conflict_with_later_stdio_includes() {
161 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_${os.getpid()}')
162 os.mkdir_all(tmp_dir)!
163 defer {
164 os.rmdir_all(tmp_dir) or {}
165 }
166 output_path := os.join_path(tmp_dir, 'shadowed_c_fn_call_test')
167 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -o ${os.quoted_path(output_path)} ${os.quoted_path(cheaders_manual_stdlib_stdio_source)}'
168 res := os.execute(cmd)
169 assert res.exit_code == 0, '${cmd}\n${res.output}'
170}
171
172fn test_manual_stdio_decls_allow_headerless_perror_declarations() {
173 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_perror_${os.getpid()}')
174 os.mkdir_all(tmp_dir)!
175 defer {
176 os.rmdir_all(tmp_dir) or {}
177 }
178 source_path := os.join_path(tmp_dir, 'c_perror.v')
179 os.write_file(source_path,
180
181 ['fn C.perror(message &char)', '', 'fn main() {', "\tC.perror(c'')", '}'].join('\n') + '\n')!
182 output_path := os.join_path(tmp_dir, 'c_perror')
183 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
184 res := os.execute(cmd)
185 assert res.exit_code == 0, '${cmd}\n${res.output}'
186}
187
188fn test_manual_stdio_decls_allow_headerless_rand_declarations() {
189 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_rand_${os.getpid()}')
190 os.mkdir_all(tmp_dir)!
191 defer {
192 os.rmdir_all(tmp_dir) or {}
193 }
194 source_path := os.join_path(tmp_dir, 'c_rand.v')
195 os.write_file(source_path,
196 ['fn C.rand() int', 'fn C.srand(seed u32)', '', 'fn main() {', '\tC.srand(1)', '\t_ = C.rand()', '}'].join('\n') +
197 '\n')!
198 output_path := os.join_path(tmp_dir, 'c_rand')
199 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
200 res := os.execute(cmd)
201 assert res.exit_code == 0, '${cmd}\n${res.output}'
202}
203
204fn test_manual_stdio_decls_allow_rand_max_macro_usage() {
205 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_rand_max_${os.getpid()}')
206 os.mkdir_all(tmp_dir)!
207 defer {
208 os.rmdir_all(tmp_dir) or {}
209 }
210 source_path := os.join_path(tmp_dir, 'c_rand_max.v')
211 os.write_file(source_path,
212 ['const rand_max = C.RAND_MAX', '', 'fn main() {', '\tassert rand_max > 0', '}'].join('\n') +
213 '\n')!
214 output_path := os.join_path(tmp_dir, 'c_rand_max')
215 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
216 res := os.execute(cmd)
217 assert res.exit_code == 0, '${cmd}\n${res.output}'
218}
219
220fn test_manual_stdio_decls_allow_direct_atof_calls() {
221 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_atof_${os.getpid()}')
222 os.mkdir_all(tmp_dir)!
223 defer {
224 os.rmdir_all(tmp_dir) or {}
225 }
226 source_path := os.join_path(tmp_dir, 'c_atof.v')
227 os.write_file(source_path, ['fn main() {', "\t_ = C.atof(c'1.25')", '}'].join('\n') + '\n')!
228 output_path := os.join_path(tmp_dir, 'c_atof')
229 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
230 res := os.execute(cmd)
231 assert res.exit_code == 0, '${cmd}\n${res.output}'
232}
233
234fn test_manual_stdio_decls_allow_translated_direct_abs_calls() {
235 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_abs_${os.getpid()}')
236 os.mkdir_all(tmp_dir)!
237 defer {
238 os.rmdir_all(tmp_dir) or {}
239 }
240 source_path := os.join_path(tmp_dir, 'c_abs.v')
241 os.write_file(source_path, ['fn main() {', '\t_ = C.abs(-7)', '}'].join('\n') + '\n')!
242 output_path := os.join_path(tmp_dir, 'c_abs')
243 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -translated -cc clang -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
244 res := os.execute(cmd)
245 assert res.exit_code == 0, '${cmd}\n${res.output}'
246}
247
248fn test_manual_stdio_decls_allow_translated_direct_strdup_calls() {
249 $if windows {
250 return
251 }
252 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_strdup_${os.getpid()}')
253 os.mkdir_all(tmp_dir)!
254 defer {
255 os.rmdir_all(tmp_dir) or {}
256 }
257 source_path := os.join_path(tmp_dir, 'c_strdup.v')
258 os.write_file(source_path, ['fn main() {', "\t_ = C.strdup(c'abc')", '}'].join('\n') + '\n')!
259 output_path := os.join_path(tmp_dir, 'c_strdup')
260 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -translated -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
261 res := os.execute(cmd)
262 assert res.exit_code == 0, '${cmd}\n${res.output}'
263}
264
265fn test_manual_stdio_decls_allow_translated_direct_strncmp_calls() {
266 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_strncmp_${os.getpid()}')
267 os.mkdir_all(tmp_dir)!
268 defer {
269 os.rmdir_all(tmp_dir) or {}
270 }
271 source_path := os.join_path(tmp_dir, 'c_strncmp.v')
272 os.write_file(source_path,
273
274 ['fn main() {', "\t_ = C.strncmp(c'abc', c'abd', 2)", '}'].join('\n') + '\n')!
275 output_path := os.join_path(tmp_dir, 'c_strncmp')
276 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -translated -cc clang -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
277 res := os.execute(cmd)
278 assert res.exit_code == 0, '${cmd}\n${res.output}'
279}
280
281fn test_c_prelude_ctype_decls_do_not_conflict_with_later_ctype_includes() {
282 $if !linux {
283 return
284 }
285 tmp_dir := os.join_path(os.vtmp_dir(), 'cheaders_manual_stdlib_ctype_${os.getpid()}')
286 os.mkdir_all(tmp_dir)!
287 defer {
288 os.rmdir_all(tmp_dir) or {}
289 }
290 source_path := os.join_path(tmp_dir, 'c_ctype.v')
291 os.write_file(source_path,
292 ['fn C.__ctype_b_loc() &&u16', '', 'fn main() {', '\tC.__ctype_b_loc()', '}'].join('\n') +
293 '\n')!
294 output_path := os.join_path(tmp_dir, 'c_ctype')
295 cmd := '${os.quoted_path(cheaders_manual_stdlib_vexe)} -cc clang -show-c-output -o ${os.quoted_path(output_path)} ${os.quoted_path(source_path)}'
296 res := os.execute(cmd)
297 assert res.exit_code == 0, '${cmd}\n${res.output}'
298}
299