- /*
- * thread_multi_locale1.c - Per-thread locale demo
- *
- * Written by Roland Mainz <roland.mainz@nrubsig.org>
- */
- #define _XOPEN_SOURCE 700
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <locale.h>
- #include <errno.h>
- #define CURSED_GLIBC_DOES_NOT_HAVE_PRINTF_L 1
- #if defined(_WIN32) && !defined(LC_GLOBAL_LOCATE)
- #define EMULATE_POSIX_NEWLOCALE_ON_WINDOWS 1
- #define CURSED_GLIBC_DOES_NOT_HAVE_PRINTF_L 1
- #endif /* defined(_WIN32) && !defined(LC_GLOBAL_LOCATE) */
- #if EMULATE_POSIX_NEWLOCALE_ON_WINDOWS
- #include <xlocinfo.h>
- typedef _locale_t locale_t;
- #define LC_ALL_MASK (LC_ALL)
- locale_t newlocale(int mask, const char * locale, locale_t base_not_implemented)
- {
- return _create_locale(mask, locale);
- }
- locale_t uselocale(locale_t newloc)
- {
- locale_t old_locale = _get_current_locale();
- /*
- * uselocale() sets the thread's locale by definition, so
- * unconditionally use thread-local locale
- */
- _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
- #define ElementsInArray(x) (sizeof(x) / sizeof((x)[0]))
- /*
- * sets all categories - right now our poor man's emulation
- * can't do it better
- */
- for(int i=0 ; i < ElementsInArray(newloc->locinfo->lc_category) ; i++) {
- const char *curr_ln = newloc->locinfo->lc_category[1].locale;
- #if 0
- i, curr_ln);
- #endif
- }
- /* return the old locale_t */
- return old_locale;
- }
- void freelocale(locale_t locobj)
- {
- _free_locale(locobj);
- }
- #endif /* EMULATE_POSIX_NEWLOCALE_ON_WINDOWS */
- #ifdef __GLIBC__
- /* { BSD, MacOSX, Illumos, ... } do not need this! */
- #define CURSED_GLIBC_DOES_NOT_HAVE_PRINTF_L
- #endif
- #ifdef CURSED_GLIBC_DOES_NOT_HAVE_PRINTF_L
- #include <stdarg.h>
- #include <errno.h>
- #endif /* CURSED_GLIBC_DOES_NOT_HAVE_PRINTF_L */
- #ifdef CURSED_GLIBC_DOES_NOT_HAVE_PRINTF_L
- /* cursed glibc does not provide |printf_l()| */
- int vprintf_l(locale_t loc, const char *format, va_list ap)
- {
- locale_t prev_loc;
- int ret;
- int saved_errno;
- prev_loc = uselocale(loc);
- saved_errno = errno;
- (void)uselocale(prev_loc);
- errno = saved_errno;
- return ret;
- }
- int printf_l(locale_t loc, const char *format, ...)
- {
- va_list args;
- int res;
- res = vprintf_l(loc, format, args);
- return res;
- }
- #endif /* CURSED_GLIBC_DOES_NOT_HAVE_PRINTF_L */
- int main(int ac, char *av[])
- {
- locale_t my_en_l;
- locale_t my_de_l;
- double x;
- #ifdef EMULATE_POSIX_NEWLOCALE_ON_WINDOWS
- " (emulated)"
- #endif /* EMULATE_POSIX_NEWLOCALE_ON_WINDOWS */
- ".");
- #if EMULATE_POSIX_NEWLOCALE_ON_WINDOWS
- my_en_l = newlocale(LC_ALL_MASK, "C", NULL);
- my_de_l = newlocale(LC_ALL_MASK, "German", NULL);
- #else
- my_en_l = newlocale(LC_ALL_MASK, "en_US.UTF-8", NULL);
- my_de_l = newlocale(LC_ALL_MASK, "de_DE.UTF-8", NULL);
- #endif /* EMULATE_POSIX_NEWLOCALE_ON_WINDOWS */
- if ((my_en_l == (locale_t)0) || (my_de_l == (locale_t)0)) {
- (ptrdiff_t)((char*)my_en_l-0),
- (ptrdiff_t)((char*)my_de_l-0));
- return EXIT_FAILURE;
- }
- #if 0
- my_de_l->locinfo->lconv->decimal_point);
- #endif
- x = 123456.789123456789;
- (void)printf_l(my_en_l, "%8.8f\n", x);
- (void)printf_l(my_de_l, "%8.8f\n", x);
- /*
- * If we use |uselocale()| we must set the current thread
- * locale to something else before freeing the current
- * locale_t object!!
- */
- freelocale(my_de_l);
- freelocale(my_en_l);
- return EXIT_SUCCESS;
- }
thread_locale1.c - Per-thread locale demo
Posted by Anonymous on Tue 16th May 2023 15:58
raw | new post
view followups (newest first): thread_locale1.c - Per-thread locale demo by Anonymous
modification of post by Anonymous (view diff)
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.