Repository navigation
CI: Check positional printf arguments on Windows #722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
760cb16
CI: Check positional printf arguments on Windows
echoix 664c5fe
CI: Use _sprintf_p in positional printf check
echoix 7c696cc
CI: Also test disabled MinGW ANSI stdio in printf check
echoix cfcc61a
CI: Test libintl for positional printf arguments
echoix 8c2fbef
CI: Inspect vcpkg libintl exports in printf check
echoix File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,129 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Throwaway check: do POSIX positional printf arguments work here? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Results are printed as PASS/FAIL lines; the exit status is always 0. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Optional defines: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * USE_LIBINTL include <libintl.h> first and report its redirects | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * TEST_LIBINTL_DIRECT also call libintl_snprintf()/libintl_vsnprintf() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef USE_LIBINTL | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <libintl.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <inttypes.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <stdarg.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <stdint.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <stdio.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <string.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #define BUFSZ 128 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef TEST_LIBINTL_DIRECT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Declared here in case libintl.h only declares them conditionally. */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extern int libintl_snprintf(char *, size_t, const char *, ...); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extern int libintl_vsnprintf(char *, size_t, const char *, va_list); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static void report(const char *func, const char *fmt, const char *result, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const char *expected) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("%s: func=%s format=\"%s\" result=\"%s\" expected=\"%s\"\n", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| strcmp(result, expected) == 0 ? "PASS" : "FAIL", func, fmt, result, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expected); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Mimics G_vasprintf(): formats through a va_list function. */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #define DEFINE_WRAPPER(name, vfunc) \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static int name(char *buf, size_t n, const char *fmt, ...) \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| va_list ap; \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int ret; \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| va_start(ap, fmt); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ret = vfunc(buf, n, fmt, ap); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| va_end(ap); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ret; \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DEFINE_WRAPPER(wrap_vsnprintf, vsnprintf) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef TEST_LIBINTL_DIRECT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DEFINE_WRAPPER(wrap_libintl_vsnprintf, libintl_vsnprintf) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef _MSC_VER | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DEFINE_WRAPPER(wrap_vsprintf_p, _vsprintf_p) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Runs all formats through fn(buf, size, fmt, args...). */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #define RUN_CASES(label, fn) \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| do { \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| memset(buf, 0, sizeof buf); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn(buf, sizeof buf, "%2$s %1$s", "a", "b"); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| report(label, "%2$s %1$s", buf, "b a"); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| memset(buf, 0, sizeof buf); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn(buf, sizeof buf, "%2$d %1$s", "x", 42); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| report(label, "%2$d %1$s", buf, "42 x"); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| memset(buf, 0, sizeof buf); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn(buf, sizeof buf, "%2$lu %1$llu", 5ULL, 7UL); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| report(label, "%2$lu %1$llu", buf, "7 5"); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| memset(buf, 0, sizeof buf); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn(buf, sizeof buf, "%2$" PRIu64 " %1$s", "x", (uint64_t)123); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| report(label, "%2$" PRIu64 " %1$s", buf, "123 x"); \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+55
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [pre-commit] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } while (0) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int main(void) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| char buf[BUFSZ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef _MSC_VER | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("compiler: MSVC _MSC_VER=%d\n", _MSC_VER); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef __GNUC__ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("compiler: GCC %d.%d\n", __GNUC__, __GNUC_MINOR__); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef _UCRT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("runtime: _UCRT defined\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("runtime: _UCRT not defined\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef __USE_MINGW_ANSI_STDIO | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("__USE_MINGW_ANSI_STDIO=%d\n", __USE_MINGW_ANSI_STDIO); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("__USE_MINGW_ANSI_STDIO not defined\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef USE_LIBINTL | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("libintl.h included first\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef snprintf | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("snprintf IS a macro after libintl.h\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("snprintf is NOT a macro after libintl.h\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef vsnprintf | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("vsnprintf IS a macro after libintl.h\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("vsnprintf is NOT a macro after libintl.h\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef _INTL_REDIRECT_MACROS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("_INTL_REDIRECT_MACROS is defined\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("_INTL_REDIRECT_MACROS is not defined\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef _INTL_NO_REDIRECT_PRINTF | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("_INTL_NO_REDIRECT_PRINTF is defined\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf("_INTL_NO_REDIRECT_PRINTF is not defined\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN_CASES("snprintf", snprintf); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN_CASES("vsnprintf(wrapper)", wrap_vsnprintf); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef TEST_LIBINTL_DIRECT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN_CASES("libintl_snprintf", libintl_snprintf); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN_CASES("libintl_vsnprintf(wrapper)", wrap_libintl_vsnprintf); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef _MSC_VER | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN_CASES("_sprintf_p", _sprintf_p); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN_CASES("_vsprintf_p(wrapper)", wrap_vsprintf_p); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| --- | ||
| name: Positional printf check | ||
|
|
||
| # Throwaway check of POSIX positional printf arguments on Windows toolchains. | ||
| on: | ||
| workflow_dispatch: | ||
| pull_request: | ||
| paths: | ||
| - .github/workflows/positional_printf_check.yml | ||
| - .github/scripts/positional_printf_check.c | ||
|
|
||
| permissions: {} | ||
|
|
||
| jobs: | ||
| msvc: | ||
| name: MSVC | ||
| runs-on: windows-latest | ||
| steps: | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| - uses: ilammy/msvc-dev-cmd@a102174a2b586eec2ea151a69e6fd14404a8ce7c # v1.13.0 | ||
| - name: Compile | ||
| shell: cmd | ||
| run: cl /nologo /W3 .github\scripts\positional_printf_check.c /Fe:check.exe | ||
| - name: Run | ||
| shell: cmd | ||
| run: check.exe | ||
| - name: Install libintl with vcpkg | ||
| id: vcpkg | ||
| continue-on-error: true | ||
| shell: cmd | ||
| run: vcpkg install gettext-libintl:x64-windows | ||
| - name: Compile with libintl | ||
| if: steps.vcpkg.outcome == 'success' | ||
| continue-on-error: true | ||
| shell: cmd | ||
| run: | | ||
| set VPREFIX=%VCPKG_INSTALLATION_ROOT%\installed\x64-windows | ||
| dir %VPREFIX%\include\libintl.h %VPREFIX%\lib\*intl* %VPREFIX%\bin\*intl* | ||
| findstr /n /i "define.*printf _INTL_REDIRECT" %VPREFIX%\include\libintl.h | ||
| dumpbin /exports %VPREFIX%\bin\intl-8.dll | findstr /i "printf" | ||
| cl /nologo /W3 /DUSE_LIBINTL /I%VPREFIX%\include .github\scripts\positional_printf_check.c /Fe:check_intl.exe /link /LIBPATH:%VPREFIX%\lib intl.lib | ||
| cl /nologo /W3 /DUSE_LIBINTL /DTEST_LIBINTL_DIRECT /I%VPREFIX%\include .github\scripts\positional_printf_check.c /Fe:check_intl_direct.exe /link /LIBPATH:%VPREFIX%\lib intl.lib | ||
| - name: Run with libintl | ||
| if: steps.vcpkg.outcome == 'success' | ||
| continue-on-error: true | ||
| shell: cmd | ||
| run: | | ||
| set PATH=%VCPKG_INSTALLATION_ROOT%\installed\x64-windows\bin;%PATH% | ||
| check_intl.exe | ||
|
|
||
| mingw: | ||
| name: MinGW64 (MSYS2) | ||
| runs-on: windows-latest | ||
| defaults: | ||
| run: | ||
| shell: msys2 {0} | ||
| steps: | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| - uses: msys2/setup-msys2@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2.33.0 | ||
| with: | ||
| msystem: MINGW64 | ||
| update: false | ||
| install: >- | ||
| mingw-w64-x86_64-gcc | ||
| mingw-w64-x86_64-gettext-runtime | ||
| mingw-w64-x86_64-gettext-tools | ||
| - name: Compile | ||
| run: | | ||
| gcc -Wall -DUSE_LIBINTL -DTEST_LIBINTL_DIRECT -o check_intl.exe .github/scripts/positional_printf_check.c -lintl | ||
| gcc -Wall -D__USE_MINGW_ANSI_STDIO=0 -DUSE_LIBINTL -DTEST_LIBINTL_DIRECT -o check_intl_msvcrt.exe .github/scripts/positional_printf_check.c -lintl | ||
| gcc -Wall -o check_default.exe .github/scripts/positional_printf_check.c | ||
| gcc -Wall -D__USE_MINGW_ANSI_STDIO=1 -o check_ansi.exe .github/scripts/positional_printf_check.c | ||
| gcc -Wall -D__USE_MINGW_ANSI_STDIO=0 -o check_msvcrt.exe .github/scripts/positional_printf_check.c | ||
| - name: Run with default __USE_MINGW_ANSI_STDIO | ||
| run: ./check_default.exe | ||
| - name: Run with __USE_MINGW_ANSI_STDIO=1 | ||
| run: ./check_ansi.exe | ||
| - name: Run with __USE_MINGW_ANSI_STDIO=0 | ||
| run: ./check_msvcrt.exe | ||
| - name: Show libintl.h printf redirects | ||
| run: | | ||
| ls -l /mingw64/include/libintl.h | ||
| grep -n -i "define.*printf\|_INTL_REDIRECT\|_INTL_NO_REDIRECT" /mingw64/include/libintl.h | ||
| - name: Run with libintl.h | ||
| run: ./check_intl.exe | ||
| - name: Run with libintl.h and __USE_MINGW_ANSI_STDIO=0 | ||
| run: ./check_intl_msvcrt.exe |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[pre-commit] reported by reviewdog 🐶