Skip to content

Commit 5d593c0

Browse files
committed
cgen: include stdio for GCC MinGW prelude
1 parent 099040e commit 5d593c0

2 files changed

Lines changed: 7 additions & 1 deletion

File tree

vlib/v/gen/c/cheaders.v

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@ extern struct __sFstub __stderr[];
429429
#define stdout ((struct __sFILE *)__stdout)
430430
#define stderr ((struct __sFILE *)__stderr)
431431
#endif
432+
#elif (defined(__MINGW32__) || defined(__MINGW64__)) && defined(__V_GCC__)
433+
// mingw-w64 stdio.h provides fprintf/vfprintf as static inline overrides
434+
// when __USE_MINGW_ANSI_STDIO is enabled, so use the system declarations
435+
// instead of the manual formatted-stdio prototypes below.
436+
#include <stdio.h>
432437
#elif defined(__MINGW32__) || defined(__MINGW64__) || (defined(__clang__) && (defined(_WIN32) || defined(_WIN64)))
433438
typedef struct _iobuf FILE;
434439
FILE* __cdecl __acrt_iob_func(unsigned index);

vlib/v/gen/c/cheaders_manual_stdlib_decls_test.v

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ fn test_default_c_prelude_uses_manual_stdio_stdlib_string_and_stdarg_decls() {
4747
assert generated_c.contains('V_CRT_LINKAGE void V_CRT_CALL _aligned_free(void *memory);'), generated_c
4848
assert generated_c.contains('V_CRT_LINKAGE unsigned short * V_CRT_CALL _wgetenv(const unsigned short *varname);'), generated_c
4949
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(__V_GCC__)\n// mingw-w64 stdio.h provides fprintf/vfprintf as static inline overrides\n// when __USE_MINGW_ANSI_STDIO is enabled, so use the system declarations\n// instead of the manual formatted-stdio prototypes below.\n#include <stdio.h>\n#elif defined(__MINGW32__) || defined(__MINGW64__) || (defined(__clang__) && (defined(_WIN32) || defined(_WIN64)))'), generated_c
5051
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
5152
assert generated_c.contains('#elif defined(__TINYC__) && (defined(_WIN32) || defined(_WIN64))'), generated_c
5253
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
@@ -59,7 +60,7 @@ fn test_default_c_prelude_uses_manual_stdio_stdlib_string_and_stdarg_decls() {
5960
assert generated_c.contains('#elif 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
6061
assert generated_c.contains('#elif defined(__NetBSD__)\n// NetBSD exposes stdin/stdout/stderr as macros into a single `__sF[3]`\n// array whose element size (sizeof(FILE)) depends on the platform and libc\n// version, so we cannot forward-declare them. The FreeBSD-style\n// `__stdinp/__stdoutp/__stderrp` symbols also do not exist on NetBSD (see\n// vlang/v#27190). Defer to the system headers for FILE, the stdio streams,\n// and the libc prototypes that would otherwise clash with the\n// `__restrict`-qualified declarations in NetBSD libc.\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>'), generated_c
6162
assert generated_c.contains('#elif defined(__TINYC__) && (defined(__FreeBSD__) || defined(__OpenBSD__))\n// TinyCC reports a hard redefinition error if system OpenSSL pulls in\n// <stdarg.h> after V has provided its own va_start macro. Include it first,\n// but keep V manual FILE declarations on these BSD libc variants.\n#include <stdarg.h>\n#if 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
62-
assert generated_c.contains('#else\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)\n#endif\n#elif defined(__MINGW32__)'), generated_c
63+
assert generated_c.contains('#else\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)\n#endif\n#elif (defined(__MINGW32__) || defined(__MINGW64__)) && defined(__V_GCC__)'), generated_c
6364
assert generated_c.contains('#if (!defined(_MSC_VER) || defined(__clang__)) && !defined(__cplusplus) && !defined(__NetBSD__)'), generated_c
6465
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
6566
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

0 commit comments

Comments
 (0)