OSDN Git Service

Reimplement btowc(), and wctob() functions.
[mingw/mingw-org-wsl.git] / mingwrt / include / wchar.h
index da61e4e..56fe9b8 100644 (file)
@@ -8,7 +8,8 @@
  *
  * Unattributed original source.
  * Adapted by Rob Savoye <rob@cygnus.com>
- * Copyright (C) 1997, 1999-2009, 2011, 2015, 2016, MinGW.org Project.
+ * Copyright (C) 1997, 1999-2009, 2011, 2015, 2016, 2018-2020,
+ *   MinGW.org Project.
  *
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -80,7 +81,7 @@
  * retrieve the overlapping content, without requiring duplication of
  * that content here; thus, from...
  */
-#include <stdio.h>
+#include "stdio.h"
 /* ...we obtain (possibly indirect) definitions and declarations for:
  *
  *  macros  NULL, FILENAME_MAX
  *
  * In similar fashion, from...
  */
-#include <stdlib.h>
+#include "stdlib.h"
 /* ...we obtain prototypes for universally supported functions:
  *
  *  long wcstol (const wchar_t *, wchar_t **, int);
  *        );
  *  wchar_t *_wfullpath (wchar_t *, const wchar_t *, size_t);
  *
+ * ...with this pair requiring either WinXP (or later), or one of
+ * the non-free MSVC runtimes from MSVCR70.DLL onwards:
+ *
+ *  __int64 _wcstoi64 (const wchar_t *, wchar_t **, int);
+ *  unsigned __int64 _wcstoui64 (const wchar_t *, wchar_t **, int);
+ *
+ *  ...and this pair requiring Win-Vista (or later), or a non-free
+ *  MSVC runtime from MSVCR80.DLL onwards:
+ *
+ *  __int64 _wcstoi64_l (const wchar_t *, wchar_t **, int, _locale_t);
+ *  unsigned __int64 _wcstoui64_l (const wchar_t *, wchar_t **,
+ *          int, _locale_t);
+ *        );
+ *
  * ...while this pair are ISO-C99 standards, which are available
  * in libmingwex.a, but not in any version of MSVCRT.DLL, (nor in
  * any of its non-free derivatives prior to MSVCR120.DLL), nor in
  *  long double wcstold (const wchar_t *restrict, wchar_t **restrict);
  *
  *
- * while from...
+ * while...
+ */
+#ifndef __STRICT_ANSI__
+/* ...when NOT compiling with "__STRICT_ANSI__" conformity checking,
+ * from...
  */
-#include <direct.h>
+#include "direct.h"
 /* ...we obtain prototypes for each of the following functions,
  * (none of which are available when using CRTDLL.DLL):
  *
  *  int _wrmdir (const wchar_t *);
  *
  *
- * From...
+ * while from...
  */
-#include <sys/stat.h>
+#include "sys/stat.h"
 /* ...we obtain function prototypes, and all associated data type
  * definitions for this pair of actual functions, in all versions of
  * MSVCRT.DLL, and its non-free derivatives preceding MSVCR80.DLL, (or
  *  int _wstat64i32 (const wchar_t *, struct _stat64i32 *);
  *
  *
- * while from...
+ * from...
  */
-#include <io.h>
+#include "conio.h"
+/* ...we obtain, depending on active MSVCRT.DLL version conformity,
+ * or non-free run-time version selection, an appropriate subset of:
+ *
+ *   wint_t _getwch (void);
+ *   wint_t _getwche (void);
+ *   wint_t _ungetwch (wint_t);
+ *
+ * ...and for non-free run-times from MSVCR80.DLL onwards only:
+ *
+ *   wint_t _getwch_nolock (void);
+ *   wint_t _getwche_nolock (void);
+ *   wint_t _ungetwch_nolock (wint_t);
+ *
+ *
+ * and from...
+ */
+#include "io.h"
 /* ...we obtain function prototypes for each of the following, which
  * are available in all versions of MSVCRT.DLL, (and all its non-free
  * derivatives), but are not supported by CRTDLL.DLL:
  * ...and these, which are only available in the non-free run-times
  * from MSVCR80.DLL onwards:
  *
- *  intptr_t _wfindfirst32 (wchar_t *, struct __wfinddata32_t *);
- *  int _wfindnext32 (intptr_t, struct __wfinddata32_t *);
+ *  intptr_t _wfindfirst32 (wchar_t *, struct _wfinddata32_t *);
+ *  int _wfindnext32 (intptr_t, struct _wfinddata32_t *);
  *
  *  intptr_t _wfindfirst32i64 (wchar_t *, struct _wfinddata32i64_t *);
  *  int _wfindnext32i64 (intptr_t, struct _wfinddata32i64_t *);
  * and _wfindnext() API, so we also declare the prototype for:
  *
  *  int _findclose (intptr_t);
- *
- *
- * and from...
  */
