add _NL_LOCALE_NAME extension to nl_langinfo
authorRich Felker <dalias@aerifal.cx>
Tue, 1 Aug 2017 03:08:27 +0000 (23:08 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 1 Aug 2017 03:08:27 +0000 (23:08 -0400)
since setlocale(cat, NULL) is required to return the setting for the
global locale, there is no standard mechanism to obtain the name of
the currently active thread-local locale set by uselocale. this makes
it impossible for application/library software to load appropriate
translations, etc. unless using the gettext implementation provided by
libc, which has privileged access to libc internals.

to fill this gap, glibc introduced the _NL_LOCALE_NAME macro which can
be used with nl_langinfo to obtain the name. GNU gettext/gnulib code
already use this functionality on glibc, and can easily be adapted to
make use of it on non-glibc systems if it's available; for other
systems they poke at locale implementation internals, which we want to
avoid. this patch provides a compatible interface to the one glibc
introduced.

include/langinfo.h
src/locale/langinfo.c

index 2153c42..519c061 100644 (file)
@@ -77,6 +77,12 @@ extern "C" {
 #define YESEXPR 0x50000
 #define NOEXPR 0x50001
 
+#define _NL_LOCALE_NAME(cat) (((cat)<<16) | 0xffff)
+
+#if defined(_GNU_SOURCE)
+#define NL_LOCALE_NAME(cat) _NL_LOCALE_NAME(cat)
+#endif
+
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define YESSTR 0x50002
 #define NOSTR 0x50003
index b2c8569..b16caf4 100644 (file)
@@ -34,6 +34,10 @@ char *__nl_langinfo_l(nl_item item, locale_t loc)
        const char *str;
 
        if (item == CODESET) return MB_CUR_MAX==1 ? "ASCII" : "UTF-8";
+
+       /* _NL_LOCALE_NAME extension */
+       if (idx == 65535 && cat < LC_ALL)
+               return loc->cat[cat] ? (char *)loc->cat[cat]->name : "C";
        
        switch (cat) {
        case LC_NUMERIC: