OSDN Git Service

Correct a defect in detection of failed btowc() conversions.
[mingw/mingw-org-wsl.git] / mingwrt / mingwex / btowc.c
1 /*
2  * btowc.c
3  *
4  * Implementation of an ISO-C99 conforming btowc() function; note that,
5  * since this considers only one byte for conversion, and a single byte
6  * can never convert to a surrogate pair, this is not susceptible to the
7  * potential wchar_t overflow error, which may occur with functions such
8  * as mbrtowc(), which may need to return surrogate pairs.
9  *
10  * $Id$
11  *
12  * Written by Keith Marshall <keith@users.osdn.me>
13  * Copyright (C) 2020, MinGW.org Project
14  *
15  *
16  * Permission is hereby granted, free of charge, to any person obtaining a
17  * copy of this software and associated documentation files (the "Software"),
18  * to deal in the Software without restriction, including without limitation
19  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20  * and/or sell copies of the Software, and to permit persons to whom the
21  * Software is furnished to do so, subject to the following conditions:
22  *
23  * The above copyright notice, this permission notice, and the following
24  * disclaimer shall be included in all copies or substantial portions of
25  * the Software.
26  *
27  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
30  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
33  * DEALINGS IN THE SOFTWARE.
34  *
35  */
36 #include "wcharmap.h"
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
44 /* We also need <stdio.h>, for EOF.
45  */
46 #include <stdio.h>
47
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
52    * character argument, (expressed as an int), returning WEOF in
53    * the event that conversion fails.
54    */
55   if( c != EOF )
56   { wint_t wc_result;
57     if( __mingw_mbtowc_convert( (char *)(&c), 1, &wc_result, 1) == 1 )
58       return wc_result;
59   }
60   return WEOF;
61 }
62
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 }
107
108 /* $RCSfile$: end of file */