From patchwork Wed Oct 2 10:46:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1991966 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YVja/vvF; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XJWmJ5prqz1xtY for ; Wed, 2 Oct 2024 20:50:08 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9DA953860C34 for ; Wed, 2 Oct 2024 10:50:06 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id AC9E33858424 for ; Wed, 2 Oct 2024 10:49:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AC9E33858424 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AC9E33858424 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727866142; cv=none; b=vmWphaYP4wEbaTP+tCuVpfjKtiUL1MTyy+McjfVQXyVHCs7oWQqlmbDT13kYj93kw4Kk0kMIPOaRhaBGFOvhl5UX/MCpIvWBeJ9dZqS3mWYmsQeTBUknzArjHCu/Bt81YXEyFvEe/nRK8nw+VCZucYgURAFl/8miTN75uQlhyec= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727866142; c=relaxed/simple; bh=f01JT1WapC0Ozcj1DklbArErc6Rwr1ShSq/gUUbv1YU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=La1E1NOf6EPWyYSJk4OCOaHLTcIzni3Nzi1MkGo23EbvpC2lEnzf76TBPLevI2treEcR5v6pfaLQYPoqU8VCviXk4t+YqP6JaYUZudqS85Rm3sJS9Kw87N8oWpc34kc0oIsxPtGum+dA4AzJOyMJ4QCne6Q7icZNnFd8P2uMI1I= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1727866140; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nWYmh1mVf2x+CF3AylG8jf4EJ6Oxf/PQuIXdeB9Xmk4=; b=YVja/vvF7C6tFO04wcAqwNEp1Vv0KHvrCXYUJj0gUtO5DWO8uefCqx0nov9PGJSzG/IXiU Q7oEHnhv0khSfmtkyia3vAbnR5v+H9wdOPf2WPMBlAn6+dfnt82rgrysnoBtlcTX0qswdy OAEfGERnbDKkJ5vJtfQgbXXcDdqu0hU= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-14-QlxNxNF1PpynzWgy3A_zUg-1; Wed, 02 Oct 2024 06:48:57 -0400 X-MC-Unique: QlxNxNF1PpynzWgy3A_zUg-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 253ED19560BC; Wed, 2 Oct 2024 10:48:56 +0000 (UTC) Received: from localhost (unknown [10.42.28.136]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 97D2219560AD; Wed, 2 Oct 2024 10:48:55 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed v2] libstdc++: Populate std::time_get::get's %c format for C locale Date: Wed, 2 Oct 2024 11:46:40 +0100 Message-ID: <20241002104854.3169663-1-jwakely@redhat.com> In-Reply-To: <20240926135607.2009101-1-jwakely@redhat.com> References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org The v1 patch included fixes to a new file for the POSIX-2008 locale, config/locale/ieee_1003.1-2008/time_members.cc, but I haven't actually pushed the POSIX-2008 locale to trunk yet. So this v2 patch removes the changes to that file, and if/when I push the POSIX-2008 work this fix will be in there from day one. Tested x86_64-linux. Pushed to trunk. This should be backported too. -- >8 -- We were using the empty string "" for D_T_FMT and ERA_D_T_FMT in the C locale, instead of "%a %b %e %T %Y" as the C standard requires. Set it correctly for each locale implementation that defines time_members.cc. We can also explicitly set the _M_era_xxx pointers to the same values as the corresponding _M_xxx ones, rather than setting them to point to identical string literals. This doesn't rely on the compiler merging string literals, and makes it more explicit that they're the same in the C locale. libstdc++-v3/ChangeLog: * config/locale/dragonfly/time_members.cc (__timepunct::_M_initialize_timepunc) (__timepunct::_M_initialize_timepunc): Set _M_date_time_format for C locale. Set %Ex formats to the same values as the %x formats. * config/locale/generic/time_members.cc: Likewise. * config/locale/gnu/time_members.cc: Likewise. * testsuite/22_locale/time_get/get/char/5.cc: New test. * testsuite/22_locale/time_get/get/wchar_t/5.cc: New test. --- .../config/locale/dragonfly/time_members.cc | 16 ++++---- .../config/locale/generic/time_members.cc | 8 ++-- .../config/locale/gnu/time_members.cc | 16 ++++---- .../22_locale/time_get/get/char/5.cc | 37 +++++++++++++++++++ .../22_locale/time_get/get/wchar_t/5.cc | 37 +++++++++++++++++++ 5 files changed, 94 insertions(+), 20 deletions(-) create mode 100644 libstdc++-v3/testsuite/22_locale/time_get/get/char/5.cc create mode 100644 libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/5.cc diff --git a/libstdc++-v3/config/locale/dragonfly/time_members.cc b/libstdc++-v3/config/locale/dragonfly/time_members.cc index 0c96928135e..069b2ddd26b 100644 --- a/libstdc++-v3/config/locale/dragonfly/time_members.cc +++ b/libstdc++-v3/config/locale/dragonfly/time_members.cc @@ -67,11 +67,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_c_locale_timepunct = _S_get_c_locale(); _M_data->_M_date_format = "%m/%d/%y"; - _M_data->_M_date_era_format = "%m/%d/%y"; + _M_data->_M_date_era_format = _M_data->_M_date_format; _M_data->_M_time_format = "%H:%M:%S"; - _M_data->_M_time_era_format = "%H:%M:%S"; - _M_data->_M_date_time_format = ""; - _M_data->_M_date_time_era_format = ""; + _M_data->_M_time_era_format = _M_data->_M_time_format; + _M_data->_M_date_time_format = "%a %b %e %T %Y"; + _M_data->_M_date_time_era_format = _M_data->_M_date_time_format; _M_data->_M_am = "AM"; _M_data->_M_pm = "PM"; _M_data->_M_am_pm_format = "%I:%M:%S %p"; @@ -224,11 +224,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_c_locale_timepunct = _S_get_c_locale(); _M_data->_M_date_format = L"%m/%d/%y"; - _M_data->_M_date_era_format = L"%m/%d/%y"; + _M_data->_M_date_era_format = _M_data->_M_date_format; _M_data->_M_time_format = L"%H:%M:%S"; - _M_data->_M_time_era_format = L"%H:%M:%S"; - _M_data->_M_date_time_format = L""; - _M_data->_M_date_time_era_format = L""; + _M_data->_M_time_era_format = _M_data->_M_time_format; + _M_data->_M_date_time_format = L"%a %b %e %T %Y"; + _M_data->_M_date_time_era_format = _M_data->_M_date_time_format; _M_data->_M_am = L"AM"; _M_data->_M_pm = L"PM"; _M_data->_M_am_pm_format = L"%I:%M:%S %p"; diff --git a/libstdc++-v3/config/locale/generic/time_members.cc b/libstdc++-v3/config/locale/generic/time_members.cc index 68395820fef..6619f0ca881 100644 --- a/libstdc++-v3/config/locale/generic/time_members.cc +++ b/libstdc++-v3/config/locale/generic/time_members.cc @@ -65,11 +65,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_data = new __timepunct_cache; _M_data->_M_date_format = "%m/%d/%y"; - _M_data->_M_date_era_format = "%m/%d/%y"; + _M_data->_M_date_era_format = _M_data->_M_date_format; _M_data->_M_time_format = "%H:%M:%S"; - _M_data->_M_time_era_format = "%H:%M:%S"; - _M_data->_M_date_time_format = ""; - _M_data->_M_date_time_era_format = ""; + _M_data->_M_time_era_format = _M_data->_M_time_format; + _M_data->_M_date_time_format = "%a %b %e %T %Y"; + _M_data->_M_date_time_era_format = _M_data->_M_date_time_format; _M_data->_M_am = "AM"; _M_data->_M_pm = "PM"; _M_data->_M_am_pm_format = "%I:%M:%S %p"; diff --git a/libstdc++-v3/config/locale/gnu/time_members.cc b/libstdc++-v3/config/locale/gnu/time_members.cc index 1e3b87488fa..88c8ab70080 100644 --- a/libstdc++-v3/config/locale/gnu/time_members.cc +++ b/libstdc++-v3/config/locale/gnu/time_members.cc @@ -73,11 +73,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_c_locale_timepunct = _S_get_c_locale(); _M_data->_M_date_format = "%m/%d/%y"; - _M_data->_M_date_era_format = "%m/%d/%y"; + _M_data->_M_date_era_format = _M_data->_M_date_format; _M_data->_M_time_format = "%H:%M:%S"; - _M_data->_M_time_era_format = "%H:%M:%S"; - _M_data->_M_date_time_format = ""; - _M_data->_M_date_time_era_format = ""; + _M_data->_M_time_era_format = _M_data->_M_time_format; + _M_data->_M_date_time_format = "%a %b %e %T %Y"; + _M_data->_M_date_time_era_format = _M_data->_M_date_time_format; _M_data->_M_am = "AM"; _M_data->_M_pm = "PM"; _M_data->_M_am_pm_format = "%I:%M:%S %p"; @@ -229,11 +229,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_c_locale_timepunct = _S_get_c_locale(); _M_data->_M_date_format = L"%m/%d/%y"; - _M_data->_M_date_era_format = L"%m/%d/%y"; + _M_data->_M_date_era_format = _M_data->_M_date_format; _M_data->_M_time_format = L"%H:%M:%S"; - _M_data->_M_time_era_format = L"%H:%M:%S"; - _M_data->_M_date_time_format = L""; - _M_data->_M_date_time_era_format = L""; + _M_data->_M_time_era_format = _M_data->_M_time_format; + _M_data->_M_date_time_format = L"%a %b %e %T %Y"; + _M_data->_M_date_time_era_format = _M_data->_M_date_time_format; _M_data->_M_am = L"AM"; _M_data->_M_pm = L"PM"; _M_data->_M_am_pm_format = L"%I:%M:%S %p"; diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/char/5.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/char/5.cc new file mode 100644 index 00000000000..61fc329cf3c --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get/char/5.cc @@ -0,0 +1,37 @@ +// { dg-do run { target c++11} } + +#include +#include +#include + +int main() +{ + using Facet = std::time_get; + const Facet& fac = std::use_facet(std::locale::classic()); + std::istringstream ss("Fri Jul 5 14:58:21 2019"); + std::ios::iostate err = std::ios::goodbit; + std::tm tm = {}; + fac.get(ss, Facet::iter_type(), ss, err, &tm, 'c'); + VERIFY( err == std::ios::eofbit ); + VERIFY( tm.tm_year == 119 ); + VERIFY( tm.tm_mon == 6 ); + VERIFY( tm.tm_mday == 5 ); + VERIFY( tm.tm_wday == 5 ); + VERIFY( tm.tm_hour == 14 ); + VERIFY( tm.tm_min == 58 ); + VERIFY( tm.tm_sec == 21 ); + ss.clear(); + ss.seekg(0); + ss.str(ss.str() + " non-whitespace after the datetime"); + err = std::ios::goodbit; + tm = std::tm(); + fac.get(ss, Facet::iter_type(), ss, err, &tm, 'c', 'E'); + VERIFY( err == std::ios::goodbit ); + VERIFY( tm.tm_year == 119 ); + VERIFY( tm.tm_mon == 6 ); + VERIFY( tm.tm_mday == 5 ); + VERIFY( tm.tm_wday == 5 ); + VERIFY( tm.tm_hour == 14 ); + VERIFY( tm.tm_min == 58 ); + VERIFY( tm.tm_sec == 21 ); +} diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/5.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/5.cc new file mode 100644 index 00000000000..5f350b043d9 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/5.cc @@ -0,0 +1,37 @@ +// { dg-do run { target c++11} } + +#include +#include +#include + +int main() +{ + using Facet = std::time_get; + const Facet& fac = std::use_facet(std::locale::classic()); + std::wistringstream ss(L"Fri Jul 5 14:58:21 2019"); + std::ios::iostate err = std::ios::goodbit; + std::tm tm = {}; + fac.get(ss, Facet::iter_type(), ss, err, &tm, 'c'); + VERIFY( err == std::ios::eofbit ); + VERIFY( tm.tm_year == 119 ); + VERIFY( tm.tm_mon == 6 ); + VERIFY( tm.tm_mday == 5 ); + VERIFY( tm.tm_wday == 5 ); + VERIFY( tm.tm_hour == 14 ); + VERIFY( tm.tm_min == 58 ); + VERIFY( tm.tm_sec == 21 ); + ss.clear(); + ss.seekg(0); + ss.str(ss.str() + L" non-whitespace after the datetime"); + err = std::ios::goodbit; + tm = std::tm(); + fac.get(ss, Facet::iter_type(), ss, err, &tm, 'c', 'E'); + VERIFY( err == std::ios::goodbit ); + VERIFY( tm.tm_year == 119 ); + VERIFY( tm.tm_mon == 6 ); + VERIFY( tm.tm_mday == 5 ); + VERIFY( tm.tm_wday == 5 ); + VERIFY( tm.tm_hour == 14 ); + VERIFY( tm.tm_min == 58 ); + VERIFY( tm.tm_sec == 21 ); +}