-#include <time.h>
-/* ...we obtain an opaque forward declaration of:
+#endif /* !__STRICT_ANSI__ */
+
+/* From...
+ */
+#include "time.h"
+/* ...we always obtain an opaque forward declaration of:
  *
  *  struct tm
  *
  * _wctime() itself, as an in-line alias for its corresponding
  * replacement library function.
  *
- *
- * Also, from...
  */
-#include <locale.h>
+#ifndef __STRICT_ANSI__
+/* Once again, when NOT compiling with "__STRICT_ANSI__" conformity
+ * checking, from...
+ */
+#include "locale.h"
 /* ...we obtain the declaration for:
  *
  *   wchar_t *_wsetlocale (int, const wchar_t *);
  *
  * and from...
  */
-#include <process.h>
+#include "process.h"
 /* ...we obtain function prototypes for:
  *
  *  intptr_t _wexecl (const wchar_t *, const wchar_t *, ...);
  *   );
  *
  */
+#endif /* !__STRICT_ANSI__ */
+
 _BEGIN_C_DECLS
 
 /* Wide character string functions must be specified here, as required
@@ -355,10 +396,13 @@ _BEGIN_C_DECLS
  */
 #endif /* ! RC_INVOKED */
 #endif /* !__STRING_H_SOURCED__ */
-#if ! (defined RC_INVOKED || (defined _WCHAR_H && defined _STRING_H))
-/* ...such that these declarations are exposed when either _WCHAR_H, or
- * _STRING_H is defined, (but not both, since that would indicate that
- * these declarations have already been processed).
+#if ! defined RC_INVOKED
+#if !(defined _WCHAR_H && (defined _STRING_H && ! defined __STRICT_ANSI__))
+/* ...such that these declarations are exposed when either _WCHAR_H is defined,
+ * or when _STRING_H is defined and __STRICT_ANSI__ is not, but NOT when BOTH of
+ * these apply, since that indicates that this group of declarations has already
+ * been processed, during partial inclusion of <wchar.h> by <string.h>, whereas
+ * we are now including <wchar.h> in its own right.
  *
  *
  * Wide character versions of the ISO-C standard string functions.
@@ -441,28 +485,62 @@ _CRTIMP __cdecl __MINGW_NOTHROW  wchar_t *wcsupr (wchar_t *);
 #endif /* !_NO_OLDNAMES */
 #endif /* !__STRICT_ANSI__ */
 
+#if _POSIX_C_SOURCE >= 200809L
+#if __MSVCRT_VERSION__ >= __MSVCR80_DLL
+/* MSVCR80.DLL adds a (mostly) POSIX.1-2008 conforming wcsnlen(); (it's
+ * also available in MSVCRT.DLL from _WIN32_WINNT_VISTA onwards, but we
+ * pretend otherwise, since recent GCC will try to use the function when
+ * it can be found in libmsvcrt.a, so breaking it for use on WinXP and
+ * earlier).
+ */
+#ifndef __STRICT_ANSI__   /* N.B.: this is not an ISO-C function */
+_CRTIMP __cdecl __MINGW_NOTHROW  char *wcsnlen (const wchar_t *, size_t);
+#endif
+
+#else  /* MSVCRT.DLL || pre-MSVCR80.DLL */
+/* Emulation, to support recent POSIX.1; we prefer this for ALL versions
+ * of MSVCRT.DLL, (even those which already provide wcsnlen()); to avoid
+ * the GCC breakage noted above.  (Note that we implement wcsnlen() with
+ * the alternative external name, __mingw_wcsnlen() in libmingwex.a, to
+ * avoid possible link time collision with MSVCR80.DLL's implementation,
+ * then map this to wcsnlen() via a __CRT_ALIAS, with stubs designated
+ * for linking from within the appropriate oldname libraries.
+ */
+extern size_t __mingw_wcsnlen (const wchar_t *, size_t);
+
+__JMPSTUB__(( LIB=coldname; FUNCTION=wcsnlen ))
+__CRT_ALIAS size_t wcsnlen (const wchar_t *__text, size_t __maxlen)
+{ return __mingw_wcsnlen (__text, __maxlen); }
+
+#endif /* MSVCRT.DLL || pre-MSVCR80.DLL */
+#endif /* _POSIX_C_SOURCE >= 200809L */
+
 /* This completes the set of declarations which are to be duplicated by
  * inclusion of <string.h>; revert the declarative condition, to make it
  * specific to <wchar.h> alone.
  */
