public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-641] libstdc++: Fix <chrono> pretty printers and add tests
@ 2023-05-09 19:53 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2023-05-09 19:53 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:7bd251ca751317385f7e2e4e031736a99f376012

commit r14-641-g7bd251ca751317385f7e2e4e031736a99f376012
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue May 9 18:18:01 2023 +0100

    libstdc++: Fix <chrono> pretty printers and add tests
    
    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.

Diff:
---
 libstdc++-v3/python/libstdcxx/v6/printers.py       | 44 ++++++-----
 .../testsuite/libstdc++-prettyprinters/chrono.cc   | 87 ++++++++++++++++++++++
 2 files changed, 113 insertions(+), 18 deletions(-)

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<C> and print out children
-    # TODO: add printer for basic_format_args<C>::_Store<Args...>
+    # TODO: add printer for basic_format_arg<Context> and print out children.
+    # TODO: add printer for __format::_ArgStore<Context, Args...>.
 
     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
+// <http://www.gnu.org/licenses/>.
+
+#include <chrono>
+#include <iostream>
+
+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<float, std::ratio<22, 7>> 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<milliseconds> 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<seconds> hms(4h + 3min + 2s);
+  // { dg-final { note-test hms {04:03:02} } }
+
+  hh_mm_ss<nanoseconds> 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 } }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-05-09 19:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-09 19:53 [gcc r14-641] libstdc++: Fix <chrono> pretty printers and add tests Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).