On Fri, 21 Mar 2025 at 09:47, Tomasz Kaminski <tkami...@redhat.com> wrote:
>
>
>
> On Thu, Mar 20, 2025 at 5:29 PM Jonathan Wakely <jwak...@redhat.com> wrote:
>>
>> On Thu, 20 Mar 2025 at 16:16, Jonathan Wakely <jwak...@redhat.com> wrote:
>> >
>> > When using std::time_put to format a chrono value, we should imbue the
>> > formatting locale into the stream. This ensures that when
>> > std::time_put::do_put uses a ctype or __timepunct facet from the locale,
>> > it gets the correct facets.
>> >
>> > libstdc++-v3/ChangeLog:
>> >
>> >         * include/bits/chrono_io.h (__formatter_chrono::_M_locale_fmt):
>> >         Imbue locale into ostringstream.
>> >         * testsuite/std/time/format/localized.cc: Check that correct
>> >         locale is used for call to time_put::put.
>> > ---
>> >
>> > Now with a test that shows the bug independent of the PR117214 patches
>> > to use std::time_put for %c formats.
>> >
>> > Tested x86_64-linux.
>> >
>> >  libstdc++-v3/include/bits/chrono_io.h         |  1 +
>> >  .../testsuite/std/time/format/localized.cc    | 30 +++++++++++++++++++
>> >  2 files changed, 31 insertions(+)
>> >
>> > diff --git a/libstdc++-v3/include/bits/chrono_io.h 
>> > b/libstdc++-v3/include/bits/chrono_io.h
>> > index c16b555df29..55ebd4ee061 100644
>> > --- a/libstdc++-v3/include/bits/chrono_io.h
>> > +++ b/libstdc++-v3/include/bits/chrono_io.h
>> > @@ -1697,6 +1697,7 @@ namespace __format
>> >                       char __fmt, char __mod) const
>> >         {
>> >           basic_ostringstream<_CharT> __os;
>> > +         __os.imbue(__loc);
>> >           const auto& __tp = use_facet<time_put<_CharT>>(__loc);
>> >           __tp.put(__os, __os, _S_space, &__tm, __fmt, __mod);
>> >           if (__os)
>> > diff --git a/libstdc++-v3/testsuite/std/time/format/localized.cc 
>> > b/libstdc++-v3/testsuite/std/time/format/localized.cc
>> > index 393d0d200e4..437a4a011b2 100644
>> > --- a/libstdc++-v3/testsuite/std/time/format/localized.cc
>> > +++ b/libstdc++-v3/testsuite/std/time/format/localized.cc
>> > @@ -13,6 +13,7 @@
>> >
>> >  #include <chrono>
>> >  #include <format>
>> > +#include <locale>
>> >  #include <stdio.h>
>> >  #include <testsuite_hooks.h>
>> >
>> > @@ -81,6 +82,35 @@ test_en()
>> >      }
>> >  }
>> >
>> > +void
>> > +test_locale_imbued()
>> > +{
>> > +  // Custom time_put facet which returns %b string for %Om
>> > +  struct TimePut : std::time_put<char>
>> > +  {
>> > +    iter_type
>> > +    do_put(iter_type out, std::ios_base& io, char_type fill, const tm* t,
>> > +          char format, char modifier) const override
>> > +    {
>> > +      if (format == 'm' && modifier == 'O')
>> > +       format = 'b';
>> > +      return std::time_put<char>::do_put(out, io, fill, t, format, 0);
>> > +    }
>> > +  };
>> > +
>> > +  auto m = std::chrono::March;
>> > +
>> > +  std::locale fr(ISO_8859(1,fr_FR));
>> > +  std::locale fr2(fr, new TimePut);
>> > +  auto s1 = std::format(fr2, "{:L%Om}", m);
>> > +  VERIFY( s1 == std::format(fr, "{:L}", m) );
>> > +
>> > +  std::locale es(ISO_8859(1,es_ES));
>> > +  std::locale es2(es, new TimePut);
>> > +  auto s2 = std::format(es2, "{:L%Om}", m);
>> > +  VERIFY( s2 == std::format(es, "{:L}", m) );
>> > +}
>> > +
>> >  int main()
>> >  {
>> >    test_ru();
>>
>> It would help if I added the new test_locale_imbued() function to main
>> so that it actually runs.
>
> LGTM with that addition.

I also added some more comments in the new test, to explain what is
expected (so it's more clear why it didn't work before the commit).


>>
>>
>> Luckily it passes when I do that.
>>

Reply via email to