-#endif /* !(RC_INVOKED || (_WCHAR_H && _STRING_H)) */
-#if defined _WCHAR_H && ! defined RC_INVOKED
+#endif /* !(_WCHAR_H && (_STRING_H && !__STRICT_ANSI__)) */
+#endif /* ! RC_INVOKED */
 
+#if defined _WCHAR_H && ! defined RC_INVOKED
 #ifndef __STRICT_ANSI__
 typedef wchar_t  _Wint_t;
 #endif
 
 typedef int mbstate_t;
 
-/* The following multi-byte character conversion functions are
- * implemented in libmingwex.a, (and maybe also in some non-free
- * Microsoft libraries, such as MSVCP60.DLL and later).
+/* The following multi-byte character conversion functions have been
+ * implemented by Microsoft, in non-free MSVCR80.DLL and later, (and
+ * maybe also in some earlier non-free DLLs, such as MSVCP60.DLL and
+ * later); they are also available in MSVCRT.DLL, from Vista onward,
+ * but to provide continuing support for earlier Windows versions,
+ * we invoke them via MinGW specific wrappers, defined below.
  */
 __cdecl __MINGW_NOTHROW  wint_t btowc (int);
 __cdecl __MINGW_NOTHROW  int wctob (wint_t);
 
-__cdecl __MINGW_NOTHROW
-size_t mbrlen (const char *__restrict__, size_t, mbstate_t *__restrict__);
+__cdecl __MINGW_NOTHROW  size_t mbrlen
+(const char *__restrict__, size_t, mbstate_t *__restrict__);
 
 __cdecl __MINGW_NOTHROW  size_t mbrtowc
 (wchar_t *__restrict__, const char *__restrict__, size_t, mbstate_t *__restrict__);
@@ -470,15 +548,102 @@ __cdecl __MINGW_NOTHROW  size_t mbrtowc
 __cdecl __MINGW_NOTHROW  size_t mbsrtowcs
 (wchar_t *__restrict__, const char **__restrict__, size_t, mbstate_t *__restrict__);
 
-__cdecl __MINGW_NOTHROW
-size_t wcrtomb (char * __restrict__, wchar_t, mbstate_t *__restrict__);
+__cdecl __MINGW_NOTHROW  size_t wcrtomb
+(char * __restrict__, wchar_t, mbstate_t *__restrict__);
 
 __cdecl __MINGW_NOTHROW  size_t wcsrtombs
 (char *__restrict__, const wchar_t **__restrict__, size_t, mbstate_t *__restrict__);
 
