On Sat, 28 Sep 2024, Pali Rohár wrote:

All non-UCRT crt library versions provide wcstok symbol which is not C95+
compatible. Its function prototype is missing the third argument. In UCRT
version this function without third argument is named _wcstok(). So rename
wcstok symbol to _wcstok in all non-UCRT import libraries for compatibility
with UCRT.

msvcr80+ provides wcstok_s symbol which is C95+ compatible wcstok()
function. msvcr80+ wcstok_s() function has same function prototype as C95+
wcstok() and the only difference between MS wcstok_s and C95 wcstok is that
MS wcstok_s validates parameters and sets errno. C95 version has undefined
behavior when called with invalid parameters (e.g. Linux version crashes).

So add appropriate aliases of wcstok_s in msvcr80+ import libraries to have
C95+ compatible wcstok() function under the correct C95 name wcstok.

For pre-msvcr80 import libraries, provide mingw-w64 implementation of
wcstok_s() and C95+ wcstok() functions. So when linking with any crt
library, the wcstok symbol resolve to the correct C95 compatible wcstok()
function. mingw-w64 implementation of wcstok is copied from musl libc which
is very compact and some parts from musl libc are already used in mingw-w64.

Update header files to reflect these changes. With this change, C95+
compatible wcstok() function is available for all builds, not only UCRT as
it was before this change.

For compatibility with C99, add missing restrict keyword for last wcstok()
argument in header files.

mingw-w64 is currently missing MS _wcstok() function for UCRT builds.
So provide it into UCRT import libraries.

Visual Studio 2015+ redefines wcstok() to _wcstok() when macro
_CRT_NON_CONFORMING_WCSTOK is defined. And in C++ mode it provides
overloaded C++ function wcstok() with two arguments unless the macro
_CRT_NO_INLINE_DEPRECATED_WCSTOK is defined. It is documented on:
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strtok-strtok-l-wcstok-wcstok-l-mbstok-mbstok-l

Implement same logic for _CRT_NON_CONFORMING_WCSTOK to get the old behavior
by default. And provides C++ inline two-argument function unless define
_CRT_NO_INLINE_DEPRECATED_WCSTOK is set.

With this change mingw-w64 always provides C95+ compatible wcstok()
function and MS two-arg _wcstok() function in all CRT import libraries.
Also every CRT import library provides MS wcstok_s() function.
---
mingw-w64-crt/Makefile.am                    | 27 ++++++++-----
mingw-w64-crt/def-include/crt-aliases.def.in |  5 +++
mingw-w64-crt/lib-common/msvcr120_app.def.in |  3 +-
mingw-w64-crt/lib-common/msvcrt.def.in       |  7 +++-
mingw-w64-crt/lib32/crtdll.def.in            |  2 +-
mingw-w64-crt/lib32/msvcr100.def.in          |  3 +-
mingw-w64-crt/lib32/msvcr100d.def.in         |  3 +-
mingw-w64-crt/lib32/msvcr110.def.in          |  3 +-
mingw-w64-crt/lib32/msvcr110d.def.in         |  3 +-
mingw-w64-crt/lib32/msvcr120.def.in          |  3 +-
mingw-w64-crt/lib32/msvcr120d.def.in         |  3 +-
mingw-w64-crt/lib32/msvcr40d.def.in          |  2 +-
mingw-w64-crt/lib32/msvcr70.def.in           |  2 +-
mingw-w64-crt/lib32/msvcr70d.def.in          |  2 +-
mingw-w64-crt/lib32/msvcr71.def.in           |  2 +-
mingw-w64-crt/lib32/msvcr71d.def.in          |  2 +-
mingw-w64-crt/lib32/msvcr80.def.in           |  3 +-
mingw-w64-crt/lib32/msvcr80d.def.in          |  3 +-
mingw-w64-crt/lib32/msvcr90.def.in           |  3 +-
mingw-w64-crt/lib32/msvcr90d.def.in          |  3 +-
mingw-w64-crt/lib32/msvcrt10.def.in          |  2 +-
mingw-w64-crt/lib32/msvcrt20.def.in          |  2 +-
mingw-w64-crt/lib32/msvcrt40.def.in          |  2 +-
mingw-w64-crt/lib32/msvcrtd.def.in           |  2 +-
mingw-w64-crt/lib64/msvcr100.def.in          |  3 +-
mingw-w64-crt/lib64/msvcr100d.def.in         |  3 +-
mingw-w64-crt/lib64/msvcr110.def.in          |  3 +-
mingw-w64-crt/lib64/msvcr110d.def.in         |  3 +-
mingw-w64-crt/lib64/msvcr120.def.in          |  3 +-
mingw-w64-crt/lib64/msvcr120d.def.in         |  3 +-
mingw-w64-crt/lib64/msvcr80.def.in           |  3 +-
mingw-w64-crt/lib64/msvcr80d.def.in          |  3 +-
mingw-w64-crt/lib64/msvcr90.def.in           |  3 +-
mingw-w64-crt/lib64/msvcr90d.def.in          |  3 +-
mingw-w64-crt/libarm32/msvcr110.def.in       |  3 +-
mingw-w64-crt/libarm32/msvcr110d.def.in      |  3 +-
mingw-w64-crt/libarm32/msvcr120.def.in       |  3 +-
mingw-w64-crt/libarm32/msvcr120d.def.in      |  3 +-
mingw-w64-crt/string/ucrt__wcstok.c          | 14 +++++++
mingw-w64-crt/string/wcstok.c                | 41 ++++++++++++++++++++
mingw-w64-headers/crt/string.h               | 11 ++++--
mingw-w64-headers/crt/wchar.h                | 11 ++++--
42 files changed, 157 insertions(+), 54 deletions(-)
create mode 100644 mingw-w64-crt/string/ucrt__wcstok.c
create mode 100644 mingw-w64-crt/string/wcstok.c


diff --git a/mingw-w64-crt/lib-common/msvcr120_app.def.in 
b/mingw-w64-crt/lib-common/msvcr120_app.def.in
index 4508a43f3370..eadcda310ad8 100644
--- a/mingw-w64-crt/lib-common/msvcr120_app.def.in
+++ b/mingw-w64-crt/lib-common/msvcr120_app.def.in
@@ -2310,7 +2310,7 @@ wcsstr
wcstod
wcstof
wcstoimax
-wcstok
+_wcstok == wcstok ; rename wcstok to _wcstok for compatibility with UCRT, real 
C95+ compatible wcstok provided by wcstok_s alias

This comment is a bit hard to understand, and as this text is copypasted a number of times, it would be good to get it understandable enough from the start.

What about this description?

Provide the nonstandard function with the name "wcstok" in the DLL, under the name "_wcstok" to match the corresponding function in UCRT. The real C95+ compatible wcstok is provided by (mingw-w64 or wcstok_s alias)

// Martin

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to