From patchwork Tue May 9 19:53:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1779117 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=DjMfy9Fr; dkim-atps=neutral Received: from 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 (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QG84Q0YjLz214S for ; Wed, 10 May 2023 05:54:12 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 434763857348 for ; Tue, 9 May 2023 19:54:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 434763857348 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1683662050; bh=zhM/VxZ1zMO40pkzBSB6eIMBJSHeJsOdmP1aW7RpEac=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=DjMfy9FrP1MfnVvle7guSLjYzhwfD/EoJFlQ4Zl2QAHHUjvcvUTkGcsFskUOr00RE 5+bRZaMtVfNu+fUlcLWBdRwwnhcRwvmrNo3tt5RmrG2TOBtdnQvE3yNbMQleqKH1UV wW6DdZHJiGdjapQ4ATupjfyf7kTdx8AenCs22V/k= 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 ESMTPS id 04C3B3858414 for ; Tue, 9 May 2023 19:53:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 04C3B3858414 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-282-W8bs7JeeOR-dhApBn5s36g-1; Tue, 09 May 2023 15:53:46 -0400 X-MC-Unique: W8bs7JeeOR-dhApBn5s36g-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4603A2823806; Tue, 9 May 2023 19:53:46 +0000 (UTC) Received: from localhost (unknown [10.42.28.7]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0CBC514171BC; Tue, 9 May 2023 19:53:45 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Fix pretty printers and add tests Date: Tue, 9 May 2023 20:53:45 +0100 Message-Id: <20230509195345.561522-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jonathan Wakely via Gcc-patches From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Tested powerpc64le-linux. Pushed to trunk. I'll backport to gcc-13 too. -- >8-- This fixes a couple of errors in the printers for chrono types, and adds tests to ensure they keep working. libstdc++-v3/ChangeLog: * python/libstdcxx/v6/printers.py (StdChronoDurationPrinter): Print floating-point durations correctly. (StdChronoTimePointPrinter): Support printing only the value, not the type name. Uncomment handling for known clocks. (StdChronoZonedTimePrinter): Remove type names from output. (StdChronoCalendarPrinter): Fix hh_mm_ss member access. (StdChronoTimeZonePrinter): Add equals sign to output. * testsuite/libstdc++-prettyprinters/chrono.cc: New test. --- libstdc++-v3/python/libstdcxx/v6/printers.py | 44 ++++++---- .../libstdc++-prettyprinters/chrono.cc | 87 +++++++++++++++++++ 2 files changed, 113 insertions(+), 18 deletions(-) create mode 100644 libstdc++-v3/testsuite/libstdc++-prettyprinters/chrono.cc diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 2c50e60eae7..b4c427d487c 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -1863,8 +1863,8 @@ class StdAtomicPrinter: class StdFormatArgsPrinter: "Print a std::basic_format_args" - # TODO: add printer for basic_format_arg and print out children - # TODO: add printer for basic_format_args::_Store + # TODO: add printer for basic_format_arg and print out children. + # TODO: add printer for __format::_ArgStore. def __init__(self, typename, val): self.typename = strip_versioned_namespace(typename) @@ -1930,7 +1930,10 @@ class StdChronoDurationPrinter: return "[{}/{}]s".format(num, den) def to_string(self): - return "std::chrono::duration = { %d%s }" % (self.val['__r'], self._suffix()) + r = self.val['__r'] + if r.type.strip_typedefs().code == gdb.TYPE_CODE_FLT: + r = "%g" % r + return "std::chrono::duration = {{ {}{} }}".format(r, self._suffix()) class StdChronoTimePointPrinter: @@ -1947,19 +1950,19 @@ class StdChronoTimePointPrinter: or name == 'std::chrono::system_clock': return ('std::chrono::sys_time', 0) # XXX need to remove leap seconds from utc, gps, and tai - #if name == 'std::chrono::utc_clock': - # return ('std::chrono::utc_time', 0) - #if name == 'std::chrono::gps_clock': - # return ('std::chrono::gps_clock time_point', 315964809) - #if name == 'std::chrono::tai_clock': - # return ('std::chrono::tai_clock time_point', -378691210) + if name == 'std::chrono::utc_clock': + return ('std::chrono::utc_time', None) # XXX + if name == 'std::chrono::gps_clock': + return ('std::chrono::gps_time', None) # XXX 315964809 + if name == 'std::chrono::tai_clock': + return ('std::chrono::tai_time', None) # XXX -378691210 if name == 'std::filesystem::__file_clock': return ('std::chrono::file_time', 6437664000) if name == 'std::chrono::local_t': return ('std::chrono::local_time', 0) return ('{} time_point'.format(name), None) - def to_string(self): + def to_string(self, abbrev = False): clock, offset = self._clock() d = self.val['__d'] r = d['__r'] @@ -1970,11 +1973,14 @@ class StdChronoTimePointPrinter: num, den = printer._ratio() secs = (r * num / den) + offset try: - dt = datetime.fromtimestamp(secs, _utc_timezone) + dt = datetime.datetime.fromtimestamp(secs, _utc_timezone) time = ' [{:%Y-%m-%d %H:%M:%S}]'.format(dt) except: pass - return '%s = {%d%s%s}' % (clock, r, suffix, time) + s = '%d%s%s' % (r, suffix, time) + if abbrev: + return s + return '%s = { %s }' % (clock, s) class StdChronoZonedTimePrinter: "Print a std::chrono::zoned_time" @@ -1984,9 +1990,11 @@ class StdChronoZonedTimePrinter: self.val = val def to_string(self): - zone = self.val['_M_zone'].dereference() + zone = self.val['_M_zone'].dereference()['_M_name'] time = self.val['_M_tp'] - return 'std::chrono::zoned_time = {{{} {}}}'.format(zone, time) + printer = StdChronoTimePointPrinter(time.type.name, time) + time = printer.to_string(True) + return 'std::chrono::zoned_time = {{ {} {} }}'.format(zone, time) months = [None, 'January', 'February', 'March', 'April', 'May', 'June', @@ -2037,13 +2045,13 @@ class StdChronoCalendarPrinter: if typ == 'std::chrono::year_month_day_last': return '{}/{}'.format(y, val['_M_mdl']) if typ == 'std::chrono::year_month_weekday': - return '{}/{}'.format(y, m, val['_M_wdi']) + return '{}/{}/{}'.format(y, m, val['_M_wdi']) if typ == 'std::chrono::year_month_weekday_last': - return '{}/{}'.format(y, m, val['_M_wdl']) + return '{}/{}/{}'.format(y, m, val['_M_wdl']) if typ.startswith('std::chrono::hh_mm_ss'): fract = '' if val['fractional_width'] != 0: - fract = '.{:0{}d}'.format(int(val['_M_ss']['__r']), + fract = '.{:0{}d}'.format(int(val['_M_ss']['_M_r']), int(val['fractional_width'])) h = int(val['_M_h']['__r']) m = int(val['_M_m']['__r']) @@ -2060,7 +2068,7 @@ class StdChronoTimeZonePrinter: self.val = val def to_string(self): - str = '%s %s' % (self.typename, self.val['_M_name']) + str = '%s = %s' % (self.typename, self.val['_M_name']) if self.typename.endswith("_link"): str += ' -> %s' % (self.val['_M_target']) return str diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/chrono.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/chrono.cc new file mode 100644 index 00000000000..01a46169393 --- /dev/null +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/chrono.cc @@ -0,0 +1,87 @@ +// { dg-options "-g -O0 -std=gnu++2a" } +// { dg-do run { target c++2a } } + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library 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, or (at your option) +// any later version. + +// This library 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 library; see the file COPYING3. If not see +// . + +#include +#include + +int +main() +{ + using namespace std::chrono; + + seconds just_a_sec(1); + // { dg-final { note-test just_a_sec {std::chrono::duration = { 1s }} } } + microseconds just_a_moment(5001); + // { dg-final { note-test just_a_moment {std::chrono::duration = { 5001us }} } } + duration> pie(2.72f); + // { dg-final { note-test pie {std::chrono::duration = { 2.72[22/7]s }} } } + + sys_seconds half_past_epoch(1800s); + // { dg-final { note-test half_past_epoch {std::chrono::sys_time = { 1800s [1970-01-01 00:30:00] }} } } + utc_time utc(467664h); + // { dg-final { note-test utc {std::chrono::utc_time = { 467664h }} } } + +#if _GLIBCXX_USE_CXX11_ABI + zoned_time zt("Europe/London", half_past_epoch); + // { dg-final { note-test zt {std::chrono::zoned_time = { "Europe/London" 1800000ms [1970-01-01 00:30:00] }} { target cxx11_abi } } } +#endif + + [[maybe_unused]] day ninth(9); + // { dg-final { note-test ninth {9} } } + [[maybe_unused]] month may = May; + // { dg-final { note-test may {May} } } + auto twentytwentythree = 2023y; + // { dg-final { note-test twentytwentythree {2023y} } } + [[maybe_unused]] weekday tues = Tuesday; + // { dg-final { note-test tues {Tuesday} } } + [[maybe_unused]] weekday_indexed second_tues = Tuesday[2]; + // { dg-final { note-test second_tues {Tuesday[2]} } } + [[maybe_unused]] weekday_last last_tues = Tuesday[last]; + // { dg-final { note-test last_tues {Tuesday[last]} } } + [[maybe_unused]] month_day midsummer = June/21; + // { dg-final { note-test midsummer {June/21} } } + [[maybe_unused]] month_day_last end_jan = January/last; + // { dg-final { note-test end_jan {January/last} } } + [[maybe_unused]] month_weekday handsel = January/Monday[1]; + // { dg-final { note-test handsel {January/Monday[1]} } } + [[maybe_unused]] month_weekday_last reek = July/Sunday[last]; + // { dg-final { note-test reek {July/Sunday[last]} } } + [[maybe_unused]] year_month feb_2023 = 2023y/February; + // { dg-final { note-test feb_2023 {2023y/February} } } + [[maybe_unused]] year_month_day barbican = September/17/1997y; + // { dg-final { note-test barbican {1997y/September/17} } } + [[maybe_unused]] year_month_day_last party_like = 1999y/December/last; + // { dg-final { note-test party_like {1999y/December/last} } } + [[maybe_unused]] year_month_weekday easter = 2023y/April/Sunday[2]; + // { dg-final { note-test easter {2023y/April/Sunday[2]} } } + [[maybe_unused]] year_month_weekday_last donnerstag = 2017y/July/Thursday[last]; + // { dg-final { note-test donnerstag {2017y/July/Thursday[last]} } } + + hh_mm_ss hms(4h + 3min + 2s); + // { dg-final { note-test hms {04:03:02} } } + + hh_mm_ss hms_nano(-14h - 13min - 12s - 11ns); + // { dg-final { note-test hms_nano {-14:13:12.000000011} } } + + std::cout << "\n"; + return 0; // Mark SPOT +} + +// { dg-final { gdb-test SPOT } }