-#ifdef _ISOC99_SOURCE
+/* To provide support for the above, on legacy Windows versions,
+ * we implement fall back wrappers in libmingwex.a; each of these
+ * will delegate to the corresponding Microsoft implementation, if
+ * it exists in the process address space; otherwise, execution
+ * will fall back to a MinGW implementation...
+ */
+__cdecl __MINGW_NOTHROW  wint_t __msvcrt_btowc (int);
+
+__cdecl __MINGW_NOTHROW  size_t __msvcrt_mbrlen
+(const char *__restrict__, size_t, mbstate_t *__restrict__);
+
+__cdecl __MINGW_NOTHROW  size_t __msvcrt_mbrtowc
+(wchar_t *__restrict__, const char *__restrict__, size_t, mbstate_t *__restrict__);
+
+__cdecl __MINGW_NOTHROW  size_t __msvcrt_mbsrtowcs
+(wchar_t *__restrict__, const char **__restrict__, size_t, mbstate_t *__restrict__);
+
+__cdecl __MINGW_NOTHROW  int __msvcrt_wctob (wint_t);
+
+__cdecl __MINGW_NOTHROW  size_t __msvcrt_wcrtomb
+(char * __restrict__, wchar_t, mbstate_t *__restrict__);
+
+__cdecl __MINGW_NOTHROW  size_t __msvcrt_wcsrtombs
+(char *__restrict__, const wchar_t **__restrict__, size_t, mbstate_t *__restrict__);
+
+/* ...whereas, these alternatives will always invoke the MinGW
+ * fall back implementations, without considering any possible
+ * reference to MSVCRT.DLL or MSVCR80.DLL implementations.
+ */
+__cdecl __MINGW_NOTHROW  wint_t __mingw_btowc (int);
+
+__cdecl __MINGW_NOTHROW  size_t __mingw_mbrlen
+(const char *__restrict__, size_t, mbstate_t *__restrict__);
+
+__cdecl __MINGW_NOTHROW  size_t __mingw_mbrtowc
+(wchar_t *__restrict__, const char *__restrict__, size_t, mbstate_t *__restrict__);
+
+__cdecl __MINGW_NOTHROW  size_t __mingw_mbsrtowcs
+(wchar_t *__restrict__, const char **__restrict__, size_t, mbstate_t *__restrict__);
+
+__cdecl __MINGW_NOTHROW  int __mingw_wctob (wint_t);
+
+__cdecl __MINGW_NOTHROW  size_t __mingw_wcrtomb
+(char * __restrict__, wchar_t, mbstate_t *__restrict__);
+
+__cdecl __MINGW_NOTHROW  size_t __mingw_wcsrtombs
+(char *__restrict__, const wchar_t **__restrict__, size_t, mbstate_t *__restrict__);
+
+#if __MSVCRT_VERSION__ < __MSVCR80_DLL
+/* FIXME: Maybe consider these mappings, even for linking with the
+ * non-free MSVCR80.DLL, and its descendants.
+ *
+ * For linking with all versions of MSVCRT.DLL, and with non-free
+ * alternatives predating MSVCR80.DLL, we enforce inline mapping to
+ * the libmingwex.a implementations, (which will delegate the calls
+ * to the Microsoft DLL implementations, when they are available).
+ */
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  wint_t btowc (int __c)
+{ return __msvcrt_btowc( __c ); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  size_t mbrlen
+(const char *__mbc, size_t __n, mbstate_t *__ps)
+{ return __msvcrt_mbrlen( __mbc, __n, __ps ); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  size_t mbrtowc
+(wchar_t *__wc, const char *__mbc, size_t __n, mbstate_t *__ps)
+{ return __msvcrt_mbrtowc( __wc, __mbc, __n, __ps ); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  size_t mbsrtowcs
+(wchar_t *__wcs, const char **__mbs, size_t __n, mbstate_t *__ps)
+{ return __msvcrt_mbsrtowcs( __wcs, __mbs, __n, __ps ); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  int wctob (wint_t __wc)
+{ return __msvcrt_wctob( __wc ); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  size_t wcrtomb
+(char * __mbc, wchar_t __wc, mbstate_t *__ps)
+{ return __msvcrt_wcrtomb(__mbc, __wc, __ps); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  size_t wcsrtombs
+(char *__mbs, const wchar_t **__wcs, size_t __len, mbstate_t *__ps)
+{ return __msvcrt_wcsrtombs(__mbs, __wcs, __len, __ps); }
+
+#endif /* ! MSVCR80.DLL or later */
+
+#if defined _ISOC99_SOURCE || defined __cplusplus
 /* These ISO-C99 functions are implemented in libmingwex.a,
- * or, in some cases, by inline stubs.
+ * or, in some cases, as inline stubs; while provided as MinGW
+ * extensions to support ISO-C99, they are also required by
+ * GNU C++.
  */
 __cdecl __MINGW_NOTHROW  int fwide (FILE *, int);
 __cdecl __MINGW_NOTHROW  int mbsinit (const mbstate_t *);