From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-3.7 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 64B291F463 for ; Wed, 18 Dec 2019 08:52:07 +0000 (UTC) Received: from localhost ([::1]:51380 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ihV3u-0007Ib-F7 for normalperson@yhbt.net; Wed, 18 Dec 2019 03:52:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:37144) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ihV3p-0007IM-8W for bug-gnulib@gnu.org; Wed, 18 Dec 2019 03:52:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ihV3n-0001CX-9v for bug-gnulib@gnu.org; Wed, 18 Dec 2019 03:52:01 -0500 Received: from mo6-p00-ob.smtp.rzone.de ([2a01:238:20a:202:5300::5]:24923) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ihV3m-00013c-Of for bug-gnulib@gnu.org; Wed, 18 Dec 2019 03:51:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1576659115; s=strato-dkim-0002; d=clisp.org; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=0IpS3mcli3SAtVZv5fkJtfmi60GNR1RYqzhtp4OvHPc=; b=ETmBsBOO++HymH+KnRKRDukK7XDBsT5x7i6wHpop9p12Y69GarwA3FWzO8bvieoPM2 SDRbcvLFHIh0iWWCS9urwHXBORh2oNvqmO09ik07pSNKe2Fy9b8hHFh6CweY9Yxws3HP LqIyX7VZMYrgxIM42w2AggPqwqnsyb77ZhZVHYeoovc/l0SzmaKg+YuDrp+RzmP2+mzw uD7ucaxZYDDXYfDw+YLAvePs1lrtODhyf5tb4+deEzP+mlh8DTWsztr/8UQzm5vp5D13 KE+mTf8NvdnGYqf/3IuG/WuHOwBKawtInTq2WRRyDsLsb6xbaCvMTCkh5k9UjfFpoO8e 3bUQ== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOH6fzxfs=" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 46.0.7 DYNA|AUTH) with ESMTPSA id t0ad5bvBI8ps47e (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (curve X9_62_prime256v1 with 256 ECDH bits, eq. 3072 bits RSA)) (Client did not present a certificate); Wed, 18 Dec 2019 09:51:54 +0100 (CET) From: Bruno Haible To: Paul Eggert Subject: Re: hard-locale: make multithread-safe Date: Wed, 18 Dec 2019 09:51:50 +0100 Message-ID: <3342152.6eQS3yp3vh@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-166-generic; KDE/5.18.0; x86_64; ; ) In-Reply-To: <09a43701-a998-5c26-ea9e-51c8c3446084@cs.ucla.edu> References: <175192568.e2XXTFFdkW@omega> <09a43701-a998-5c26-ea9e-51c8c3446084@cs.ucla.edu> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart2596323.pavZAmFpx6" Content-Transfer-Encoding: 7Bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a01:238:20a:202:5300::5 X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: bug-gnulib@gnu.org Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" This is a multi-part message in MIME format. --nextPart2596323.pavZAmFpx6 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" > Thanks, this change looks fine to me. Thanks. But before I do the rewrite, let me add a unit test first. It's a bit tricky only on musl libc, NetBSD, and OpenBSD. Other than that, there's a test failure on Android 4.3, where - setlocale (category, NULL) always returns NULL. - hard_locale of the initial locale returns true, but should be false. 2019-12-18 Bruno Haible hard-locale: Add test. * tests/test-hard-locale.c: New file. * tests/locale.c: New file. * modules/hard-locale-tests: New file. --nextPart2596323.pavZAmFpx6 Content-Disposition: attachment; filename="0001-hard-locale-Add-test.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0001-hard-locale-Add-test.patch" >From 2d1b7501b00dce53481b58b3808313f264c720ea Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 18 Dec 2019 09:41:31 +0100 Subject: [PATCH] hard-locale: Add test. * tests/test-hard-locale.c: New file. * tests/locale.c: New file. * modules/hard-locale-tests: New file. --- ChangeLog | 7 +++ modules/hard-locale-tests | 18 ++++++++ tests/locale.c | 81 ++++++++++++++++++++++++++++++++++ tests/test-hard-locale.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+) create mode 100644 modules/hard-locale-tests create mode 100644 tests/locale.c create mode 100644 tests/test-hard-locale.c diff --git a/ChangeLog b/ChangeLog index 7988bec..2fffaf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2019-12-18 Bruno Haible + + hard-locale: Add test. + * tests/test-hard-locale.c: New file. + * tests/locale.c: New file. + * modules/hard-locale-tests: New file. + 2019-12-17 Paul Eggert dfa: do not match invalid UTF-8 diff --git a/modules/hard-locale-tests b/modules/hard-locale-tests new file mode 100644 index 0000000..cdc084e --- /dev/null +++ b/modules/hard-locale-tests @@ -0,0 +1,18 @@ +Files: +tests/test-hard-locale.c +tests/locale.c + +Depends-on: + +configure.ac: +AC_REQUIRE([AC_CANONICAL_HOST]) +case "$host_os" in + *-musl*) AC_DEFINE([MUSL_LIBC], [1], [Define to 1 on musl libc.]) ;; +esac +dnl Distinguish OpenBSD >= 6.2 from OpenBSD < 6.2. +AC_CHECK_FUNCS_ONCE([duplocale]) + +Makefile.am: +TESTS += test-hard-locale +check_PROGRAMS += test-hard-locale +noinst_PROGRAMS += locale diff --git a/tests/locale.c b/tests/locale.c new file mode 100644 index 0000000..ac587ad --- /dev/null +++ b/tests/locale.c @@ -0,0 +1,81 @@ +/* Program that prints the names of the categories of the current locale. + Copyright (C) 2019 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2019. */ + +#include + +#include +#include +#include + +/* Specification: + + Here we implement only the invocation without any command-line options. */ + +static const char * +defaulted_getenv (const char *variable) +{ + const char *value = getenv (variable); + return (value != NULL ? value : ""); +} + +static void +print_category (int category, const char *variable) +{ + const char *value = defaulted_getenv (variable); + if (value[0] != '\0' && defaulted_getenv ("LC_ALL")[0] == '\0') + /* The variable is set in the environment and not overridden by LC_ALL. */ + printf ("%s=%s\n", variable, value); + else + printf ("%s=\"%s\"\n", variable, setlocale (category, NULL)); +} + +int +main () +{ + setlocale (LC_ALL, ""); + + printf ("LANG=%s\n", defaulted_getenv ("LANG")); + print_category (LC_CTYPE, "LC_CTYPE"); + print_category (LC_NUMERIC, "LC_NUMERIC"); + print_category (LC_TIME, "LC_TIME"); + print_category (LC_COLLATE, "LC_COLLATE"); + print_category (LC_MONETARY, "LC_MONETARY"); + print_category (LC_MESSAGES, "LC_MESSAGES"); +#ifdef LC_PAPER + print_category (LC_PAPER, "LC_PAPER"); +#endif +#ifdef LC_NAME + print_category (LC_NAME, "LC_NAME"); +#endif +#ifdef LC_ADDRESS + print_category (LC_ADDRESS, "LC_ADDRESS"); +#endif +#ifdef LC_TELEPHONE + print_category (LC_TELEPHONE, "LC_TELEPHONE"); +#endif +#ifdef LC_MEASUREMENT + print_category (LC_MEASUREMENT, "LC_MEASUREMENT"); +#endif +#ifdef LC_IDENTIFICATION + print_category (LC_IDENTIFICATION, "LC_IDENTIFICATION"); +#endif + + printf ("LC_ALL=%s\n", defaulted_getenv ("LC_ALL")); + + return 0; +} diff --git a/tests/test-hard-locale.c b/tests/test-hard-locale.c new file mode 100644 index 0000000..f83dc27 --- /dev/null +++ b/tests/test-hard-locale.c @@ -0,0 +1,109 @@ +/* Test of determination whether a locale is different from the "C" locale. + Copyright (C) 2019 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2019. */ + +#include + +#include "hard-locale.h" + +#include +#include +#include +#include + +/* True if all locale names are accepted and all locales are trivial. + This is the case e.g. on OpenBSD 3.8. */ +static bool all_trivial; + +static int +test_one (const char *name, int failure_bitmask) +{ + if (setlocale (LC_ALL, name) != NULL) + { + bool expected; + + /* musl libc has special code for the C.UTF-8 locale; other than that, + all locale names are accepted and all locales are trivial. + OpenBSD returns the locale name that was set, but we don't know how it + behaves under the hood. */ +#if defined MUSL_LIBC || defined __OpenBSD__ + expected = true; +#else + expected = !all_trivial; +#endif + if (hard_locale (LC_CTYPE) != expected) + { + if (expected) + fprintf (stderr, "Unexpected: The category LC_CTYPE of the locale '%s' is not equivalent to C or POSIX.\n", + name); + else + fprintf (stderr, "Unexpected: The category LC_CTYPE of the locale '%s' is equivalent to C or POSIX.\n", + name); + return failure_bitmask; + } + + /* On NetBSD 7.0, some locales such as de_DE.ISO8859-1 and de_DE.UTF-8 + have the LC_COLLATE category set to "C". + Similarly, on musl libc, with the C.UTF-8 locale. */ +#if defined __NetBSD__ + expected = false; +#elif defined MUSL_LIBC + expected = strcmp (name, "C.UTF-8") != 0; +#elif defined __OpenBSD__ && HAVE_DUPLOCALE /* OpenBSD >= 6.2 */ + expected = true; +#else + expected = !all_trivial; +#endif + if (hard_locale (LC_COLLATE) != expected) + { + if (expected) + fprintf (stderr, "Unexpected: The category LC_COLLATE of the locale '%s' is not equivalent to C or POSIX.\n", + name); + else + fprintf (stderr, "Unexpected: The category LC_COLLATE of the locale '%s' is equivalent to C or POSIX.\n", + name); + return failure_bitmask; + } + } + return 0; +} + +int +main () +{ + int fail = 0; + + /* The initial locale is the "C" or "POSIX" locale. */ + if (hard_locale (LC_CTYPE) || hard_locale (LC_COLLATE)) + { + fprintf (stderr, "The initial locale should not be hard!\n"); + fail |= 1; + } + + all_trivial = (setlocale (LC_ALL, "foobar") != NULL); + + fail |= test_one ("de", 2); + fail |= test_one ("de_DE", 4); + fail |= test_one ("de_DE.ISO8859-1", 8); + fail |= test_one ("de_DE.iso88591", 8); + fail |= test_one ("de_DE.UTF-8", 16); + fail |= test_one ("de_DE.utf8", 16); + fail |= test_one ("german", 32); + fail |= test_one ("C.UTF-8", 64); + + return fail; +} -- 2.7.4 --nextPart2596323.pavZAmFpx6--