The MinGW.OSDN Windows System Libraries. Formerly designated as "MinGW.org Windows System Libraries", this encapsulates the "mingwrt" C runtime library extensions, and the "w32api" 32-bit MS-Windows API libraries.
Please note that this project no longer owns the "MinGW.org" domain name; any software which may be distributed from that domain is NOT supported by this project.
修订版 | 37af5680dbbdee37de0e9b7d3863951f9fc85cde (tree) |
---|---|
时间 | 2020-07-05 06:06:58 |
作者 | Keith Marshall <keith@user...> |
Commiter | Keith Marshall |
Discontinue use of Microsoft's MBCS/wide character converters.
@@ -1,3 +1,60 @@ | ||
1 | +2020-07-04 Keith Marshall <keith@users.osdn.me> | |
2 | + | |
3 | + Discontinue use of Microsoft's MBCS/wide character converters. | |
4 | + | |
5 | + * include/wchar.h (__mingw_redirect): Delete macro definition. | |
6 | + (__mingw_mbrlen, __msvcrt_mbrlen, __mingw_mbrtowc, __msvcrt_mbrtowc) | |
7 | + (__mingw_btowc, __msvcrt_btowc, __mingw_mbsrtowcs, __msvcrt_mbsrtowcs) | |
8 | + (__mingw_wctob, __msvcrt_wctob, __mingw_wcrtomb, __msvcrt_wcrtomb) | |
9 | + (__mingw_wcsrtombs, __msvcrt_wcsrtombs): Delete prototypes, and... | |
10 | + (mbrlen, mbrtowc, btowc, mbsrtowcs, wctomb, wcrtomb, wcsrtombs): | |
11 | + ...their corresponding redirected inline implementations. | |
12 | + | |
13 | + * mingwex/btowc.c (__msvcrt_btowc): Delete implementation. | |
14 | + (__mingw_btowc_fallback, __mingw_btowc): Fold together, into... | |
15 | + (btowc): ...this publicly accessible function; add weak aliases... | |
16 | + (__mingw_btowc, __msvcrt_btowc): ...named thus. | |
17 | + | |
18 | + * mingwex/mbrlen.c (__msvcrt_mbrlen): Delete implementation. | |
19 | + (__mingw_mbrlen_fallback, __mingw_mbrlen): Fold together, into... | |
20 | + (mbrlen): ...this publicly accessible function; factor out codeset | |
21 | + and codeset property initializations; add weak aliases... | |
22 | + (__mingw_mbrlen, __msvcrt_mbrlen): ...named thus. | |
23 | + | |
24 | + * mingwex/mbrtowc.c (__msvcrt_mbrtowc): Delete implementation. | |
25 | + (__mingw_mbrtowc_fallback, __mingw_mbrtowc): Fold together, into... | |
26 | + (mbrtowc): ...this publicly accessible function; factor out codeset | |
27 | + and codeset property initializations; add weak aliases... | |
28 | + (__mingw_mbrtowc, __msvcrt_mbrtowc): ...named thus. | |
29 | + | |
30 | + * mingwex/mbsrtowcs.c (__msvcrt_mbsrtowcs): Delete implementation. | |
31 | + (__mingw_mbsrtowcs_fallback, __mingw_mbsrtowcs): Fold; rename as... | |
32 | + (mbsrtowcs): ...this publicly accessible function; add weak aliases... | |
33 | + (__mingw_mbsrtowcs, __msvcrt_mbsrtowcs): ...named thus. | |
34 | + (__mbsrtowcs_fallback): Rename it as... | |
35 | + (__mbsrtowcs_internal): ...this. | |
36 | + | |
37 | + * mingwex/mbrconv.c (__mingw_mbrtowc_handler): Initialize codeset. | |
38 | + | |
39 | + * mingwex/wcrtomb.c (__msvcrt_wcrtomb): Delete implementation. | |
40 | + (__mingw_wcrtomb_fallback, __mingw_wcrtomb): Fold together, into... | |
41 | + (wcrtomb): ...this publicly accessible function; add weak aliases... | |
42 | + (__mingw_wcrtomb, __msvcrt_wcrtomb): ...named thus. | |
43 | + (__wcrtomb_fallback): Rename it as... | |
44 | + (__wcrtomb_internal): ...this. | |
45 | + | |
46 | + * mingwex/wcsrtombs.c (__mingw_wcsrtombs): Rename it as... | |
47 | + (wcsrtombs): ...this ISO-C99 name; preserve delegation to... | |
48 | + (__mingw_wcsrtombs_fallback): ...this, but rename it as... | |
49 | + (__mingw_wcsrtombs_internal): ...this; inline it. | |
50 | + (__msvcrt_wcsrtombs): Delete implementation. | |
51 | + (__mingw_wcsrtombs, __msvcrt_wcsrtombs): Reinstate as weak aliases. | |
52 | + | |
53 | + * mingwex/wctob.c (__msvcrt_wctob): Delete implementation. | |
54 | + (__mingw_wctob_fallback, __mingw_wctob): Fold together, into... | |
55 | + (wctob): ...this publicly accessible function; add weak aliases... | |
56 | + (__mingw_wctob, __msvcrt_wctob): ...named thus. | |
57 | + | |
1 | 58 | 2020-06-03 Keith Marshall <keith@users.osdn.me> |
2 | 59 | |
3 | 60 | Prepare and publish MinGW.org WSL-5.3.3 release. |
@@ -534,7 +534,7 @@ typedef int mbstate_t; | ||
534 | 534 | * maybe also in some earlier non-free DLLs, such as MSVCP60.DLL and |
535 | 535 | * later); they are also available in MSVCRT.DLL, from Vista onward, |
536 | 536 | * but to provide continuing support for earlier Windows versions, |
537 | - * we invoke them via MinGW specific wrappers, defined below. | |
537 | + * we always use MinGW replacements, provided in libmingwex.a | |
538 | 538 | */ |
539 | 539 | __cdecl __MINGW_NOTHROW wint_t btowc (int); |
540 | 540 | __cdecl __MINGW_NOTHROW int wctob (wint_t); |
@@ -554,109 +554,6 @@ __cdecl __MINGW_NOTHROW size_t wcrtomb | ||
554 | 554 | __cdecl __MINGW_NOTHROW size_t wcsrtombs |
555 | 555 | (char *__restrict__, const wchar_t **__restrict__, size_t, mbstate_t *__restrict__); |
556 | 556 | |
557 | -/* To provide support for the above, on legacy Windows versions, | |
558 | - * we implement fall back wrappers in libmingwex.a; each of these | |
559 | - * will delegate to the corresponding Microsoft implementation, if | |
560 | - * it exists in the process address space; otherwise, execution | |
561 | - * will fall back to a MinGW implementation... | |
562 | - */ | |
563 | -__cdecl __MINGW_NOTHROW wint_t __msvcrt_btowc (int); | |
564 | - | |
565 | -__cdecl __MINGW_NOTHROW size_t __msvcrt_mbrlen | |
566 | -(const char *__restrict__, size_t, mbstate_t *__restrict__); | |
567 | - | |
568 | -__cdecl __MINGW_NOTHROW size_t __msvcrt_mbrtowc | |
569 | -(wchar_t *__restrict__, const char *__restrict__, size_t, mbstate_t *__restrict__); | |
570 | - | |
571 | -__cdecl __MINGW_NOTHROW size_t __msvcrt_mbsrtowcs | |
572 | -(wchar_t *__restrict__, const char **__restrict__, size_t, mbstate_t *__restrict__); | |
573 | - | |
574 | -__cdecl __MINGW_NOTHROW int __msvcrt_wctob (wint_t); | |
575 | - | |
576 | -__cdecl __MINGW_NOTHROW size_t __msvcrt_wcrtomb | |
577 | -(char * __restrict__, wchar_t, mbstate_t *__restrict__); | |
578 | - | |
579 | -__cdecl __MINGW_NOTHROW size_t __msvcrt_wcsrtombs | |
580 | -(char *__restrict__, const wchar_t **__restrict__, size_t, mbstate_t *__restrict__); | |
581 | - | |
582 | -/* ...whereas, these alternatives will always invoke the MinGW | |
583 | - * fall back implementations, without considering any possible | |
584 | - * reference to MSVCRT.DLL or MSVCR80.DLL implementations. | |
585 | - */ | |
586 | -__cdecl __MINGW_NOTHROW wint_t __mingw_btowc (int); | |
587 | - | |
588 | -__cdecl __MINGW_NOTHROW size_t __mingw_mbrlen | |
589 | -(const char *__restrict__, size_t, mbstate_t *__restrict__); | |
590 | - | |
591 | -__cdecl __MINGW_NOTHROW size_t __mingw_mbrtowc | |
592 | -(wchar_t *__restrict__, const char *__restrict__, size_t, mbstate_t *__restrict__); | |
593 | - | |
594 | -__cdecl __MINGW_NOTHROW size_t __mingw_mbsrtowcs | |
595 | -(wchar_t *__restrict__, const char **__restrict__, size_t, mbstate_t *__restrict__); | |
596 | - | |
597 | -__cdecl __MINGW_NOTHROW int __mingw_wctob (wint_t); | |
598 | - | |
599 | -__cdecl __MINGW_NOTHROW size_t __mingw_wcrtomb | |
600 | -(char * __restrict__, wchar_t, mbstate_t *__restrict__); | |
601 | - | |
602 | -__cdecl __MINGW_NOTHROW size_t __mingw_wcsrtombs | |
603 | -(char *__restrict__, const wchar_t **__restrict__, size_t, mbstate_t *__restrict__); | |
604 | - | |
605 | -#if __MSVCRT_VERSION__ < __MSVCR80_DLL | |
606 | -/* For linking with all versions of MSVCRT.DLL, and with non-free | |
607 | - * alternatives predating MSVCR80.DLL, we enforce inline mapping to | |
608 | - * the libmingwex.a implementations, (which will delegate the calls | |
609 | - * to the Microsoft DLL implementations, when they are available, | |
610 | - * but substitute the MinGW replacements as required). | |
611 | - */ | |
612 | -#undef __mingw_redirect | |
613 | -#if _ISOC99_SOURCE & 0x08 | |
614 | -/* The user has explicitly requested ISO-C99 compatibility; ensure | |
615 | - * that calls to the following functions are serviced by the MinGW | |
616 | - * implementations, regardless of availability of any alternative | |
617 | - * MSVCRT.DLL implementation. | |
618 | - */ | |
619 | -# define __mingw_redirect(NAME) __mingw_##NAME | |
620 | -#else | |
621 | -/* No explicit ISO-C99 compatibility has been requested; map calls | |
622 | - * to these functions to delegate to any MSVCRT.DLL implementations | |
623 | - * which may be available, or to fall back to the MinGW replacement | |
624 | - * implementations, when necessary. | |
625 | - */ | |
626 | -# define __mingw_redirect(NAME) __msvcrt_##NAME | |
627 | -#endif | |
628 | -/* FIXME: Maybe consider these mappings, even for linking with the | |
629 | - * non-free MSVCR80.DLL, and its descendants. | |
630 | - */ | |
631 | -__CRT_ALIAS __cdecl __MINGW_NOTHROW wint_t btowc (int __c) | |
632 | -{ return __mingw_redirect(btowc( __c )); } | |
633 | - | |
634 | -__CRT_ALIAS __cdecl __MINGW_NOTHROW size_t mbrlen | |
635 | -(const char *__mbc, size_t __n, mbstate_t *__ps) | |
636 | -{ return __mingw_redirect(mbrlen( __mbc, __n, __ps )); } | |
637 | - | |
638 | -__CRT_ALIAS __cdecl __MINGW_NOTHROW size_t mbrtowc | |
639 | -(wchar_t *__wc, const char *__mbc, size_t __n, mbstate_t *__ps) | |
640 | -{ return __mingw_redirect(mbrtowc( __wc, __mbc, __n, __ps )); } | |
641 | - | |
642 | -__CRT_ALIAS __cdecl __MINGW_NOTHROW size_t mbsrtowcs | |
643 | -(wchar_t *__wcs, const char **__mbs, size_t __n, mbstate_t *__ps) | |
644 | -{ return __mingw_redirect(mbsrtowcs( __wcs, __mbs, __n, __ps )); } | |
645 | - | |
646 | -__CRT_ALIAS __cdecl __MINGW_NOTHROW int wctob (wint_t __wc) | |
647 | -{ return __mingw_redirect(wctob( __wc )); } | |
648 | - | |
649 | -__CRT_ALIAS __cdecl __MINGW_NOTHROW size_t wcrtomb | |
650 | -(char * __mbc, wchar_t __wc, mbstate_t *__ps) | |
651 | -{ return __mingw_redirect(wcrtomb(__mbc, __wc, __ps)); } | |
652 | - | |
653 | -__CRT_ALIAS __cdecl __MINGW_NOTHROW size_t wcsrtombs | |
654 | -(char *__mbs, const wchar_t **__wcs, size_t __len, mbstate_t *__ps) | |
655 | -{ return __mingw_redirect(wcsrtombs(__mbs, __wcs, __len, __ps)); } | |
656 | - | |
657 | -#undef __mingw_redirect | |
658 | -#endif /* ! MSVCR80.DLL or later */ | |
659 | - | |
660 | 557 | #if defined _ISOC99_SOURCE || defined __cplusplus |
661 | 558 | /* These ISO-C99 functions are implemented in libmingwex.a, |
662 | 559 | * or, in some cases, as inline stubs; while provided as MinGW |
@@ -7,6 +7,7 @@ | ||
7 | 7 | * potential wchar_t overflow error, which may occur with functions such |
8 | 8 | * as mbrtowc(), which may need to return surrogate pairs. |
9 | 9 | * |
10 | + * | |
10 | 11 | * $Id$ |
11 | 12 | * |
12 | 13 | * Written by Keith Marshall <keith@users.osdn.me> |
@@ -35,74 +36,30 @@ | ||
35 | 36 | */ |
36 | 37 | #include "wcharmap.h" |
37 | 38 | |
38 | -/* For runtime delegation, we need a mechanism for detection of an | |
39 | - * implementation, within the default C runtime DLL; we may use the | |
40 | - * MinGW dlfcn emulation, to facilitate this. | |
41 | - */ | |
42 | -#include <dlfcn.h> | |
43 | - | |
44 | 39 | /* We also need <stdio.h>, for EOF. |
45 | 40 | */ |
46 | 41 | #include <stdio.h> |
47 | 42 | |
48 | -static wint_t __mingw_btowc_fallback( int c ) | |
49 | -{ /* Fallback function, providing an implementation of the btowc() | |
50 | - * function, when none is available within the Microsoft runtime. | |
51 | - * This performs an MBCS to wchar_t conversion on the given single | |
43 | +wint_t btowc( int c ) | |
44 | +{ /* Implementation of ISO-C99 btowc() function, in libmingwex.a; | |
45 | + * this performs an MBCS to wchar_t conversion on the given single | |
52 | 46 | * character argument, (expressed as an int), returning WEOF in |
53 | 47 | * the event that conversion fails. |
54 | 48 | */ |
55 | 49 | if( c != EOF ) |
56 | 50 | { wint_t wc_result; |
51 | + (void)(__mingw_mbrtowc_codeset_init()); | |
57 | 52 | if( __mingw_mbtowc_convert( (char *)(&c), 1, &wc_result, 1) == 1 ) |
58 | 53 | return wc_result; |
59 | 54 | } |
60 | 55 | return WEOF; |
61 | 56 | } |
62 | 57 | |
63 | -wint_t __mingw_btowc( int c ) | |
64 | -{ /* Wrapper for the btowc() function; this will unconditionally | |
65 | - * delegate the call to the MinGW fallback implementation, (as | |
66 | - * implemented above), after initialization of the effective | |
67 | - * codeset file-global variable. | |
68 | - */ | |
69 | - (void)(__mingw_mbrtowc_codeset_init()); | |
70 | - return __mingw_btowc_fallback( c ); | |
71 | -} | |
72 | - | |
73 | -wint_t __msvcrt_btowc( int c ) | |
74 | -{ /* Wrapper for the btowc() function; it will initially attempt | |
75 | - * to delegate the call to a Microsoft-provided implementation, | |
76 | - * but if no such implementation can be found, fall back to the | |
77 | - * MinGW substitute (defined above). | |
78 | - */ | |
79 | - static wint_t (*redirector_hook)( int ) = NULL; | |
80 | - | |
81 | - /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with | |
82 | - * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus, | |
83 | - * Microsoft's btowc() is likely to be similarly unreliable, so we | |
84 | - * always use the MinGW fallback with such code pages. | |
85 | - */ | |
86 | - if( __mb_cur_max_for_codeset(__mingw_mbrtowc_codeset_init()) > 2 ) | |
87 | - return __mingw_btowc_fallback( c ); | |
88 | - | |
89 | - /* On first time call, we don't know which implementation is to be | |
90 | - * selected; look for a Microsoft implementation, which, if available, | |
91 | - * may be registered for immediate use on this, and any subsequent, | |
92 | - * calls to this function wrapper... | |
93 | - */ | |
94 | - if( (redirector_hook == NULL) | |
95 | - && ((redirector_hook = dlsym( RTLD_DEFAULT, "btowc" )) == NULL) ) | |
96 | - | |
97 | - /* ...but when no Microsoft implementation can be found, register | |
98 | - * the MinGW fall back in its stead. | |
99 | - */ | |
100 | - redirector_hook = __mingw_btowc_fallback; | |
101 | - | |
102 | - /* Finally, delegate the call to whichever implementation has been | |
103 | - * registered on first-time call. | |
104 | - */ | |
105 | - return redirector_hook( c ); | |
106 | -} | |
58 | +/* FIXME: these aliases are provided for link-compatibitity with | |
59 | + * libraries compiled against mingwrt-5.3.x; they may be removed | |
60 | + * from future versions of mingwrt. | |
61 | + */ | |
62 | +wint_t __msvcrt_btowc( int c )__attribute__((__weak__,__alias__("btowc"))); | |
63 | +wint_t __mingw_btowc( int c )__attribute__((__weak__,__alias__("btowc"))); | |
107 | 64 | |
108 | 65 | /* $RCSfile$: end of file */ |
@@ -2,8 +2,8 @@ | ||
2 | 2 | * mbrconv.c |
3 | 3 | * |
4 | 4 | * Implementation of back-end MBCS to wchar_t conversion infrastructure |
5 | - * routines to support the mbrlen(), and mbrtowc() functions, for use in | |
6 | - * those applications where Microsoft does not provide adequate support. | |
5 | + * routines to support the MinGW mbrlen(), and mbrtowc() functions. | |
6 | + * | |
7 | 7 | * |
8 | 8 | * $Id$ |
9 | 9 | * |
@@ -60,127 +60,129 @@ size_t __mingw_mbrtowc_handler | ||
60 | 60 | ( wchar_t *restrict pwc, const char *restrict s, size_t n, |
61 | 61 | mbstate_t *restrict ps |
62 | 62 | ) |
63 | -{ /* Common fallback handler for mbrtowc() and mbrlen() functions. | |
63 | +{ /* Common handler for MinGW mbrtowc() and mbrlen() functions. | |
64 | 64 | */ |
65 | - union { mbstate_t st; wchar_t wc[2]; } retval; | |
66 | - union { mbstate_t st; char mb[MB_LEN_MAX]; wchar_t wc[2]; } state = { *ps }; | |
67 | - unsigned int mbrlen_cur_max = __mingw_mbrlen_cur_max(); | |
68 | - size_t pending, len = 0, count = 0; | |
65 | + (void)(__mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() )); | |
66 | + { union { mbstate_t st; wchar_t wc[2]; } retval; | |
67 | + union { mbstate_t st; char mb[MB_LEN_MAX]; wchar_t wc[2]; } state = { *ps }; | |
68 | + unsigned int mbrlen_cur_max = __mingw_mbrlen_cur_max(); | |
69 | + size_t pending, len = 0, count = 0; | |
69 | 70 | |
70 | - /* Any residual state, from a preceding call, has been captured | |
71 | - * in the local "state" union; assume that this call will clear | |
72 | - * any such state, leaving no further residual. | |
73 | - */ | |
74 | - *ps = (mbstate_t)(0); | |
71 | + /* Any residual state, from a preceding call, has been captured | |
72 | + * in the local "state" union; assume that this call will clear | |
73 | + * any such state, leaving no further residual. | |
74 | + */ | |
75 | + *ps = (mbstate_t)(0); | |
75 | 76 | |
76 | - /* Normally, it makes no sense to call mbrlen(), or mbrtowc(), | |
77 | - * with a look-ahead byte count limit of zero; however, due to | |
78 | - * the constraints imposed by MS-Windows using UTF-16LE as the | |
79 | - * underlying encoding for wchar_t... | |
80 | - */ | |
81 | - if( n == 0 ) | |
82 | - { /* ...we allow this, as a special case, so that, when any | |
83 | - * immediately preceding call to mbrtowc() has returned a | |
84 | - * high surrogate, the accompanying low surrogate... | |
77 | + /* Normally, it makes no sense to call mbrlen(), or mbrtowc(), | |
78 | + * with a look-ahead byte count limit of zero; however, due to | |
79 | + * the constraints imposed by MS-Windows using UTF-16LE as the | |
80 | + * underlying encoding for wchar_t... | |
85 | 81 | */ |
86 | - if( IS_SURROGATE_PAIR( state.wc[0], state.wc[1] ) ) | |
87 | - { | |
88 | - /* ...may be returned to the caller, without consuming | |
89 | - * any further bytes from the original MBCS sequence. | |
82 | + if( n == 0 ) | |
83 | + { /* ...we allow this, as a special case, so that, when any | |
84 | + * immediately preceding call to mbrtowc() has returned a | |
85 | + * high surrogate, the accompanying low surrogate... | |
86 | + */ | |
87 | + if( IS_SURROGATE_PAIR( state.wc[0], state.wc[1] ) ) | |
88 | + { | |
89 | + /* ...may be returned to the caller, without consuming | |
90 | + * any further bytes from the original MBCS sequence. | |
91 | + */ | |
92 | + if( pwc != NULL ) *pwc = state.wc[1]; | |
93 | + return (size_t)(0); | |
94 | + } | |
95 | + /* When the conversion state does not represent a deferred | |
96 | + * low surrogate, then restore it, and pass this through as | |
97 | + * an effective no-op. | |
90 | 98 | */ |
91 | - if( pwc != NULL ) *pwc = state.wc[1]; | |
92 | - return (size_t)(0); | |
99 | + *ps = state.st; | |
100 | + return (size_t)(-2); | |
93 | 101 | } |
94 | - /* When the conversion state does not represent a deferred | |
95 | - * low surrogate, then restore it, and pass this through as | |
96 | - * an effective no-op. | |
102 | + /* In any context, other than the preceding (special) n == 0 | |
103 | + * case, for retrieval of a deferred low surrogate, a pending | |
104 | + * conversion state which represents a surrogate pair is not | |
105 | + * a valid state; reject it. | |
97 | 106 | */ |
98 | - *ps = state.st; | |
99 | - return (size_t)(-2); | |
100 | - } | |
101 | - /* In any context, other than the preceding (special) n == 0 | |
102 | - * case, for retrieval of a deferred low surrogate, a pending | |
103 | - * conversion state which represents a surrogate pair is not | |
104 | - * a valid state; reject it. | |
105 | - */ | |
106 | - if( IS_SURROGATE_PAIR( state.wc[0], state.wc[1] ) ) | |
107 | - return errout( EINVAL, (size_t)(-1) ); | |
108 | - | |
109 | - /* Step over any pending MBCS bytes, which may already be | |
110 | - * present within the conversion state buffer, accumulating | |
111 | - * both the count of such pending bytes, together with a | |
112 | - * partial count of total bytes for conversion. | |
113 | - */ | |
114 | - while( (len < sizeof( mbstate_t )) && (state.mb[len] != '\0') ) | |
115 | - ++len; | |
116 | - pending = len; | |
107 | + if( IS_SURROGATE_PAIR( state.wc[0], state.wc[1] ) ) | |
108 | + return errout( EINVAL, (size_t)(-1) ); | |
117 | 109 | |
118 | - /* Append MBCS bytes from the input sequence, to the pending | |
119 | - * state buffer, up to the specified look-ahead count limit, or | |
120 | - * until the filled length of the buffer becomes equivalent to | |
121 | - * the effective value of MB_CUR_MAX. | |
122 | - */ | |
123 | - while( (len < mbrlen_cur_max) && (count < n) && (s[count] != '\0') ) | |
124 | - state.mb[len++] = s[count++]; | |
110 | + /* Step over any pending MBCS bytes, which may already be | |
111 | + * present within the conversion state buffer, accumulating | |
112 | + * both the count of such pending bytes, together with a | |
113 | + * partial count of total bytes for conversion. | |
114 | + */ | |
115 | + while( (len < sizeof( mbstate_t )) && (state.mb[len] != '\0') ) | |
116 | + ++len; | |
117 | + pending = len; | |
125 | 118 | |
126 | - /* If the pending look-ahead state has not yet been padded | |
127 | - * to the full MB_CUR_MAX length, ensure that it is encoded | |
128 | - * as a NUL terminated MBCS sequence, before attempting to | |
129 | - * interpret it as a complete MBCS sequence. | |
130 | - */ | |
131 | - if( len < mbrlen_cur_max ) state.mb[len] = '\0'; | |
132 | - if( (int)(count = mbrlen_min( state.mb, len, retval.wc )) > 0 ) | |
133 | - { | |
134 | - /* No valid conversion state should ever exist, where no | |
135 | - * additional bytes are required to complete a previously | |
136 | - * deferred multibyte character. | |
119 | + /* Append MBCS bytes from the input sequence, to the pending | |
120 | + * state buffer, up to the specified look-ahead count limit, or | |
121 | + * until the filled length of the buffer becomes equivalent to | |
122 | + * the effective value of MB_CUR_MAX. | |
137 | 123 | */ |
138 | - if( pending >= count ) return errout( EILSEQ, (size_t)(-1) ); | |
124 | + while( (len < mbrlen_cur_max) && (count < n) && (s[count] != '\0') ) | |
125 | + state.mb[len++] = s[count++]; | |
139 | 126 | |
140 | - /* The accumulated encoding state does now represent a | |
141 | - * complete MBCS sequence; when servicing an mbrtowc() call, | |
142 | - * with non-NULL return value pointer, we must store that | |
143 | - * return value... | |
127 | + /* If the pending look-ahead state has not yet been padded | |
128 | + * to the full MB_CUR_MAX length, ensure that it is encoded | |
129 | + * as a NUL terminated MBCS sequence, before attempting to | |
130 | + * interpret it as a complete MBCS sequence. | |
144 | 131 | */ |
145 | - if( pwc != NULL ) | |
146 | - { /* ...noting that, under MS-Windows, we may not be able | |
147 | - * to accommodate the entire converted value in a single | |
148 | - * UTF-16 wchar_t, in which case we must return it as a | |
149 | - * surrogate pair, of which only the high surrogate can | |
150 | - * be returned now... | |
132 | + if( len < mbrlen_cur_max ) state.mb[len] = '\0'; | |
133 | + if( (int)(count = mbrlen_min( state.mb, len, retval.wc )) > 0 ) | |
134 | + { | |
135 | + /* No valid conversion state should ever exist, where no | |
136 | + * additional bytes are required to complete a previously | |
137 | + * deferred multibyte character. | |
138 | + */ | |
139 | + if( pending >= count ) return errout( EILSEQ, (size_t)(-1) ); | |
140 | + | |
141 | + /* The accumulated encoding state does now represent a | |
142 | + * complete MBCS sequence; when servicing an mbrtowc() call, | |
143 | + * with non-NULL return value pointer, we must store that | |
144 | + * return value... | |
151 | 145 | */ |
152 | - if( IS_HIGH_SURROGATE( *pwc = retval.wc[0] ) ) | |
153 | - /* ...with the entire pair being stored at the passed | |
154 | - * mbstate_t reference buffer, allowing for subsequent | |
155 | - * retrieval of the low surrogate. | |
146 | + if( pwc != NULL ) | |
147 | + { /* ...noting that, under MS-Windows, we may not be able | |
148 | + * to accommodate the entire converted value in a single | |
149 | + * UTF-16 wchar_t, in which case we must return it as a | |
150 | + * surrogate pair, of which only the high surrogate can | |
151 | + * be returned now... | |
156 | 152 | */ |
157 | - *ps = retval.st; | |
158 | - } | |
159 | - /* In the case that the wchar_t return value represents a | |
160 | - * NUL character, ISO-C99 prescribes that, whichever of the | |
161 | - * supported functions is being serviced, the returned byte | |
162 | - * count, of converted MBCS bytes, must be zero. | |
163 | - */ | |
164 | - if( retval.wc[0] == L'\0' ) return (size_t)(0); | |
153 | + if( IS_HIGH_SURROGATE( *pwc = retval.wc[0] ) ) | |
154 | + /* ...with the entire pair being stored at the passed | |
155 | + * mbstate_t reference buffer, allowing for subsequent | |
156 | + * retrieval of the low surrogate. | |
157 | + */ | |
158 | + *ps = retval.st; | |
159 | + } | |
160 | + /* In the case that the wchar_t return value represents a | |
161 | + * NUL character, ISO-C99 prescribes that, whichever of the | |
162 | + * supported functions is being serviced, the returned byte | |
163 | + * count, of converted MBCS bytes, must be zero. | |
164 | + */ | |
165 | + if( retval.wc[0] == L'\0' ) return (size_t)(0); | |
165 | 166 | |
166 | - /* The effective function return value, for this case, is | |
167 | - * the count of bytes accumulated into the completed MBCS | |
168 | - * byte sequence, discounting those which were deferred | |
169 | - * from any preceding call. | |
170 | - */ | |
171 | - return (count - pending); | |
172 | - } | |
173 | - else if( count < mbrlen_cur_max ) | |
174 | - { /* The accumulated encoding state does not represent a | |
175 | - * complete, and valid MBCS sequence, but we have not yet | |
176 | - * accumulated as many bytes as the effective MB_CUR_MAX | |
177 | - * length can accommodate; save the encoding state for | |
178 | - * deferred reprocessing, and return the appropriate | |
179 | - * pseudo-count to inform the caller that this encoding | |
180 | - * state may yet develop into a valid MBCS sequence. | |
181 | - */ | |
182 | - *ps = retval.st; | |
183 | - return (size_t)(-2); | |
167 | + /* The effective function return value, for this case, is | |
168 | + * the count of bytes accumulated into the completed MBCS | |
169 | + * byte sequence, discounting those which were deferred | |
170 | + * from any preceding call. | |
171 | + */ | |
172 | + return (count - pending); | |
173 | + } | |
174 | + else if( count < mbrlen_cur_max ) | |
175 | + { /* The accumulated encoding state does not represent a | |
176 | + * complete, and valid MBCS sequence, but we have not yet | |
177 | + * accumulated as many bytes as the effective MB_CUR_MAX | |
178 | + * length can accommodate; save the encoding state for | |
179 | + * deferred reprocessing, and return the appropriate | |
180 | + * pseudo-count to inform the caller that this encoding | |
181 | + * state may yet develop into a valid MBCS sequence. | |
182 | + */ | |
183 | + *ps = retval.st; | |
184 | + return (size_t)(-2); | |
185 | + } | |
184 | 186 | } |
185 | 187 | /* If neither of the preceding encoding states prevails, then |
186 | 188 | * the current state must represent an invalid MBCS sequence; |
@@ -1,9 +1,11 @@ | ||
1 | 1 | /* |
2 | 2 | * mbrlen.c |
3 | 3 | * |
4 | - * MinGW.org replacement for the ISO-C99 mbrlen() function; delegates to a | |
5 | - * Microsoft implementation, if available in the C runtime DLL, (unless this | |
6 | - * is overridden by user choice); otherwise handles the call locally. | |
4 | + * MinGW.org replacement for the ISO-C99 mbrlen() function, supporting its | |
5 | + * use on any legacy Windows version for which Microsoft does not provide it, | |
6 | + * while replacing the Microsoft implementation on those Windows versions | |
7 | + * for which it is provided. | |
8 | + * | |
7 | 9 | * |
8 | 10 | * $Id$ |
9 | 11 | * |
@@ -33,75 +35,23 @@ | ||
33 | 35 | */ |
34 | 36 | #include "wcharmap.h" |
35 | 37 | |
36 | -/* For runtime delegation, we need a mechanism for detection of an | |
37 | - * implementation, within the default C runtime DLL; we may use the | |
38 | - * MinGW dlfcn emulation, to facilitate this. | |
39 | - */ | |
40 | -#include <dlfcn.h> | |
41 | - | |
42 | -static size_t __mingw_mbrlen_fallback | |
43 | -( const char *restrict s, size_t n, mbstate_t *restrict ps ) | |
38 | +size_t mbrlen( const char *restrict s, size_t n, mbstate_t *restrict ps ) | |
44 | 39 | { |
45 | - /* Fallback function, providing an implementation of the mbrlen() | |
46 | - * function, when none is available within the Microsoft C runtime, | |
47 | - * or the user has explicitly overridden accessibility of any such | |
48 | - * Microsoft implementation. | |
49 | - * | |
50 | - * This is simply delegated to common handler, for both mbrlen(), | |
51 | - * and mbrtowc() fallback functions. | |
40 | + /* Implementation of ISO-C99 mbrlen() function, in libmingwex.a; | |
41 | + * this is simply delegated to the common handler, which services | |
42 | + * both the mbrlen(), and mbrtowc() functions. | |
52 | 43 | */ |
53 | 44 | return __mingw_mbrtowc_handler( NULL, s, n, __mbrtowc_state( ps ) ); |
54 | 45 | } |
55 | 46 | |
56 | -size_t __mingw_mbrlen | |
57 | -( const char *restrict s, size_t n, mbstate_t *restrict ps ) | |
58 | -{ | |
59 | - /* Wrapper for the mbrlen() function; this will unconditionally | |
60 | - * delegate the call to the MinGW fallback implementation, (defined | |
61 | - * above), irrespective of availability of any Microsoft-provided | |
62 | - * implementation. | |
63 | - */ | |
64 | - __mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ); | |
65 | - return __mingw_mbrlen_fallback( s, n, ps ); | |
66 | -} | |
67 | - | |
68 | -size_t __msvcrt_mbrlen | |
69 | -( const char *restrict s, size_t n, mbstate_t *restrict ps ) | |
70 | -{ | |
71 | - /* Wrapper for the mbrlen() function; this will initially attempt | |
72 | - * to delegate the call to a Microsoft-provided implementation, but | |
73 | - * if no such implementation can be found, fall back to the MinGW | |
74 | - * substitute (defined above). | |
75 | - */ | |
76 | - typedef size_t (*redirector_t) | |
77 | - ( const char *restrict, size_t, mbstate_t *restrict ); | |
78 | - static redirector_t redirector_hook = NULL; | |
79 | - | |
80 | - /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with | |
81 | - * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus, | |
82 | - * Microsoft's mbrlen() is likely to be similarly unreliable, so | |
83 | - * always use the MinGW fallback with such code pages. | |
84 | - */ | |
85 | - if( __mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ) > 2 ) | |
86 | - return __mingw_mbrlen_fallback( s, n, ps ); | |
87 | - | |
88 | - /* On first time call, we don't know which implementation is to be | |
89 | - * selected; look for a Microsoft implementation, which, if available, | |
90 | - * may be registered for immediate use on this, and any subsequent, | |
91 | - * calls to this function wrapper... | |
92 | - */ | |
93 | - if( (redirector_hook == NULL) | |
94 | - && ((redirector_hook = dlsym( RTLD_DEFAULT, "mbrlen" )) == NULL) ) | |
95 | - | |
96 | - /* ...but when no Microsoft implementation can be found, register | |
97 | - * the MinGW fall back in its stead. | |
98 | - */ | |
99 | - redirector_hook = __mingw_mbrlen_fallback; | |
47 | +/* FIXME: these aliases are provided for link-compatibitity with | |
48 | + * libraries compiled against mingwrt-5.3.x; they may be removed | |
49 | + * from future versions of mingwrt. | |
50 | + */ | |
51 | +size_t __mingw_mbrlen( const char *restrict, size_t, mbstate_t *restrict ) | |
52 | +__attribute__((__weak__,__alias__("mbrlen"))); | |
100 | 53 | |
101 | - /* Finally, delegate the call to whichever implementation has been | |
102 | - * registered on first-time call. | |
103 | - */ | |
104 | - return redirector_hook( s, n, ps ); | |
105 | -} | |
54 | +size_t __msvcrt_mbrlen( const char *restrict, size_t, mbstate_t *restrict ) | |
55 | +__attribute__((__weak__,__alias__("mbrlen"))); | |
106 | 56 | |
107 | 57 | /* $RCSfile$: end of file */ |
@@ -1,9 +1,11 @@ | ||
1 | 1 | /* |
2 | 2 | * mbrtowc.c |
3 | 3 | * |
4 | - * MinGW.org replacement for the ISO-C99 mbrtowc() function; delegates to a | |
5 | - * Microsoft implementation, if available in the C runtime DLL, (unless this | |
6 | - * is overridden by user choice); otherwise handles the call locally. | |
4 | + * MinGW.org replacement for the ISO-C99 mbrtowc() function, supporting | |
5 | + * use of this function on legacy Windows versions, for which Microsoft | |
6 | + * does not provide it, while replacing the Microsoft implementation on | |
7 | + * those Windows versions for which it is provided. | |
8 | + * | |
7 | 9 | * |
8 | 10 | * $Id$ |
9 | 11 | * |
@@ -33,20 +35,11 @@ | ||
33 | 35 | */ |
34 | 36 | #include "wcharmap.h" |
35 | 37 | |
36 | -/* For runtime delegation, we need a mechanism for detection of an | |
37 | - * implementation, within the default C runtime DLL; we may use the | |
38 | - * MinGW dlfcn emulation, to facilitate this. | |
39 | - */ | |
40 | -#include <dlfcn.h> | |
41 | - | |
42 | -static size_t __mingw_mbrtowc_fallback | |
38 | +size_t mbrtowc | |
43 | 39 | ( wchar_t *restrict pwc, const char *restrict s, size_t n, |
44 | 40 | mbstate_t *restrict ps |
45 | 41 | ) |
46 | -{ /* Fallback function, providing an implementation of the mbrtowc() | |
47 | - * function, when none is available within the Microsoft C runtime, | |
48 | - * or the user has explicitly overridden accessibility of any such | |
49 | - * Microsoft implementation. | |
42 | +{ /* Implementation of ISO-C99 mbrtowc() function, in libmingwex.a | |
50 | 43 | * |
51 | 44 | * When s is a NULL pointer, ISO-C99 decrees that the call shall |
52 | 45 | * be interpreted as the equivalent of: |
@@ -55,69 +48,25 @@ static size_t __mingw_mbrtowc_fallback | ||
55 | 48 | * |
56 | 49 | * with any other supplied values for pwc and n being ignored. |
57 | 50 | */ |
58 | - if( s == NULL ) return __mingw_mbrtowc_fallback( NULL, "", 1, ps ); | |
51 | + if( s == NULL ) return mbrtowc( NULL, "", 1, ps ); | |
59 | 52 | |
60 | 53 | /* Otherwise, we simply delegate the the call to the common |
61 | - * handler, which implements the fallback action for both the | |
62 | - * mbrlen() function, and the mbrtowc() function. | |
54 | + * handler, which implements the action for both the mbrlen() | |
55 | + * function, and the mbrtowc() function. | |
63 | 56 | */ |
64 | 57 | return __mingw_mbrtowc_handler( pwc, s, n, __mbrtowc_state( ps ) ); |
65 | 58 | } |
66 | 59 | |
60 | +/* FIXME: these aliases are provided for link-compatibitity with | |
61 | + * libraries compiled against mingwrt-5.3.x; they may be removed | |
62 | + * from future versions of mingwrt. | |
63 | + */ | |
67 | 64 | size_t __mingw_mbrtowc |
68 | -( wchar_t *restrict pwc, const char *restrict s, size_t n, | |
69 | - mbstate_t *restrict ps | |
70 | -) | |
71 | -{ /* Wrapper for the mbrtowc() function; this will unconditionally | |
72 | - * delegate the call to the MinGW fallback implementation, (defined | |
73 | - * above), irrespective of availability of any Microsoft-provided | |
74 | - * implementation. | |
75 | - * | |
76 | - * Note that, before handing off the call, we must unconditionally | |
77 | - * initialize the working codeset, and its effective MB_CUR_MAX. | |
78 | - */ | |
79 | - (void)(__mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() )); | |
80 | - return __mingw_mbrtowc_fallback( pwc, s, n, ps ); | |
81 | -} | |
65 | +( wchar_t *restrict, const char *restrict, size_t, mbstate_t *restrict ) | |
66 | +__attribute__((__weak__,__alias__("mbrtowc"))); | |
82 | 67 | |
83 | 68 | size_t __msvcrt_mbrtowc |
84 | -( wchar_t *restrict pwc, const char *restrict s, size_t n, | |
85 | - mbstate_t *restrict ps | |
86 | -) | |
87 | -{ /* Wrapper for the mbrtowc() function; this will initially attempt | |
88 | - * to delegate the call to a Microsoft-provided implementation, but | |
89 | - * if no such implementation can be found, fall back to the MinGW | |
90 | - * substitute (defined above). | |
91 | - */ | |
92 | - typedef size_t (*redirector_t) | |
93 | - ( wchar_t *restrict, const char *restrict, size_t, mbstate_t *restrict ); | |
94 | - static redirector_t redirector_hook = NULL; | |
95 | - | |
96 | - /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with | |
97 | - * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus, | |
98 | - * Microsoft's mbrtowc() is likely to be similarly unreliable, so | |
99 | - * always use the MinGW fallback with such code pages. | |
100 | - */ | |
101 | - if( __mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ) > 2 ) | |
102 | - return __mingw_mbrtowc_fallback( pwc, s, n, ps ); | |
103 | - | |
104 | - /* On first time call, we don't know which implementation is to be | |
105 | - * selected; look for a Microsoft implementation, which, if available, | |
106 | - * may be registered for immediate use on this, and any subsequent, | |
107 | - * calls to this function wrapper... | |
108 | - */ | |
109 | - if( (redirector_hook == NULL) | |
110 | - && ((redirector_hook = dlsym( RTLD_DEFAULT, "mbrtowc" )) == NULL) ) | |
111 | - | |
112 | - /* ...but when no Microsoft implementation can be found, register | |
113 | - * the MinGW fall back in its stead. | |
114 | - */ | |
115 | - redirector_hook = __mingw_mbrtowc_fallback; | |
116 | - | |
117 | - /* Finally, delegate the call to whichever implementation has been | |
118 | - * registered on first-time call. | |
119 | - */ | |
120 | - return redirector_hook( pwc, s, n, ps ); | |
121 | -} | |
69 | +( wchar_t *restrict, const char *restrict, size_t, mbstate_t *restrict ) | |
70 | +__attribute__((__weak__,__alias__("mbrtowc"))); | |
122 | 71 | |
123 | 72 | /* $RCSfile$: end of file */ |
@@ -1,9 +1,11 @@ | ||
1 | 1 | /* |
2 | 2 | * mbsrtowcs.c |
3 | 3 | * |
4 | - * MinGW.org replacement for the ISO-C99 mbsrtowcs() function; may delegate | |
5 | - * to a Microsoft implementation, if available in the C runtime DLL, (unless | |
6 | - * this is overridden by user choice); otherwise handles the call locally. | |
4 | + * MinGW.org replacement for the ISO-C99 mbsrtowcs() function, supporting | |
5 | + * its use on legacy Windows versions, for which Microsoft does not provide | |
6 | + * it, while replacing the Microsoft implementation on any Windows version | |
7 | + * for which it is provided. | |
8 | + * | |
7 | 9 | * |
8 | 10 | * $Id$ |
9 | 11 | * |
@@ -33,7 +35,6 @@ | ||
33 | 35 | */ |
34 | 36 | #include "wcharmap.h" |
35 | 37 | |
36 | -#include <dlfcn.h> | |
37 | 38 | #include <limits.h> |
38 | 39 | |
39 | 40 | static __mb_inline__ |
@@ -45,14 +46,12 @@ boolean __mingw_mbtowc_verify( const char *src, size_t len ) | ||
45 | 46 | return __mingw_mbtowc_copy( NULL, src, len ) != (size_t)(-1); |
46 | 47 | } |
47 | 48 | |
48 | -static __mb_inline__ size_t __mbsrtowcs_fallback | |
49 | +static __mb_inline__ size_t __mbsrtowcs_internal | |
49 | 50 | ( wchar_t *restrict wcs, const char **restrict src, size_t len, |
50 | 51 | mbstate_t *restrict ps |
51 | 52 | ) |
52 | -{ /* Internal fallback function, providing an implementation of the | |
53 | - * mbsrtowcs() function, when none is available in the Microsoft C | |
54 | - * runtime DLL, or the user has explicitly overridden selection of | |
55 | - * any such Microsoft implementation. | |
53 | +{ /* Internal implementation of the mbsrtowcs() function; this is | |
54 | + expanded inline, within the public implementation. | |
56 | 55 | */ |
57 | 56 | size_t count = (size_t)(0); |
58 | 57 | if( (src != NULL) && (*src != NULL) ) |
@@ -156,72 +155,28 @@ static __mb_inline__ size_t __mbsrtowcs_fallback | ||
156 | 155 | return count; |
157 | 156 | } |
158 | 157 | |
159 | -static size_t __mingw_mbsrtowcs_fallback | |
160 | -( wchar_t *restrict wcs, const char **restrict src, size_t len, | |
161 | - mbstate_t *restrict ps __attribute__((__unused__)) | |
162 | -) | |
163 | -{ /* MinGW fallback implementation for the mbsrtowcs() function; this | |
164 | - * is a trivial wrapper around the preceding implementation, (which | |
165 | - * should be expanded in-line), ensuring that an internal buffer is | |
166 | - * assigned for the "ps" argument, if the caller doesn't pass one. | |
167 | - */ | |
168 | - return __mbsrtowcs_fallback( wcs, src, len, __mbrtowc_state( ps ) ); | |
169 | -} | |
170 | - | |
171 | -size_t __mingw_mbsrtowcs | |
158 | +size_t mbsrtowcs | |
172 | 159 | ( wchar_t *restrict wcs, const char **restrict src, size_t len, |
173 | 160 | mbstate_t *restrict ps |
174 | 161 | ) |
175 | -{ /* Wrapper for the mbsrtowcs() function; this will unconditionally | |
176 | - * delegate the call to the MinGW fallback implementation, (defined | |
177 | - * above), irrespective of availability of any Microsoft-provided | |
178 | - * implementation. | |
179 | - * | |
180 | - * Note that, before handing off the call, we must unconditionally | |
181 | - * initialize the working codeset, and its effective MB_CUR_MAX. | |
162 | +{ /* Implementation of ISO-C99 mbsrtowcs() function, in libmingwex.a; | |
163 | + * this stores the effective codeset properties, before returning the | |
164 | + * result from expansion of the preceding inline implementation. | |
182 | 165 | */ |
183 | 166 | (void)(__mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() )); |
184 | - return __mingw_mbsrtowcs_fallback( wcs, src, len, ps ); | |
167 | + return __mbsrtowcs_internal( wcs, src, len, __mbrtowc_state( ps ) ); | |
185 | 168 | } |
186 | 169 | |
187 | -size_t __msvcrt_mbsrtowcs | |
188 | -( wchar_t *restrict wcs, const char **restrict src, size_t len, | |
189 | - mbstate_t *restrict ps | |
190 | -) | |
191 | -{ /* Wrapper for the mbsrtowcs() function; this will initially attempt | |
192 | - * to delegate the call to a Microsoft-provided implementation, but if | |
193 | - * no such implementation can be found, it will fall back to the MinGW | |
194 | - * substitute (defined above). | |
195 | - */ | |
196 | - typedef size_t (*redirector_t) | |
197 | - ( wchar_t *restrict, const char **restrict, size_t, mbstate_t *restrict ); | |
198 | - static redirector_t redirector_hook = NULL; | |
199 | - | |
200 | - /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with | |
201 | - * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus, | |
202 | - * Microsoft's mbsrtowcs() is likely to be similarly unreliable, so | |
203 | - * always use the MinGW fallback with such code pages. | |
204 | - */ | |
205 | - if( __mingw_mbrlen_cur_max_init( __mingw_mbrtowc_codeset_init() ) > 2 ) | |
206 | - return __mingw_mbsrtowcs_fallback( wcs, src, len, ps ); | |
207 | - | |
208 | - /* On first time call, we don't know which implementation is to be | |
209 | - * selected; look for a Microsoft implementation, which, if available, | |
210 | - * may be registered for immediate use on this, and any subsequent, | |
211 | - * calls to this function wrapper... | |
212 | - */ | |
213 | - if( (redirector_hook == NULL) | |
214 | - && ((redirector_hook = dlsym( RTLD_DEFAULT, "mbsrtowcs" )) == NULL) ) | |
215 | - | |
216 | - /* ...but when no Microsoft implementation can be found, register | |
217 | - * the MinGW fall back in its stead. | |
218 | - */ | |
219 | - redirector_hook = __mingw_mbsrtowcs_fallback; | |
170 | +/* FIXME: these aliases are provided for link-compatibitity with | |
171 | + * libraries compiled against mingwrt-5.3.x; they may be removed | |
172 | + * from future versions of mingwrt. | |
173 | + */ | |
174 | +size_t __mingw_mbsrtowcs | |
175 | +( wchar_t *restrict, const char **restrict, size_t, mbstate_t *restrict ) | |
176 | +__attribute__((__weak__,__alias__("mbsrtowcs"))); | |
220 | 177 | |
221 | - /* Finally, delegate the call to whichever implementation has been | |
222 | - * registered on first-time call. | |
223 | - */ | |
224 | - return redirector_hook( wcs, src, len, ps ); | |
225 | -} | |
178 | +size_t __msvcrt_mbsrtowcs | |
179 | +( wchar_t *restrict, const char **restrict, size_t, mbstate_t *restrict ) | |
180 | +__attribute__((__weak__,__alias__("mbsrtowcs"))); | |
226 | 181 | |
227 | 182 | /* $RCSfile$: end of file */ |
@@ -1,9 +1,11 @@ | ||
1 | 1 | /* |
2 | 2 | * wcrtomb.c |
3 | 3 | * |
4 | - * MinGW.org replacement for the wcrtomb() function; delegates to the | |
5 | - * Microsoft implementation, if available in the C runtime DLL, otherwise | |
6 | - * handles the call locally. | |
4 | + * MinGW.org replacement for the wcrtomb() function; supports use of this | |
5 | + * function on legacy Windows versions, for which it is not available in the | |
6 | + * C runtime DLL, and replaces the Microsoft implementation, in those cases | |
7 | + * where one is available. | |
8 | + * | |
7 | 9 | * |
8 | 10 | * $Id$ |
9 | 11 | * |
@@ -33,19 +35,11 @@ | ||
33 | 35 | */ |
34 | 36 | #include "wcharmap.h" |
35 | 37 | |
36 | -/* For runtime delegation, we need a mechanism for detection of an | |
37 | - * implementation, within the default C runtime DLL; we may use the | |
38 | - * MinGW dlfcn emulation, to facilitate this. | |
39 | - */ | |
40 | -#include <dlfcn.h> | |
41 | - | |
42 | -static __mb_inline__ size_t __wcrtomb_fallback | |
38 | +static __mb_inline__ size_t __wcrtomb_internal | |
43 | 39 | ( char *restrict mb, wchar_t wc, mbstate_t *ps ) |
44 | 40 | { |
45 | - /* Fallback function, providing an implementation of the wcrtomb() | |
46 | - * function, when none is available within the Microsoft C runtime, | |
47 | - * or the user has explicitly overridden accessibility of any such | |
48 | - * Microsoft implementation. | |
41 | + /* Internal implementation of the wcrtomb() function; this is | |
42 | + * expanded inline, within the public implementation. | |
49 | 43 | */ |
50 | 44 | if( *ps != (mbstate_t)(0) ) |
51 | 45 | { |
@@ -114,65 +108,24 @@ static __mb_inline__ size_t __wcrtomb_fallback | ||
114 | 108 | return __mingw_wctomb_convert( mb, __mingw_wctomb_cur_max(), &wc, 1 ); |
115 | 109 | } |
116 | 110 | |
117 | -static size_t __mingw_wcrtomb_fallback | |
118 | -( char *restrict mb, wchar_t wc, mbstate_t *ps ) | |
119 | -{ | |
120 | - /* A thin wrapper around the preceding fallback implementation, | |
121 | - * (which is expanded in-line); this serves as the sole interface | |
122 | - * between either of the two following public API entry points, and | |
123 | - * the fallback implementation, ensuring that a private mbstate_t | |
124 | - * reference is provided, if the caller doesn't supply its own. | |
125 | - */ | |
126 | - return __wcrtomb_fallback( mb, wc, __mbrtowc_state( ps ) ); | |
127 | -} | |
128 | - | |
129 | -size_t __mingw_wcrtomb | |
130 | -( char *restrict mb, wchar_t wc, mbstate_t *restrict ps ) | |
111 | +size_t wcrtomb( char *restrict mb, wchar_t wc, mbstate_t *restrict ps ) | |
131 | 112 | { |
132 | - /* Wrapper for the wcrtomb() function; this will unconditionally | |
133 | - * delegate the call to the MinGW fallback implementation, (defined | |
134 | - * above), irrespective of availability of any Microsoft-provided | |
135 | - * implementation. | |
113 | + /* Implementation of ISO-C99 wcrtomb() function, in libmingwex.a; | |
114 | + * after storing the effective codeset properties, this returns the | |
115 | + * result from expansion of the preceding inline implementation. | |
136 | 116 | */ |
137 | 117 | (void)(__mingw_wctomb_cur_max_init( __mingw_wctomb_codeset_init() )); |
138 | - return __mingw_wcrtomb_fallback( mb, wc, ps ); | |
118 | + return __wcrtomb_internal( mb, wc, __mbrtowc_state( ps ) ); | |
139 | 119 | } |
140 | 120 | |
141 | -size_t __msvcrt_wcrtomb( char *restrict mb, wchar_t wc, mbstate_t *restrict ps ) | |
142 | -{ | |
143 | - /* Wrapper for the wcrtomb() function; this will initially attempt | |
144 | - * to delegate the call to a Microsoft-provided implementation, but | |
145 | - * if no such implementation can be found, fall back to the MinGW | |
146 | - * substitute (defined above). | |
147 | - */ | |
148 | - typedef size_t (*redirect_t)( char *restrict, wchar_t, mbstate_t *restrict ); | |
149 | - static redirect_t redirector_hook = NULL; | |
150 | - | |
151 | - /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with | |
152 | - * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus, | |
153 | - * Microsoft's wcrtomb() is likely to be similarly unreliable, so | |
154 | - * always use the MinGW fallback with such code pages. | |
155 | - */ | |
156 | - if( (__mingw_wctomb_cur_max_init( __mingw_wctomb_codeset_init() )) > 2 ) | |
157 | - return __mingw_wcrtomb_fallback( mb, wc, ps ); | |
158 | - | |
159 | - /* On first time call, we don't know which implementation is to be | |
160 | - * selected; look for a Microsoft implementation, which, if available, | |
161 | - * may be registered for immediate use on this, and any subsequent, | |
162 | - * calls to this function wrapper... | |
163 | - */ | |
164 | - if( (redirector_hook == NULL) | |
165 | - && ((redirector_hook = dlsym( RTLD_DEFAULT, "wcrtomb" )) == NULL) ) | |
166 | - | |
167 | - /* ...but when no Microsoft implementation can be found, register | |
168 | - * the MinGW fall back in its stead. | |
169 | - */ | |
170 | - redirector_hook = __mingw_wcrtomb_fallback; | |
121 | +/* FIXME: these aliases are provided for link-compatibitity with | |
122 | + * libraries compiled against mingwrt-5.3.x; they may be removed | |
123 | + * from future versions of mingwrt. | |
124 | + */ | |
125 | +size_t __msvcrt_wcrtomb( char *restrict, wchar_t, mbstate_t *restrict ) | |
126 | +__attribute__((__weak__,__alias__("wcrtomb"))); | |
171 | 127 | |
172 | - /* Finally, delegate the call to whichever implementation has been | |
173 | - * registered on first-time call. | |
174 | - */ | |
175 | - return redirector_hook( mb, wc, ps ); | |
176 | -} | |
128 | +size_t __mingw_wcrtomb( char *restrict, wchar_t, mbstate_t *restrict ) | |
129 | +__attribute__((__weak__,__alias__("wcrtomb"))); | |
177 | 130 | |
178 | 131 | /* $RCSfile$: end of file */ |
@@ -1,9 +1,10 @@ | ||
1 | 1 | /* |
2 | 2 | * wcsrtombs.c |
3 | 3 | * |
4 | - * MinGW.org replacement for the wcsrtombs() function; delegates to the | |
5 | - * Microsoft implementation, if available in the C runtime DLL, otherwise | |
6 | - * handles the call locally. | |
4 | + * MinGW.org implementation of the wcsrtombs() function; supports use of | |
5 | + * this function on any legacy Windows version, for which Microsoft do not | |
6 | + * provide it, and replaces the Microsoft implementation, when they do. | |
7 | + * | |
7 | 8 | * |
8 | 9 | * $Id$ |
9 | 10 | * |
@@ -33,19 +34,12 @@ | ||
33 | 34 | */ |
34 | 35 | #include "wcharmap.h" |
35 | 36 | |
36 | -/* For runtime delegation, we need a mechanism for detection of an | |
37 | - * implementation, within the default C runtime DLL; we may use the | |
38 | - * MinGW dlfcn emulation, to facilitate this. | |
39 | - */ | |
40 | -#include <dlfcn.h> | |
41 | - | |
42 | -static size_t __mingw_wcsrtombs_fallback | |
37 | +static __mb_inline__ size_t __mingw_wcsrtombs_internal | |
43 | 38 | ( char *restrict mbs, const wchar_t **restrict wcs, size_t len, |
44 | 39 | mbstate_t *restrict ps |
45 | 40 | ) |
46 | -{ /* Fallback function, providing an implementation of the wcsrtombs() | |
47 | - * function, when none is available within the Microsoft C runtime, or | |
48 | - * the user has elected to override any such Microsoft implementation. | |
41 | +{ /* Internal implementation of the wcsrtombs() function; this will be | |
42 | + * expanded inline, within the body of the public implementation. | |
49 | 43 | * |
50 | 44 | * Initially, save the current errno state, so that we may restore |
51 | 45 | * it on return, clear it to zero for internal checking, and compute |
@@ -144,63 +138,30 @@ static size_t __mingw_wcsrtombs_fallback | ||
144 | 138 | return errout( errno_reset, count ); |
145 | 139 | } |
146 | 140 | |
147 | -size_t __mingw_wcsrtombs | |
148 | -( char *mbs, const wchar_t **wcs, size_t len, mbstate_t *ps ) | |
141 | +size_t wcsrtombs( char *mbs, const wchar_t **wcs, size_t len, mbstate_t *ps ) | |
149 | 142 | { |
150 | - /* Wrapper for the wcsrtombs() function; this will unconditionally | |
151 | - * delegate the call to the MinGW fallback implementation, (defined | |
152 | - * above), after first ensuring that the specified wcs reference is | |
153 | - * valid, and that the effective codeset has been initialized. | |
143 | + /* Implementation of ISO-C99 wcsrtombs() function, in libmingwex.a; | |
144 | + * before proceeding, we must ensure that the wcs argument specifies | |
145 | + * an indirect reference to a non-NULL wchar_t array. | |
154 | 146 | */ |
155 | 147 | if( (wcs == NULL) || (*wcs == NULL) ) return errout( EINVAL, (size_t)(-1) ); |
156 | 148 | |
149 | + /* With a valid wcs reference, store the effective codeset, and | |
150 | + * hand the conversion off to the inline expansion of the preceding | |
151 | + * implementation. | |
152 | + */ | |
157 | 153 | (void)(__mingw_wctomb_codeset_init() ); |
158 | - return __mingw_wcsrtombs_fallback( mbs, wcs, len, ps ); | |
154 | + return __mingw_wcsrtombs_internal( mbs, wcs, len, ps ); | |
159 | 155 | } |
160 | 156 | |
161 | -size_t __msvcrt_wcsrtombs | |
162 | -( char *mbs, const wchar_t **wcs, size_t len, mbstate_t *ps ) | |
163 | -{ | |
164 | - /* Wrapper for the wcsrtombs() function; it will initially attempt | |
165 | - * to delegate the call to a Microsoft-provided implementation, but | |
166 | - * if no such implementation can be found, fall back to the MinGW | |
167 | - * substitute (defined above). | |
168 | - */ | |
169 | - typedef size_t (*redirect_t)(char *, const wchar_t **, size_t, mbstate_t *); | |
170 | - static redirect_t redirector_hook = NULL; | |
171 | - | |
172 | - /* Neither wcs, not the pointer to which it refers, may be NULL. | |
173 | - * ISO C doesn't specify any particular outcome for this condition, | |
174 | - * (so a segmentation fault would conform); it makes more sense to | |
175 | - * catch the abnormality, and bail out. | |
176 | - */ | |
177 | - if( (wcs == NULL) || (*wcs == NULL) ) return errout( EINVAL, (size_t)(-1) ); | |
178 | - | |
179 | - /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with | |
180 | - * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus, | |
181 | - * Microsoft's wcsrtombs() is likely to be similarly unreliable, so | |
182 | - * always use the MinGW fallback with such code pages. | |
183 | - */ | |
184 | - if( __mb_cur_max_for_codeset( __mingw_wctomb_codeset_init() ) > 2 ) | |
185 | - return __mingw_wcsrtombs_fallback( mbs, wcs, len, ps ); | |
157 | +/* FIXME: these aliases are provided for link-compatibitity with | |
158 | + * libraries compiled against mingwrt-5.3.x; they may be removed | |
159 | + * from future versions of mingwrt. | |
160 | + */ | |
161 | +size_t __msvcrt_wcsrtombs( char *, const wchar_t **, size_t, mbstate_t * ) | |
162 | +__attribute__((__weak__,__alias__("wcsrtombs"))); | |
186 | 163 | |
187 | - /* On first time call, we don't know which implementation is to be | |
188 | - * selected; look for a Microsoft implementation, which, if available, | |
189 | - * may be registered for immediate use on this, and any subsequent, | |
190 | - * calls to this function wrapper... | |
191 | - */ | |
192 | - if( (redirector_hook == NULL) | |
193 | - && ((redirector_hook = dlsym( RTLD_DEFAULT, "wcsrtombs" )) == NULL) ) | |
194 | - { | |
195 | - /* ...but when no Microsoft implementation can be found, register | |
196 | - * the MinGW fallback in its stead. | |
197 | - */ | |
198 | - redirector_hook = __mingw_wcsrtombs_fallback; | |
199 | - } | |
200 | - /* Finally, delegate the call to whichever implementation has been | |
201 | - * registered on first-time call. | |
202 | - */ | |
203 | - return redirector_hook( mbs, wcs, len, ps ); | |
204 | -} | |
164 | +size_t __mingw_wcsrtombs( char *, const wchar_t **, size_t, mbstate_t * ) | |
165 | +__attribute__((__weak__,__alias__("wcsrtombs"))); | |
205 | 166 | |
206 | 167 | /* $RCSfile$: end of file */ |
@@ -2,9 +2,9 @@ | ||
2 | 2 | * wctob.c |
3 | 3 | * |
4 | 4 | * Implementation of ISO-C99 wctob() function, supporting it on legacy |
5 | - * Windows versions, for which MSVCRT.DLL doesn't provide it, otherwise | |
6 | - * delegating to the Microsoft implementation, except in specific cases | |
7 | - * when that implementation may not support the active MBCS codeset. | |
5 | + * Windows versions, for which MSVCRT.DLL doesn't provide it, and also | |
6 | + * replacing the Microsoft implementation, on Windows versions with an | |
7 | + * MSVCRT.DLL, or MSVCRn.DLL which does. | |
8 | 8 | * |
9 | 9 | * |
10 | 10 | * $Id$ |
@@ -35,69 +35,27 @@ | ||
35 | 35 | */ |
36 | 36 | #include "wcharmap.h" |
37 | 37 | |
38 | -/* For runtime delegation, we need a mechanism for detection of an | |
39 | - * implementation, within the default C runtime DLL; we may use the | |
40 | - * MinGW dlfcn emulation, to facilitate this. | |
41 | - */ | |
42 | -#include <dlfcn.h> | |
43 | 38 | #include <stdio.h> |
44 | 39 | |
45 | -static int __mingw_wctob_fallback( wint_t wc ) | |
46 | -{ /* Fallback function, providing an implementation of the wctob() | |
47 | - * function, when none is available within the Microsoft runtime. | |
48 | - * This performs a wchar_t to MBCS conversion on the given single | |
49 | - * wide character argument, capturing the conversion into a local | |
50 | - * buffer, checks that the result occupies exactly one byte, for | |
51 | - * which the coercion of that byte value to int is returned, or | |
52 | - * otherwise returns EOF. | |
40 | +int wctob( wint_t wc ) | |
41 | +{ /* Implementation of ISO-C99 wctob() function, in libmingwex.a; | |
42 | + * after first storing the effective codeset index, this performs | |
43 | + * a wchar_t to MBCS conversion on the given single wide character | |
44 | + * argument, capturing the conversion into a local buffer, checks | |
45 | + * that the result occupies exactly one byte, for which the byte | |
46 | + * value is coerced to int and returned; otherwise returns EOF. | |
53 | 47 | */ |
48 | + (void)(__mingw_wctomb_codeset_init()); | |
54 | 49 | union { unsigned char u; char c; } retval; |
55 | 50 | return (__mingw_wctomb_convert( &retval.c, 1, &wc, 1 ) == 1) |
56 | 51 | ? (int)(retval.u) : EOF; |
57 | 52 | } |
58 | 53 | |
59 | -int __mingw_wctob( wint_t wc ) | |
60 | -{ /* Wrapper for the wctob() function; this variant will unconditionally | |
61 | - * delegate the call to the MinGW fallback implementation, after first | |
62 | - * storing the effective codeset index. | |
63 | - */ | |
64 | - (void)(__mingw_wctomb_codeset_init()); | |
65 | - return __mingw_wctob_fallback( wc ); | |
66 | -} | |
67 | - | |
68 | -int __msvcrt_wctob( wint_t wc ) | |
69 | -{ /* Wrapper for the wctob() function; it will initially attempt | |
70 | - * to delegate the call to a Microsoft-provided implementation, | |
71 | - * but if no such implementation can be found, fall back to the | |
72 | - * MinGW substitute (defined above). | |
73 | - */ | |
74 | - static int (*redirector_hook)( wchar_t ) = NULL; | |
75 | - | |
76 | - /* MSVCRT.DLL's setlocale() cannot reliably handle code pages with | |
77 | - * more than two bytes per code point, (e.g. UTF-7 and UTF-8); thus, | |
78 | - * Microsoft's wctob() is likely to be similarly unreliable, so we | |
79 | - * always use the MinGW fallback with such code pages. | |
80 | - */ | |
81 | - if( __mingw_wctomb_cur_max_init(__mingw_wctomb_codeset_init()) > 2 ) | |
82 | - return __mingw_wctob_fallback( wc ); | |
83 | - | |
84 | - /* On first time call, we don't know which implementation is to be | |
85 | - * selected; look for a Microsoft implementation, which, if available, | |
86 | - * may be registered for immediate use on this, and any subsequent, | |
87 | - * calls to this function wrapper... | |
88 | - */ | |
89 | - if( (redirector_hook == NULL) | |
90 | - && ((redirector_hook = dlsym( RTLD_DEFAULT, "wctob" )) == NULL) ) | |
91 | - | |
92 | - /* ...but when no Microsoft implementation can be found, register | |
93 | - * the MinGW fall back in its stead. | |
94 | - */ | |
95 | - redirector_hook = __mingw_wctob_fallback; | |
96 | - | |
97 | - /* Finally, delegate the call to whichever implementation has been | |
98 | - * registered on first-time call. | |
99 | - */ | |
100 | - return redirector_hook( wc ); | |
101 | -} | |
54 | +/* FIXME: these aliases are provided for link-compatibitity with | |
55 | + * libraries compiled against mingwrt-5.3.x; they may be removed | |
56 | + * from future versions of mingwrt. | |
57 | + */ | |
58 | +int __msvcrt_wctob( wint_t )__attribute__((__weak__,__alias__("wctob"))); | |
59 | +int __mingw_wctob( wint_t )__attribute__((__weak__,__alias__("wctob"))); | |
102 | 60 | |
103 | 61 | /* $RCSfile$: end of file */ |