OSDN Git Service

Discontinue use of Microsoft's MBCS/wide character converters.
authorKeith Marshall <keith@users.osdn.me>
Sat, 4 Jul 2020 21:06:58 +0000 (22:06 +0100)
committerKeith Marshall <keith@users.osdn.me>
Sat, 4 Jul 2020 21:06:58 +0000 (22:06 +0100)
mingwrt/ChangeLog
mingwrt/include/wchar.h
mingwrt/mingwex/btowc.c
mingwrt/mingwex/mbrconv.c
mingwrt/mingwex/mbrlen.c
mingwrt/mingwex/mbrtowc.c
mingwrt/mingwex/mbsrtowcs.c
mingwrt/mingwex/wcrtomb.c
mingwrt/mingwex/wcsrtombs.c
mingwrt/mingwex/wctob.c

index 919eacd..5be08eb 100644 (file)
@@ -1,3 +1,60 @@
+2020-07-04  Keith Marshall  <keith@users.osdn.me>
+
+       Discontinue use of Microsoft's MBCS/wide character converters.
+
+       * include/wchar.h (__mingw_redirect): Delete macro definition.
+       (__mingw_mbrlen, __msvcrt_mbrlen, __mingw_mbrtowc, __msvcrt_mbrtowc)
+       (__mingw_btowc, __msvcrt_btowc, __mingw_mbsrtowcs, __msvcrt_mbsrtowcs)
+       (__mingw_wctob, __msvcrt_wctob, __mingw_wcrtomb, __msvcrt_wcrtomb)
+       (__mingw_wcsrtombs, __msvcrt_wcsrtombs): Delete prototypes, and...
+       (mbrlen, mbrtowc, btowc, mbsrtowcs, wctomb, wcrtomb, wcsrtombs):
+       ...their corresponding redirected inline implementations.
+
+       * mingwex/btowc.c (__msvcrt_btowc): Delete implementation.
+       (__mingw_btowc_fallback, __mingw_btowc): Fold together, into...
+       (btowc): ...this publicly accessible function; add weak aliases...
+       (__mingw_btowc, __msvcrt_btowc): ...named thus.
+
+       * mingwex/mbrlen.c (__msvcrt_mbrlen): Delete implementation.
+       (__mingw_mbrlen_fallback, __mingw_mbrlen): Fold together, into...
+       (mbrlen): ...this publicly accessible function; factor out codeset
+       and codeset property initializations; add weak aliases...
+       (__mingw_mbrlen, __msvcrt_mbrlen): ...named thus.
+
+       * mingwex/mbrtowc.c (__msvcrt_mbrtowc): Delete implementation.
+       (__mingw_mbrtowc_fallback, __mingw_mbrtowc): Fold together, into...
+       (mbrtowc): ...this publicly accessible function; factor out codeset
+       and codeset property initializations; add weak aliases...
+       (__mingw_mbrtowc, __msvcrt_mbrtowc): ...named thus.
+
+       * mingwex/mbsrtowcs.c (__msvcrt_mbsrtowcs): Delete implementation.
+       (__mingw_mbsrtowcs_fallback, __mingw_mbsrtowcs): Fold; rename as...
+       (mbsrtowcs): ...this publicly accessible function; add weak aliases...
+       (__mingw_mbsrtowcs, __msvcrt_mbsrtowcs): ...named thus.
+       (__mbsrtowcs_fallback): Rename it as...
+       (__mbsrtowcs_internal): ...this.
+
+       * mingwex/mbrconv.c (__mingw_mbrtowc_handler): Initialize codeset.
+
+       * mingwex/wcrtomb.c (__msvcrt_wcrtomb): Delete implementation.
+       (__mingw_wcrtomb_fallback, __mingw_wcrtomb): Fold together, into...
+       (wcrtomb): ...this publicly accessible function; add weak aliases...
+       (__mingw_wcrtomb, __msvcrt_wcrtomb): ...named thus.
+       (__wcrtomb_fallback): Rename it as...
+       (__wcrtomb_internal): ...this.
+
+       * mingwex/wcsrtombs.c (__mingw_wcsrtombs): Rename it as...
+       (wcsrtombs): ...this ISO-C99 name; preserve delegation to...
+       (__mingw_wcsrtombs_fallback): ...this, but rename it as...
+       (__mingw_wcsrtombs_internal): ...this; inline it.
+       (__msvcrt_wcsrtombs): Delete implementation.
+       (__mingw_wcsrtombs, __msvcrt_wcsrtombs): Reinstate as weak aliases.
+
+       * mingwex/wctob.c (__msvcrt_wctob): Delete implementation.
+       (__mingw_wctob_fallback, __mingw_wctob): Fold together, into...
+       (wctob): ...this publicly accessible function; add weak aliases...
+       (__mingw_wctob, __msvcrt_wctob): ...named thus.
+
 2020-06-03  Keith Marshall  <keith@users.osdn.me>
 
        Prepare and publish MinGW.org WSL-5.3.3 release.
index bb8b0b7..56660a5 100644 (file)
@@ -534,7 +534,7 @@ typedef int mbstate_t;
  * 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.
+ * we always use MinGW replacements, provided in libmingwex.a
  */
 __cdecl __MINGW_NOTHROW  wint_t btowc (int);
 __cdecl __MINGW_NOTHROW  int wctob (wint_t);
@@ -554,109 +554,6 @@ __cdecl __MINGW_NOTHROW  size_t wcrtomb
 __cdecl __MINGW_NOTHROW  size_t wcsrtombs
 (char *__restrict__, const wchar_t **__restrict__, size_t, mbstate_t *__restrict__);
 
