diff --git a/newlib/libc/include/langinfo.h b/newlib/libc/include/langinfo.h index 0fbb2a8d9..193cce348 100644 --- a/newlib/libc/include/langinfo.h +++ b/newlib/libc/include/langinfo.h @@ -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 diff --git a/newlib/libc/locale/nl_langinfo.c b/newlib/libc/locale/nl_langinfo.c index 6d078b978..eb984912f 100644 --- a/newlib/libc/locale/nl_langinfo.c +++ b/newlib/libc/locale/nl_langinfo.c @@ -24,6 +24,8 @@ * SUCH DAMAGE. */ +#define _GNU_SOURCE + #include #include @@ -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) {