Home | History | Annotate | Download | only in win32
      1 // -*- C++ -*-
      2 //===-------------------- support/win32/locale_win32.cpp ------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #include <locale>
     12 #include <cstdarg> // va_start, va_end
     13 #include <memory>
     14 #include <type_traits>
     15 
     16 #include <crtversion.h>
     17 
     18 typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
     19 typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
     20 
     21 // FIXME: base currently unused. Needs manual work to construct the new locale
     22 locale_t newlocale( int mask, const char * locale, locale_t /*base*/ )
     23 {
     24     return _create_locale( mask, locale );
     25 }
     26 locale_t uselocale( locale_t newloc )
     27 {
     28     locale_t old_locale = _get_current_locale();
     29     if ( newloc == NULL )
     30         return old_locale;
     31     // uselocale sets the thread's locale by definition, so unconditionally use thread-local locale
     32     _configthreadlocale( _ENABLE_PER_THREAD_LOCALE );
     33     // uselocale sets all categories
     34 #if _VC_CRT_MAJOR_VERSION < 14
     35     setlocale( LC_ALL, newloc->locinfo->lc_category[LC_ALL].locale );
     36 #endif
     37     // uselocale returns the old locale_t
     38     return old_locale;
     39 }
     40 lconv *localeconv_l( locale_t loc )
     41 {
     42     __locale_raii __current( uselocale(loc), uselocale );
     43     return localeconv();
     44 }
     45 size_t mbrlen_l( const char *__restrict s, size_t n,
     46                  mbstate_t *__restrict ps, locale_t loc )
     47 {
     48     __locale_raii __current( uselocale(loc), uselocale );
     49     return mbrlen( s, n, ps );
     50 }
     51 size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
     52                     size_t len, mbstate_t *__restrict ps, locale_t loc )
     53 {
     54     __locale_raii __current( uselocale(loc), uselocale );
     55     return mbsrtowcs( dst, src, len, ps );
     56 }
     57 size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,
     58                   locale_t loc )
     59 {
     60     __locale_raii __current( uselocale(loc), uselocale );
     61     return wcrtomb( s, wc, ps );
     62 }
     63 size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,
     64                   size_t n, mbstate_t *__restrict ps, locale_t loc )
     65 {
     66     __locale_raii __current( uselocale(loc), uselocale );
     67     return mbrtowc( pwc, s, n, ps );
     68 }
     69 size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
     70                      size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc )
     71 {
     72     __locale_raii __current( uselocale(loc), uselocale );
     73     return mbsnrtowcs( dst, src, nms, len, ps );
     74 }
     75 size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,
     76                      size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc )
     77 {
     78     __locale_raii __current( uselocale(loc), uselocale );
     79     return wcsnrtombs( dst, src, nwc, len, ps );
     80 }
     81 wint_t btowc_l( int c, locale_t loc )
     82 {
     83     __locale_raii __current( uselocale(loc), uselocale );
     84     return btowc( c );
     85 }
     86 int wctob_l( wint_t c, locale_t loc )
     87 {
     88     __locale_raii __current( uselocale(loc), uselocale );
     89     return wctob( c );
     90 }
     91 
     92 int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...)
     93 {
     94     __locale_raii __current( uselocale(loc), uselocale );
     95     va_list ap;
     96     va_start( ap, format );
     97     int result = vsnprintf( ret, n, format, ap );
     98     va_end(ap);
     99     return result;
    100 }
    101 
    102 int asprintf_l( char **ret, locale_t loc, const char *format, ... )
    103 {
    104     va_list ap;
    105     va_start( ap, format );
    106     int result = vasprintf_l( ret, loc, format, ap );
    107     va_end(ap);
    108     return result;
    109 }
    110 int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap )
    111 {
    112     __locale_raii __current( uselocale(loc), uselocale );
    113     return vasprintf( ret, format, ap );
    114 }
    115