-/* 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
-/* 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,
- * but substitute the MinGW replacements as required).
- */
-#undef __mingw_redirect
-#if _ISOC99_SOURCE & 0x08
-/* The user has explicitly requested ISO-C99 compatibility; ensure
- * that calls to the following functions are serviced by the MinGW
- * implementations, regardless of availability of any alternative
- * MSVCRT.DLL implementation.
- */
-# define __mingw_redirect(NAME)  __mingw_##NAME
-#else
-/* No explicit ISO-C99 compatibility has been requested; map calls
- * to these functions to delegate to any MSVCRT.DLL implementations
- * which may be available, or to fall back to the MinGW replacement
- * implementations, when necessary.
- */
-# define __mingw_redirect(NAME)  __msvcrt_##NAME
-#endif
-/* FIXME: Maybe consider these mappings, even for linking with the
- * non-free MSVCR80.DLL, and its descendants.
- */
-__CRT_ALIAS __cdecl __MINGW_NOTHROW  wint_t btowc (int __c)
-{ return __mingw_redirect(btowc( __c )); }
-
-__CRT_ALIAS __cdecl __MINGW_NOTHROW  size_t mbrlen
-(const char *__mbc, size_t __n, mbstate_t *__ps)
-{ return __mingw_redirect(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 __mingw_redirect(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 __mingw_redirect(mbsrtowcs( __wcs, __mbs, __n, __ps )); }
-
-__CRT_ALIAS __cdecl __MINGW_NOTHROW  int wctob (wint_t __wc)
-{ return __mingw_redirect(wctob( __wc )); }
-
-__CRT_ALIAS __cdecl __MINGW_NOTHROW  size_t wcrtomb
-(char * __mbc, wchar_t __wc, mbstate_t *__ps)
-{ return __mingw_redirect(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 __mingw_redirect(wcsrtombs(__mbs, __wcs, __len, __ps)); }
-
-#undef __mingw_redirect
-#endif /* ! MSVCR80.DLL or later */
-
 #if defined _ISOC99_SOURCE || defined __cplusplus
 /* These ISO-C99 functions are implemented in libmingwex.a,
  * or, in some cases, as inline stubs; while provided as MinGW
index af75b07..c1d58f7 100644 (file)
@@ -7,6 +7,7 @@
  * potential wchar_t overflow error, which may occur with functions such
  * as mbrtowc(), which may need to return surrogate pairs.
  *
+ *
  * $Id$
  *
  * Written by Keith Marshall <keith@users.osdn.me>
  */
 #include "wcharmap.h"
 
-/* For runtime delegation, we need a mechanism for detection of an
- * implementation, within the default C runtime DLL; we may use the
- * MinGW dlfcn emulation, to facilitate this.
- */
-#include <dlfcn.h>
-
 /* We also need <stdio.h>, for EOF.
  */
 #include <stdio.h>
 
-static wint_t __mingw_btowc_fallback( int c )
-{ /* Fallback function, providing an implementation of the btowc()
-   * function, when none is available within the Microsoft runtime.
-   * This performs an MBCS to wchar_t conversion on the given single
+wint_t btowc( int c )
+{ /* Implementation of ISO-C99 btowc() function, in libmingwex.a;
+   * this performs an MBCS to wchar_t conversion on the given single
    * character argument, (expressed as an int), returning WEOF in
    * the event that conversion fails.
    */
   if( c != EOF )
   { wint_t wc_result;
+    (void)(__mingw_mbrtowc_codeset_init());
     if( __mingw_mbtowc_convert( (char *)(&c), 1, &wc_result, 1) == 1 )
       return wc_result;
   }
   return WEOF;
 }
 
-wint_t __mingw_btowc( int c )
-{ /* Wrapper for the btowc() function; this will unconditionally
-   * delegate the call to the MinGW fallback implementation, (as
-   * implemented above), after initialization of the effective
-   * codeset file-global variable.
-   */
-  (void)(__mingw_mbrtowc_codeset_init());
-  return __mingw_btowc_fallback( c );
-}
-
-wint_t __msvcrt_btowc( int c )
-{ /* Wrapper for the btowc() function; it will initially attempt
-   * to delegate the call to a Microsoft-provided implementation,
-   * but if no such implementation can be found, fall back to the
-   * MinGW substitute (defined above).
-   */
-  static wint_t (*redirector_hook)( int ) = NULL;
-
-  /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with
-   * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus,
-   * Microsoft's btowc() is likely to be similarly unreliable, so we
-   * always use the MinGW fallback with such code pages.
-   */
-  if( __mb_cur_max_for_codeset(__mingw_mbrtowc_codeset_init()) > 2 )
-    return __mingw_btowc_fallback( c );
-
-  /* On first time call, we don't know which implementation is to be
-   * selected; look for a Microsoft implementation, which, if available,
-   * may be registered for immediate use on this, and any subsequent,
-   * calls to this function wrapper...
-   */
-  if(  (redirector_hook == NULL)
-  &&  ((redirector_hook = dlsym( RTLD_DEFAULT, "btowc" )) == NULL)  )
-
-    /* ...but when no Microsoft implementation can be found, register
-     * the MinGW fall back in its stead.
-     */
-    redirector_hook = __mingw_btowc_fallback;
-
-  /* Finally, delegate the call to whichever implementation has been
-   * registered on first-time call.
-   */
-  return redirector_hook( c );
-}
+/* FIXME: these aliases are provided for link-compatibitity with
+ * libraries compiled against mingwrt-5.3.x; they may be removed
+ * from future versions of mingwrt.
+ */
+wint_t __msvcrt_btowc( int c )__attribute__((__weak__,__alias__("btowc")));
+wint_t __mingw_btowc( int c )__attribute__((__weak__,__alias__("btowc")));
 
 /* $RCSfile$: end of file */
index 45e3cf4..8fa6901 100644 (file)
@@ -2,8 +2,8 @@
  * mbrconv.c
  *
  * Implementation of back-end MBCS to wchar_t conversion infrastructure
- * routines to support the mbrlen(), and mbrtowc() functions, for use in
- * those applications where Microsoft does not provide adequate support.
+ * routines to support the MinGW mbrlen(), and mbrtowc() functions.
+ *
  *
  * $Id$
  *
@@ -60,127 +60,129 @@ size_t __mingw_mbrtowc_handler
 ( wchar_t *restrict pwc, const char *restrict s, size_t n,
   mbstate_t *restrict ps
 )
-{ /* Common fallback handler for mbrtowc() and mbrlen() functions.
+{ /* Common handler for MinGW mbrtowc() and mbrlen() functions.
    */
-  union { mbstate_t st; wchar_t wc[2]; } retval;
-  union { mbstate_t st; char mb[MB_LEN_MAX]; wchar_t wc[2]; } state = { *ps };
-  unsigned int mbrlen_cur_max = __mingw_mbrlen_cur_max();
-  size_t pending, len = 0, count = 0;
+  (void)(__mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ));
+  { union { mbstate_t st; wchar_t wc[2]; } retval;
+    union { mbstate_t st; char mb[MB_LEN_MAX]; wchar_t wc[2]; } state = { *ps };
+    unsigned int mbrlen_cur_max = __mingw_mbrlen_cur_max();
+    size_t pending, len = 0, count = 0;
 
-  /* Any residual state, from a preceding call, has been captured
-   * in the local "state" union; assume that this call will clear
-   * any such state, leaving no further residual.
-   */
-  *ps = (mbstate_t)(0);
+    /* Any residual state, from a preceding call, has been captured
+     * in the local "state" union; assume that this call will clear
+     * any such state, leaving no further residual.
+     */
+    *ps = (mbstate_t)(0);
 
-  /* Normally, it makes no sense to call mbrlen(), or mbrtowc(),
-   * with a look-ahead byte count limit of zero; however, due to
-   * the constraints imposed by MS-Windows using UTF-16LE as the
-   * underlying encoding for wchar_t...
-   */
-  if( n == 0 )
-  { /* ...we allow this, as a special case, so that, when any
-     * immediately preceding call to mbrtowc() has returned a
-     * high surrogate, the accompanying low surrogate...
+    /* Normally, it makes no sense to call mbrlen(), or mbrtowc(),
+     * with a look-ahead byte count limit of zero; however, due to
+     * the constraints imposed by MS-Windows using UTF-16LE as the
+     * underlying encoding for wchar_t...
      */
-    if( IS_SURROGATE_PAIR( state.wc[0], state.wc[1] ) )
-    {
-      /* ...may be returned to the caller, without consuming
-       * any further bytes from the original MBCS sequence.
+    if( n == 0 )
+    { /* ...we allow this, as a special case, so that, when any
+       * immediately preceding call to mbrtowc() has returned a
+       * high surrogate, the accompanying low surrogate...
+       */
+      if( IS_SURROGATE_PAIR( state.wc[0], state.wc[1] ) )
+      {
+       /* ...may be returned to the caller, without consuming
+        * any further bytes from the original MBCS sequence.
+        */
+       if( pwc != NULL ) *pwc = state.wc[1];
+       return (size_t)(0);
+      }
+      /* When the conversion state does not represent a deferred
+       * low surrogate, then restore it, and pass this through as
+       * an effective no-op.
        */
-      if( pwc != NULL ) *pwc = state.wc[1];
-      return (size_t)(0);
+      *ps = state.st;
+      return (size_t)(-2);
     }
-    /* When the conversion state does not represent a deferred
-     * low surrogate, then restore it, and pass this through as
-     * an effective no-op.
+    /* In any context, other than the preceding (special) n == 0
+     * case, for retrieval of a deferred low surrogate, a pending
+     * conversion state which represents a surrogate pair is not
+     * a valid state; reject it.
      */
-    *ps = state.st;
-    return (size_t)(-2);
-  }
-  /* In any context, other than the preceding (special) n == 0
-   * case, for retrieval of a deferred low surrogate, a pending
-   * conversion state which represents a surrogate pair is not
-   * a valid state; reject it.
-   */
-  if( IS_SURROGATE_PAIR( state.wc[0], state.wc[1] ) )
-    return errout( EINVAL, (size_t)(-1) );
-
-  /* Step over any pending MBCS bytes, which may already be
-   * present within the conversion state buffer, accumulating
-   * both the count of such pending bytes, together with a
-   * partial count of total bytes for conversion.
-   */
-  while( (len < sizeof( mbstate_t )) && (state.mb[len] != '\0') )
-    ++len;
-  pending = len;
+    if( IS_SURROGATE_PAIR( state.wc[0], state.wc[1] ) )
+      return errout( EINVAL, (size_t)(-1) );
 
-  /* Append MBCS bytes from the input sequence, to the pending
-   * state buffer, up to the specified look-ahead count limit, or
-   * until the filled length of the buffer becomes equivalent to
-   * the effective value of MB_CUR_MAX.
-   */
-  while( (len < mbrlen_cur_max) && (count < n) && (s[count] != '\0') )
-    state.mb[len++] = s[count++];
+    /* Step over any pending MBCS bytes, which may already be
+     * present within the conversion state buffer, accumulating
+     * both the count of such pending bytes, together with a
+     * partial count of total bytes for conversion.
+     */
+    while( (len < sizeof( mbstate_t )) && (state.mb[len] != '\0') )
+      ++len;
+    pending = len;
 
-  /* If the pending look-ahead state has not yet been padded
-   * to the full MB_CUR_MAX length, ensure that it is encoded
-   * as a NUL terminated MBCS sequence, before attempting to
-   * interpret it as a complete MBCS sequence.
-   */
-  if( len < mbrlen_cur_max ) state.mb[len] = '\0';
-  if( (int)(count = mbrlen_min( state.mb, len, retval.wc )) > 0 )
-  {
-    /* No valid conversion state should ever exist, where no
-     * additional bytes are required to complete a previously
-     * deferred multibyte character.
+    /* Append MBCS bytes from the input sequence, to the pending
+     * state buffer, up to the specified look-ahead count limit, or
+     * until the filled length of the buffer becomes equivalent to
+     * the effective value of MB_CUR_MAX.
      */
-    if( pending >= count ) return errout( EILSEQ, (size_t)(-1) );
+    while( (len < mbrlen_cur_max) && (count < n) && (s[count] != '\0') )
+      state.mb[len++] = s[count++];
 
-    /* The accumulated encoding state does now represent a
-     * complete MBCS sequence; when servicing an mbrtowc() call,
-     * with non-NULL return value pointer, we must store that
-     * return value...
+    /* If the pending look-ahead state has not yet been padded
+     * to the full MB_CUR_MAX length, ensure that it is encoded
+     * as a NUL terminated MBCS sequence, before attempting to
+     * interpret it as a complete MBCS sequence.
      */
-    if( pwc != NULL )
-    { /* ...noting that, under MS-Windows, we may not be able
-       * to accommodate the entire converted value in a single
-       * UTF-16 wchar_t, in which case we must return it as a
-       * surrogate pair, of which only the high surrogate can
-       * be returned now...
+    if( len < mbrlen_cur_max ) state.mb[len] = '\0';
+    if( (int)(count = mbrlen_min( state.mb, len, retval.wc )) > 0 )
+    {
+      /* No valid conversion state should ever exist, where no
+       * additional bytes are required to complete a previously
+       * deferred multibyte character.
+       */
+      if( pending >= count ) return errout( EILSEQ, (size_t)(-1) );
+
+      /* The accumulated encoding state does now represent a
+       * complete MBCS sequence; when servicing an mbrtowc() call,
+       * with non-NULL return value pointer, we must store that
+       * return value...
        */
-      if( IS_HIGH_SURROGATE( *pwc = retval.wc[0] ) )
-       /* ...with the entire pair being stored at the passed
-        * mbstate_t reference buffer, allowing for subsequent
-        * retrieval of the low surrogate.
+      if( pwc != NULL )
+      { /* ...noting that, under MS-Windows, we may not be able
+        * to accommodate the entire converted value in a single
+        * UTF-16 wchar_t, in which case we must return it as a
+        * surrogate pair, of which only the high surrogate can
+        * be returned now...
         */
-       *ps = retval.st;
-    }
-    /* In the case that the wchar_t return value represents a
-     * NUL character, ISO-C99 prescribes that, whichever of the
-     * supported functions is being serviced, the returned byte
-     * count, of converted MBCS bytes, must be zero.
-     */
-    if( retval.wc[0] == L'\0' ) return (size_t)(0);
+       if( IS_HIGH_SURROGATE( *pwc = retval.wc[0] ) )
+         /* ...with the entire pair being stored at the passed
+          * mbstate_t reference buffer, allowing for subsequent
+          * retrieval of the low surrogate.
+          */
+         *ps = retval.st;
+      }
+      /* In the case that the wchar_t return value represents a
+       * NUL character, ISO-C99 prescribes that, whichever of the
+       * supported functions is being serviced, the returned byte
+       * count, of converted MBCS bytes, must be zero.
+       */
+      if( retval.wc[0] == L'\0' ) return (size_t)(0);
 
-    /* The effective function return value, for this case, is
-     * the count of bytes accumulated into the completed MBCS
-     * byte sequence, discounting those which were deferred
-     * from any preceding call.
-     */
-    return (count - pending);
-  }
-  else if( count < mbrlen_cur_max )
-  { /* The accumulated encoding state does not represent a
-     * complete, and valid MBCS sequence, but we have not yet
-     * accumulated as many bytes as the effective MB_CUR_MAX
-     * length can accommodate; save the encoding state for
-     * deferred reprocessing, and return the appropriate
-     * pseudo-count to inform the caller that this encoding
-     * state may yet develop into a valid MBCS sequence.
-     */
-    *ps = retval.st;
-    return (size_t)(-2);
+      /* The effective function return value, for this case, is
+       * the count of bytes accumulated into the completed MBCS
+       * byte sequence, discounting those which were deferred
+       * from any preceding call.
+       */
+      return (count - pending);
+    }
+    else if( count < mbrlen_cur_max )
+    { /* The accumulated encoding state does not represent a
+       * complete, and valid MBCS sequence, but we have not yet
+       * accumulated as many bytes as the effective MB_CUR_MAX
+       * length can accommodate; save the encoding state for
+       * deferred reprocessing, and return the appropriate
+       * pseudo-count to inform the caller that this encoding
+       * state may yet develop into a valid MBCS sequence.
+       */
+      *ps = retval.st;
+      return (size_t)(-2);
+    }
   }
   /* If neither of the preceding encoding states prevails, then
    * the current state must represent an invalid MBCS sequence;
index fddd46a..42c8f76 100644 (file)
@@ -1,9 +1,11 @@
 /*
  * mbrlen.c
  *
- * MinGW.org replacement for the ISO-C99 mbrlen() function; delegates to a
- * Microsoft implementation, if available in the C runtime DLL, (unless this
- * is overridden by user choice); otherwise handles the call locally.
+ * MinGW.org replacement for the ISO-C99 mbrlen() function, supporting its
+ * use on any legacy Windows version for which Microsoft does not provide it,
+ * while replacing the Microsoft implementation on those Windows versions
+ * for which it is provided.
+ *
  *
  * $Id$
  *
  */
 #include "wcharmap.h"
 
-/* For runtime delegation, we need a mechanism for detection of an
- * implementation, within the default C runtime DLL; we may use the
- * MinGW dlfcn emulation, to facilitate this.
- */
-#include <dlfcn.h>
-
-static size_t __mingw_mbrlen_fallback
-( const char *restrict s, size_t n, mbstate_t *restrict ps )
+size_t mbrlen( const char *restrict s, size_t n, mbstate_t *restrict ps )
 {
-  /* Fallback function, providing an implementation of the mbrlen()
-   * function, when none is available within the Microsoft C runtime,
-   * or the user has explicitly overridden accessibility of any such
-   * Microsoft implementation.
-   *
-   * This is simply delegated to common handler, for both mbrlen(),
-   * and mbrtowc() fallback functions.
+  /* Implementation of ISO-C99 mbrlen() function, in libmingwex.a;
+   * this is simply delegated to the common handler, which services
+   * both the mbrlen(), and mbrtowc() functions.
    */
   return __mingw_mbrtowc_handler( NULL, s, n, __mbrtowc_state( ps ) );
 }
 
-size_t __mingw_mbrlen
-( const char *restrict s, size_t n, mbstate_t *restrict ps )
-{
-  /* Wrapper for the mbrlen() function; this will unconditionally
-   * delegate the call to the MinGW fallback implementation, (defined
-   * above), irrespective of availability of any Microsoft-provided
-   * implementation.
-   */
-  __mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() );
-  return __mingw_mbrlen_fallback( s, n, ps );
-}
-
-size_t __msvcrt_mbrlen
-( const char *restrict s, size_t n, mbstate_t *restrict ps )
-{
-  /* Wrapper for the mbrlen() function; this will initially attempt
-   * to delegate the call to a Microsoft-provided implementation, but
-   * if no such implementation can be found, fall back to the MinGW
-   * substitute (defined above).
-   */
-  typedef size_t (*redirector_t)
-  ( const char *restrict, size_t, mbstate_t *restrict );
-  static redirector_t redirector_hook = NULL;
-
-  /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with
-   * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus,
-   * Microsoft's mbrlen() is likely to be similarly unreliable, so
-   * always use the MinGW fallback with such code pages.
-   */
-  if( __mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ) > 2 )
-    return __mingw_mbrlen_fallback( s, n, ps );
-
-  /* On first time call, we don't know which implementation is to be
-   * selected; look for a Microsoft implementation, which, if available,
-   * may be registered for immediate use on this, and any subsequent,
-   * calls to this function wrapper...
-   */
-  if(  (redirector_hook == NULL)
-  &&  ((redirector_hook = dlsym( RTLD_DEFAULT, "mbrlen" )) == NULL)  )
-
-    /* ...but when no Microsoft implementation can be found, register
-     * the MinGW fall back in its stead.
-     */
-    redirector_hook = __mingw_mbrlen_fallback;
+/* FIXME: these aliases are provided for link-compatibitity with
+ * libraries compiled against mingwrt-5.3.x; they may be removed
+ * from future versions of mingwrt.
+ */
+size_t __mingw_mbrlen( const char *restrict, size_t, mbstate_t *restrict )
+__attribute__((__weak__,__alias__("mbrlen")));
 
-  /* Finally, delegate the call to whichever implementation has been
-   * registered on first-time call.
-   */
-  return redirector_hook( s, n, ps );
-}
+size_t __msvcrt_mbrlen( const char *restrict, size_t, mbstate_t *restrict )
+__attribute__((__weak__,__alias__("mbrlen")));
 
 /* $RCSfile$: end of file */
index e425b77..d284013 100644 (file)
@@ -1,9 +1,11 @@
 /*
  * mbrtowc.c
  *
- * MinGW.org replacement for the ISO-C99 mbrtowc() function; delegates to a
- * Microsoft implementation, if available in the C runtime DLL, (unless this
- * is overridden by user choice); otherwise handles the call locally.
+ * MinGW.org replacement for the ISO-C99 mbrtowc() function, supporting
+ * use of this function on legacy Windows versions, for which Microsoft
+ * does not provide it, while replacing the Microsoft implementation on
+ * those Windows versions for which it is provided.
+ *
  *
  * $Id$
  *
  */
 #include "wcharmap.h"
 
-/* For runtime delegation, we need a mechanism for detection of an
- * implementation, within the default C runtime DLL; we may use the
- * MinGW dlfcn emulation, to facilitate this.
- */
-#include <dlfcn.h>
-
-static size_t __mingw_mbrtowc_fallback
+size_t mbrtowc
 ( wchar_t *restrict pwc, const char *restrict s, size_t n,
   mbstate_t *restrict ps
 )
-{ /* Fallback function, providing an implementation of the mbrtowc()
-   * function, when none is available within the Microsoft C runtime,
-   * or the user has explicitly overridden accessibility of any such
-   * Microsoft implementation.
+{ /* Implementation of ISO-C99 mbrtowc() function, in libmingwex.a
    *
    * When s is a NULL pointer, ISO-C99 decrees that the call shall
    * be interpreted as the equivalent of:
@@ -55,69 +48,25 @@ static size_t __mingw_mbrtowc_fallback
    *
    * with any other supplied values for pwc and n being ignored.
    */
-  if( s == NULL ) return __mingw_mbrtowc_fallback( NULL, "", 1, ps );
+  if( s == NULL ) return mbrtowc( NULL, "", 1, ps );
 
   /* Otherwise, we simply delegate the the call to the common
-   * handler, which implements the fallback action for both the
-   * mbrlen() function, and the mbrtowc() function.
+   * handler, which implements the action for both the mbrlen()
+   * function, and the mbrtowc() function.
    */
   return __mingw_mbrtowc_handler( pwc, s, n, __mbrtowc_state( ps ) );
 }
 
