Can someone tell me if NetBSD is non-conforming here, or should only the
newlocale(3) man-page be updated?

SUSv5 says for newlocale(3):

        If the base argument is (locale_t)0, a new locale object shall
        be created[...]
        If a completely new locale object is created, the data for all
        sections not requested by category_mask shall be taken from the
        POSIX locale.

and that is what happens on Linux (Debian 13.4.0) and FreeBSD (15.0-RELEASE).
However, the Tribblix 0m39 newlocale(3) says:

        To create a new locale, the argument base should be passed the
        special argument (locale_t)0. This will use a copy of the current
        global locale as a starting point.

So, the base is the _current_ locale, not POSIX, when base == (locale_t)0.
NetBSD has the same behaviour, but, this isn't documented.

Test code follows:

---START---
#ifdef __linux__
#define _GNU_SOURCE
#endif
#include <langinfo.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __FreeBSD__
#include <xlocale.h>
#else
#include <locale.h>
#endif

int
main(void)
{
        locale_t nl;

        /*
         * es_ES -> es_ES
         */

        setlocale(LC_ALL, "es_ES.UTF-8");     /* must have locale files */
        printf("%s\n", localeconv()->decimal_point);       /* , */
        printf("%f\n", strtod("0,987654", NULL));   /* 0,987654 */

        /*
         * C -> es_ES
         */

        /* use LC_NUMERIC_MASK on NetBSD & Tribblix 0m39 */
        nl = newlocale(LC_CTYPE_MASK, "C", (locale_t)0);
        printf("%s\n", nl_langinfo_l(RADIXCHAR, nl)); /* . or , (nbsd, 
tribblix) */
        printf("%f\n", strtod_l("0.987654", NULL, nl));     /* expect: 0,987654 
*/
        freelocale(nl);

        return 0;
}
---END---

-RVP

Reply via email to