nl_langinfo: Add NL_LOCALE_NAME macro

Provide an extension NL_LOCALE_NAME() macro, with semantics
matching glibc, which can be used as:
  nl_langinfo_l(NL_LOCALE_NAME(LC_MESSAGES), locale);
to get back the locale string that locale was originally
created with during newlocale(). This in turn allows a library
(such as gettext) to determine what thread-local locale settings
it has inherited from the main program without having to be told
what parameters were passed to newlocale(), for less overall
coupling between parts of the program.

gnulib is set up to use the extension:
https://lists.gnu.org/archive/html/bug-gnulib/2017-01/msg00129.html

* libc/include/langinfo.h (NL_LOCALE_NAME): New macro
* libc/locale/nl_langinfo.c (nl_langinfo_l): Expose locale names
of a locale_t's category components.

Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Eric Blake 2017-01-19 20:45:16 -06:00 committed by Corinna Vinschen
parent ef00718487
commit ca3e3bc54e
2 changed files with 18 additions and 1 deletions

View File

@ -304,7 +304,7 @@ enum __nl_item
_NL_COLLATE_CODESET,
/* This MUST be the last entry since it's used to check for an array
index in nl_langinfo(). */
index in nl_langinfo(). It also must not exceed _NL_LOCALE_NAME_BASE. */
_NL_LOCALE_EXTENDED_LAST_ENTRY
#endif /* __HAVE_LOCALE_INFO_EXTENDED__ */
@ -312,6 +312,14 @@ enum __nl_item
};
/* As an extension, nl_langinfo can retrive the name of a locale
category, with this mapping from setlocale() category (other than
LC_ALL) to nl_item. */
#define _NL_LOCALE_NAME_BASE 100000
#if __GNU_VISIBLE
#define NL_LOCALE_NAME(category) (_NL_LOCALE_NAME_BASE + (category))
#endif
__BEGIN_DECLS
char *nl_langinfo (nl_item);
#if __POSIX_VISIBLE >= 200809

View File

@ -24,6 +24,8 @@
* SUCH DAMAGE.
*/
#define _GNU_SOURCE
#include <sys/cdefs.h>
#include <locale.h>
@ -368,6 +370,13 @@ do_codeset:
break;
#endif
default:
/* Relies on the fact that LC_ALL is 0, and all other
LC_ constants are in ascending order. */
if (item > NL_LOCALE_NAME(LC_ALL)
&& item < NL_LOCALE_NAME(_LC_LAST)) {
return locale->categories[item
- NL_LOCALE_NAME(LC_ALL)];
}
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
if (item > _NL_LOCALE_EXTENDED_FIRST_ENTRY
&& item < _NL_LOCALE_EXTENDED_LAST_ENTRY) {