+/* FIXME: these aliases are provided for link-compatibitity with
+ * libraries compiled against mingwrt-5.3.x; they may be removed
+ * from future versions of mingwrt.
+ */
 size_t __mingw_mbrtowc
-( wchar_t *restrict pwc, const char *restrict s, size_t n,
-  mbstate_t *restrict ps
-)
-{ /* Wrapper for the mbrtowc() function; this will unconditionally
-   * delegate the call to the MinGW fallback implementation, (defined
-   * above), irrespective of availability of any Microsoft-provided
-   * implementation.
-   *
-   * Note that, before handing off the call, we must unconditionally
-   * initialize the working codeset, and its effective MB_CUR_MAX.
-   */
-  (void)(__mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ));
-  return __mingw_mbrtowc_fallback( pwc, s, n, ps );
-}
+( wchar_t *restrict, const char *restrict, size_t, mbstate_t *restrict )
+__attribute__((__weak__,__alias__("mbrtowc")));
 
 size_t __msvcrt_mbrtowc
-( wchar_t *restrict pwc, const char *restrict s, size_t n,
-  mbstate_t *restrict ps
-)
-{ /* Wrapper for the mbrtowc() function; this will initially attempt
-   * to delegate the call to a Microsoft-provided implementation, but
-   * if no such implementation can be found, fall back to the MinGW
-   * substitute (defined above).
-   */
-  typedef size_t (*redirector_t)
-  ( wchar_t *restrict, const char *restrict, size_t, mbstate_t *restrict );
-  static redirector_t redirector_hook = NULL;
-
-  /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with
-   * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus,
-   * Microsoft's mbrtowc() is likely to be similarly unreliable, so
-   * always use the MinGW fallback with such code pages.
-   */
-  if( __mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ) > 2 )
-    return __mingw_mbrtowc_fallback( pwc, s, n, ps );
-
-  /* On first time call, we don't know which implementation is to be
-   * selected; look for a Microsoft implementation, which, if available,
-   * may be registered for immediate use on this, and any subsequent,
-   * calls to this function wrapper...
-   */
-  if(  (redirector_hook == NULL)
-  &&  ((redirector_hook = dlsym( RTLD_DEFAULT, "mbrtowc" )) == NULL)  )
-
-    /* ...but when no Microsoft implementation can be found, register
-     * the MinGW fall back in its stead.
-     */
-    redirector_hook = __mingw_mbrtowc_fallback;
-
-  /* Finally, delegate the call to whichever implementation has been
-   * registered on first-time call.
-   */
-  return redirector_hook( pwc, s, n, ps );
-}
+( wchar_t *restrict, const char *restrict, size_t, mbstate_t *restrict )
+__attribute__((__weak__,__alias__("mbrtowc")));
 
 /* $RCSfile$: end of file */
index 9790dc1..7d8a150 100644 (file)
@@ -1,9 +1,11 @@
 /*
  * mbsrtowcs.c
  *
- * MinGW.org replacement for the ISO-C99 mbsrtowcs() function; may delegate
- * to a Microsoft implementation, if available in the C runtime DLL, (unless
- * this is overridden by user choice); otherwise handles the call locally.
+ * MinGW.org replacement for the ISO-C99 mbsrtowcs() function, supporting
+ * its use on legacy Windows versions, for which Microsoft does not provide
+ * it, while replacing the Microsoft implementation on any Windows version
+ * for which it is provided.
+ *
  *
  * $Id$
  *
@@ -33,7 +35,6 @@
  */
 #include "wcharmap.h"
 
-#include <dlfcn.h>
 #include <limits.h>
 
 static __mb_inline__
@@ -45,14 +46,12 @@ boolean __mingw_mbtowc_verify( const char *src, size_t len )
   return __mingw_mbtowc_copy( NULL, src, len ) != (size_t)(-1);
 }
 
-static __mb_inline__ size_t __mbsrtowcs_fallback
+static __mb_inline__ size_t __mbsrtowcs_internal
 ( wchar_t *restrict wcs, const char **restrict src, size_t len,
   mbstate_t *restrict ps
 )
-{ /* Internal fallback function, providing an implementation of the
-   * mbsrtowcs() function, when none is available in the Microsoft C
-   * runtime DLL, or the user has explicitly overridden selection of
-   * any such Microsoft implementation.
+{ /* Internal implementation of the mbsrtowcs() function; this is
+     expanded inline, within the public implementation.
    */
   size_t count = (size_t)(0);
   if( (src != NULL) && (*src != NULL) )
@@ -156,72 +155,28 @@ static __mb_inline__ size_t __mbsrtowcs_fallback
   return count;
 }
 
-static size_t __mingw_mbsrtowcs_fallback
-( wchar_t *restrict wcs, const char **restrict src, size_t len,
-  mbstate_t *restrict ps __attribute__((__unused__))
-)
-{ /* MinGW fallback implementation for the mbsrtowcs() function; this
-   * is a trivial wrapper around the preceding implementation, (which
-   * should be expanded in-line), ensuring that an internal buffer is
-   * assigned for the "ps" argument, if the caller doesn't pass one.
-   */
-  return __mbsrtowcs_fallback( wcs, src, len, __mbrtowc_state( ps ) );
-}
-
-size_t __mingw_mbsrtowcs
+size_t mbsrtowcs
 ( wchar_t *restrict wcs, const char **restrict src, size_t len,
   mbstate_t *restrict ps
 )
-{ /* Wrapper for the mbsrtowcs() function; this will unconditionally
-   * delegate the call to the MinGW fallback implementation, (defined
-   * above), irrespective of availability of any Microsoft-provided
-   * implementation.
-   *
-   * Note that, before handing off the call, we must unconditionally
-   * initialize the working codeset, and its effective MB_CUR_MAX.
+{ /* Implementation of ISO-C99 mbsrtowcs() function, in libmingwex.a;
+   * this stores the effective codeset properties, before returning the
+   * result from expansion of the preceding inline implementation.
    */
   (void)(__mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ));
-  return __mingw_mbsrtowcs_fallback( wcs, src, len, ps );
+  return __mbsrtowcs_internal( wcs, src, len, __mbrtowc_state( ps ) );
 }
 
-size_t __msvcrt_mbsrtowcs
-( wchar_t *restrict wcs, const char **restrict src, size_t len,
-  mbstate_t *restrict ps
-)
-{ /* Wrapper for the mbsrtowcs() function; this will initially attempt
-   * to delegate the call to a Microsoft-provided implementation, but if
-   * no such implementation can be found, it will fall back to the MinGW
-   * substitute (defined above).
-   */
-  typedef size_t (*redirector_t)
-  ( wchar_t *restrict, const char **restrict, size_t, mbstate_t *restrict );
-  static redirector_t redirector_hook = NULL;
-
-  /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with
-   * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus,
-   * Microsoft's mbsrtowcs() is likely to be similarly unreliable, so
-   * always use the MinGW fallback with such code pages.
-   */
-  if( __mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ) > 2 )
-    return __mingw_mbsrtowcs_fallback( wcs, src, len, ps );
-
-  /* On first time call, we don't know which implementation is to be
-   * selected; look for a Microsoft implementation, which, if available,
-   * may be registered for immediate use on this, and any subsequent,
-   * calls to this function wrapper...
-   */
-  if(  (redirector_hook == NULL)
-  &&  ((redirector_hook = dlsym( RTLD_DEFAULT, "mbsrtowcs" )) == NULL)  )
-
-    /* ...but when no Microsoft implementation can be found, register
-     * the MinGW fall back in its stead.
-     */
-    redirector_hook = __mingw_mbsrtowcs_fallback;
+/* FIXME: these aliases are provided for link-compatibitity with
+ * libraries compiled against mingwrt-5.3.x; they may be removed
+ * from future versions of mingwrt.
+ */
+size_t __mingw_mbsrtowcs
+( wchar_t *restrict, const char **restrict, size_t, mbstate_t *restrict )
+__attribute__((__weak__,__alias__("mbsrtowcs")));
 
-  /* Finally, delegate the call to whichever implementation has been
-   * registered on first-time call.
-   */
-  return redirector_hook( wcs, src, len, ps );
-}
+size_t __msvcrt_mbsrtowcs
+( wchar_t *restrict, const char **restrict, size_t, mbstate_t *restrict )
+__attribute__((__weak__,__alias__("mbsrtowcs")));
 
 /* $RCSfile$: end of file */
index aa6e7d4..96896e0 100644 (file)
@@ -1,9 +1,11 @@
 /*
  * wcrtomb.c
  *
- * MinGW.org replacement for the wcrtomb() function; delegates to the
- * Microsoft implementation, if available in the C runtime DLL, otherwise
- * handles the call locally.
+ * MinGW.org replacement for the wcrtomb() function; supports use of this
+ * function on legacy Windows versions, for which it is not available in the
+ * C runtime DLL, and replaces the Microsoft implementation, in those cases
+ * where one is available.
+ *
  *
  * $Id$
  *
  */
 #include "wcharmap.h"
 
-/* For runtime delegation, we need a mechanism for detection of an
- * implementation, within the default C runtime DLL; we may use the
- * MinGW dlfcn emulation, to facilitate this.
- */
-#include <dlfcn.h>
-
-static __mb_inline__ size_t __wcrtomb_fallback
+static __mb_inline__ size_t __wcrtomb_internal
 ( char *restrict mb, wchar_t wc, mbstate_t *ps )
 {
-  /* Fallback function, providing an implementation of the wcrtomb()
-   * function, when none is available within the Microsoft C runtime,
-   * or the user has explicitly overridden accessibility of any such
-   * Microsoft implementation.
+  /* Internal implementation of the wcrtomb() function; this is
+   * expanded inline, within the public implementation.
    */
   if( *ps != (mbstate_t)(0) )
   {
@@ -114,65 +108,24 @@ static __mb_inline__ size_t __wcrtomb_fallback
   return __mingw_wctomb_convert( mb, __mingw_wctomb_cur_max(), &wc, 1 );
 }
 
-static size_t __mingw_wcrtomb_fallback
-( char *restrict mb, wchar_t wc, mbstate_t *ps )
-{
-  /* A thin wrapper around the preceding fallback implementation,
-   * (which is expanded in-line); this serves as the sole interface
-   * between either of the two following public API entry points, and
-   * the fallback implementation, ensuring that a private mbstate_t
-   * reference is provided, if the caller doesn't supply its own.
-   */
-  return __wcrtomb_fallback( mb, wc, __mbrtowc_state( ps ) );
-}
-
-size_t __mingw_wcrtomb
-( char *restrict mb, wchar_t wc, mbstate_t *restrict ps )
+size_t wcrtomb( char *restrict mb, wchar_t wc, mbstate_t *restrict ps )
 {
-  /* Wrapper for the wcrtomb() function; this will unconditionally
-   * delegate the call to the MinGW fallback implementation, (defined
-   * above), irrespective of availability of any Microsoft-provided
-   * implementation.
+  /* Implementation of ISO-C99 wcrtomb() function, in libmingwex.a;
+   * after storing the effective codeset properties, this returns the
+   * result from expansion of the preceding inline implementation.
    */
   (void)(__mingw_wctomb_cur_max_init( __mingw_wctomb_codeset_init() ));
-  return __mingw_wcrtomb_fallback( mb, wc, ps );
+  return __wcrtomb_internal( mb, wc, __mbrtowc_state( ps ) );
 }
 
-size_t __msvcrt_wcrtomb( char *restrict mb, wchar_t wc, mbstate_t *restrict ps )
-{
-  /* Wrapper for the wcrtomb() function; this will initially attempt
-   * to delegate the call to a Microsoft-provided implementation, but
-   * if no such implementation can be found, fall back to the MinGW
-   * substitute (defined above).
-   */
-  typedef size_t (*redirect_t)( char *restrict, wchar_t, mbstate_t *restrict );
-  static redirect_t redirector_hook = NULL;
-
-  /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with
-   * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus,
-   * Microsoft's wcrtomb() is likely to be similarly unreliable, so
-   * always use the MinGW fallback with such code pages.
-   */
-  if( (__mingw_wctomb_cur_max_init( __mingw_wctomb_codeset_init() )) > 2 )
-    return __mingw_wcrtomb_fallback( mb, wc, ps );
-
-  /* On first time call, we don't know which implementation is to be
-   * selected; look for a Microsoft implementation, which, if available,
-   * may be registered for immediate use on this, and any subsequent,
-   * calls to this function wrapper...
-   */
-  if(  (redirector_hook == NULL)
-  &&  ((redirector_hook = dlsym( RTLD_DEFAULT, "wcrtomb" )) == NULL)  )
-
-    /* ...but when no Microsoft implementation can be found, register
-     * the MinGW fall back in its stead.
-     */
-    redirector_hook = __mingw_wcrtomb_fallback;
+/* FIXME: these aliases are provided for link-compatibitity with
+ * libraries compiled against mingwrt-5.3.x; they may be removed
+ * from future versions of mingwrt.
+ */
+size_t __msvcrt_wcrtomb( char *restrict, wchar_t, mbstate_t *restrict )
+__attribute__((__weak__,__alias__("wcrtomb")));
 
-  /* Finally, delegate the call to whichever implementation has been
-   * registered on first-time call.
-   */
-  return redirector_hook( mb, wc, ps );
-}
+size_t __mingw_wcrtomb( char *restrict, wchar_t, mbstate_t *restrict )
+__attribute__((__weak__,__alias__("wcrtomb")));
 
 /* $RCSfile$: end of file */
index b18298b..e6a7f69 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * wcsrtombs.c
  *
- * MinGW.org replacement for the wcsrtombs() function; delegates to the
- * Microsoft implementation, if available in the C runtime DLL, otherwise
- * handles the call locally.
+ * MinGW.org implementation of the wcsrtombs() function; supports use of
+ * this function on any legacy Windows version, for which Microsoft do not
+ * provide it, and replaces the Microsoft implementation, when they do.
+ *
  *
  * $Id$
  *
  */
 #include "wcharmap.h"
 
-/* For runtime delegation, we need a mechanism for detection of an
- * implementation, within the default C runtime DLL; we may use the
- * MinGW dlfcn emulation, to facilitate this.
- */
-#include <dlfcn.h>
-
-static size_t __mingw_wcsrtombs_fallback
+static __mb_inline__ size_t __mingw_wcsrtombs_internal
 ( char *restrict mbs, const wchar_t **restrict wcs, size_t len,
   mbstate_t *restrict ps
 )
-{ /* Fallback function, providing an implementation of the wcsrtombs()
-   * function, when none is available within the Microsoft C runtime, or
-   * the user has elected to override any such Microsoft implementation.
+{ /* Internal implementation of the wcsrtombs() function; this will be
+   * expanded inline, within the body of the public implementation.
    *
    * Initially, save the current errno state, so that we may restore
    * it on return, clear it to zero for internal checking, and compute
@@ -144,63 +138,30 @@ static size_t __mingw_wcsrtombs_fallback
   return errout( errno_reset, count );
 }
 
-size_t __mingw_wcsrtombs
-( char *mbs, const wchar_t **wcs, size_t len, mbstate_t *ps )
+size_t wcsrtombs( char *mbs, const wchar_t **wcs, size_t len, mbstate_t *ps )
 {
-  /* Wrapper for the wcsrtombs() function; this will unconditionally
-   * delegate the call to the MinGW fallback implementation, (defined
-   * above), after first ensuring that the specified wcs reference is
-   * valid, and that the effective codeset has been initialized.
+  /* Implementation of ISO-C99 wcsrtombs() function, in libmingwex.a;
+   * before proceeding, we must ensure that the wcs argument specifies
+   * an indirect reference to a non-NULL wchar_t array.
    */
   if( (wcs == NULL) || (*wcs == NULL) ) return errout( EINVAL, (size_t)(-1) );
 
+  /* With a valid wcs reference, store the effective codeset, and
+   * hand the conversion off to the inline expansion of the preceding
+   * implementation.
+   */
   (void)(__mingw_wctomb_codeset_init() );
-  return __mingw_wcsrtombs_fallback( mbs, wcs, len, ps );
+  return __mingw_wcsrtombs_internal( mbs, wcs, len, ps );
 }
 
-size_t __msvcrt_wcsrtombs
-( char *mbs, const wchar_t **wcs, size_t len, mbstate_t *ps )
-{
-  /* Wrapper for the wcsrtombs() function; it will initially attempt
-   * to delegate the call to a Microsoft-provided implementation, but
-   * if no such implementation can be found, fall back to the MinGW
-   * substitute (defined above).
-   */
-  typedef size_t (*redirect_t)(char *, const wchar_t **, size_t, mbstate_t *);
-  static redirect_t redirector_hook = NULL;
-
-  /* Neither wcs, not the pointer to which it refers, may be NULL.
-   * ISO C doesn't specify any particular outcome for this condition,
-   * (so a segmentation fault would conform); it makes more sense to
-   * catch the abnormality, and bail out.
-   */
-  if( (wcs == NULL) || (*wcs == NULL) ) return errout( EINVAL, (size_t)(-1) );
-
-  /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with
-   * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus,
-   * Microsoft's wcsrtombs() is likely to be similarly unreliable, so
-   * always use the MinGW fallback with such code pages.
-   */
-  if( __mb_cur_max_for_codeset( __mingw_wctomb_codeset_init() ) > 2 )
-    return __mingw_wcsrtombs_fallback( mbs, wcs, len, ps );
+/* FIXME: these aliases are provided for link-compatibitity with
+ * libraries compiled against mingwrt-5.3.x; they may be removed
+ * from future versions of mingwrt.
+ */
+size_t __msvcrt_wcsrtombs( char *, const wchar_t **, size_t, mbstate_t * )
+__attribute__((__weak__,__alias__("wcsrtombs")));
 
-  /* On first time call, we don't know which implementation is to be
-   * selected; look for a Microsoft implementation, which, if available,
-   * may be registered for immediate use on this, and any subsequent,
-   * calls to this function wrapper...
-   */
-  if(  (redirector_hook == NULL)
-  &&  ((redirector_hook = dlsym( RTLD_DEFAULT, "wcsrtombs" )) == NULL)  )
-  {
-    /* ...but when no Microsoft implementation can be found, register
-     * the MinGW fallback in its stead.
-     */
-    redirector_hook = __mingw_wcsrtombs_fallback;
-  }
-  /* Finally, delegate the call to whichever implementation has been
-   * registered on first-time call.
-   */
-  return redirector_hook( mbs, wcs, len, ps );
-}
+size_t __mingw_wcsrtombs( char *, const wchar_t **, size_t, mbstate_t * )
+__attribute__((__weak__,__alias__("wcsrtombs")));
 
 /* $RCSfile$: end of file */
index e52e201..ca94eb3 100644 (file)
@@ -2,9 +2,9 @@
  * wctob.c
  *
  * Implementation of ISO-C99 wctob() function, supporting it on legacy
- * Windows versions, for which MSVCRT.DLL doesn't provide it, otherwise
- * delegating to the Microsoft implementation, except in specific cases
- * when that implementation may not support the active MBCS codeset.
+ * Windows versions, for which MSVCRT.DLL doesn't provide it, and also
+ * replacing the Microsoft implementation, on Windows versions with an
+ * MSVCRT.DLL, or MSVCRn.DLL which does.
  *
  *
  * $Id$
  */
 #include "wcharmap.h"
 
-/* For runtime delegation, we need a mechanism for detection of an
- * implementation, within the default C runtime DLL; we may use the
- * MinGW dlfcn emulation, to facilitate this.
- */
-#include <dlfcn.h>
 #include <stdio.h>
 
-static int __mingw_wctob_fallback( wint_t wc )
-{ /* Fallback function, providing an implementation of the wctob()
-   * function, when none is available within the Microsoft runtime.
-   * This performs a wchar_t to MBCS conversion on the given single
-   * wide character argument, capturing the conversion into a local
-   * buffer, checks that the result occupies exactly one byte, for
-   * which the coercion of that byte value to int is returned, or
-   * otherwise returns EOF.
+int wctob( wint_t wc )
+{ /* Implementation of ISO-C99 wctob() function, in libmingwex.a;
+   * after first storing the effective codeset index, this performs
+   * a wchar_t to MBCS conversion on the given single wide character
+   * argument, capturing the conversion into a local buffer, checks
+   * that the result occupies exactly one byte, for which the byte
+   * value is coerced to int and returned; otherwise returns EOF.
    */
+  (void)(__mingw_wctomb_codeset_init());
   union { unsigned char u; char c; } retval;
   return (__mingw_wctomb_convert( &retval.c, 1, &wc, 1 ) == 1)
     ? (int)(retval.u) : EOF;
 }
 
-int __mingw_wctob( wint_t wc )
-{ /* Wrapper for the wctob() function; this variant will unconditionally
-   * delegate the call to the MinGW fallback implementation, after first
-   * storing the effective codeset index.
-   */
-  (void)(__mingw_wctomb_codeset_init());
-  return __mingw_wctob_fallback( wc );
-}
-
-int __msvcrt_wctob( wint_t wc )
-{ /* Wrapper for the wctob() function; it will initially attempt
-   * to delegate the call to a Microsoft-provided implementation,
-   * but if no such implementation can be found, fall back to the
-   * MinGW substitute (defined above).
-   */
-  static int (*redirector_hook)( wchar_t ) = NULL;
-
-  /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with
-   * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus,
-   * Microsoft's wctob() is likely to be similarly unreliable, so we
-   * always use the MinGW fallback with such code pages.
-   */
-  if( __mingw_wctomb_cur_max_init(__mingw_wctomb_codeset_init()) > 2 )
-    return __mingw_wctob_fallback( wc );
-
-  /* On first time call, we don't know which implementation is to be
-   * selected; look for a Microsoft implementation, which, if available,
-   * may be registered for immediate use on this, and any subsequent,
-   * calls to this function wrapper...
-   */
-  if(  (redirector_hook == NULL)
-  &&  ((redirector_hook = dlsym( RTLD_DEFAULT, "wctob" )) == NULL)  )
-
-    /* ...but when no Microsoft implementation can be found, register
-     * the MinGW fall back in its stead.
-     */
-    redirector_hook = __mingw_wctob_fallback;
-
-  /* Finally, delegate the call to whichever implementation has been
-   * registered on first-time call.
-   */
-  return redirector_hook( wc );
-}
+/* FIXME: these aliases are provided for link-compatibitity with
+ * libraries compiled against mingwrt-5.3.x; they may be removed
+ * from future versions of mingwrt.
+ */
+int __msvcrt_wctob( wint_t )__attribute__((__weak__,__alias__("wctob")));
+int __mingw_wctob( wint_t )__attribute__((__weak__,__alias__("wctob")));
 
 /* $RCSfile$: end of file */