This is already supported by gnulib. * manual/time.texi: Document %q outputs quarter 1..4. * time/strftime_l.c: Implement %q. --- manual/time.texi | 6 ++++++ time/strftime_l.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/manual/time.texi b/manual/time.texi index 8a5f94e..f4c5f87 100644 --- a/manual/time.texi +++ b/manual/time.texi @@ -1510,6 +1510,12 @@ most locales @samp{AM}/@samp{PM} format is not supported, in such cases This format is a GNU extension. +@item %q +Quarter of the year (@samp{1}@dots{}@samp{4}), +with January starting the first quarter. + +This format is a GNU extension. + @item %r The complete calendar time using the AM/PM format of the current locale. diff --git a/time/strftime_l.c b/time/strftime_l.c index 869e0b9..13db490 100644 --- a/time/strftime_l.c +++ b/time/strftime_l.c @@ -1108,6 +1108,10 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument goto underlying_strftime; #endif + case L_('q'): /* GNU extension. */ + DO_SIGNED_NUMBER (1, tp->tm_mon < -3, tp->tm_mon / 3 + 1U); + break; + case L_('R'): subfmt = L_("%H:%M"); goto subformat; -- 2.5.5
* Pádraig Brady: > This is already supported by gnulib. This needs a test case (at least a test case update). > + case L_('q'): /* GNU extension. */ > + DO_SIGNED_NUMBER (1, tp->tm_mon < -3, tp->tm_mon / 3 + 1U); > + break; I don't think we have DO_SIGNED_NUMBER in glibc.
On 03/11/2016 17:58, Florian Weimer wrote:
> * Pádraig Brady:
>
>> This is already supported by gnulib.
>
> This needs a test case (at least a test case update).
>
>> + case L_('q'): /* GNU extension. */
>> + DO_SIGNED_NUMBER (1, tp->tm_mon < -3, tp->tm_mon / 3 + 1U);
>> + break;
>
> I don't think we have DO_SIGNED_NUMBER in glibc.
>
Indeed and you need to indicate how/where exactly you have tested
it.
[-- Attachment #1: Type: text/plain, Size: 229 bytes --] On Thu, 3 Nov 2016, Florian Weimer wrote: > * Pádraig Brady: > > > This is already supported by gnulib. > > This needs a test case (at least a test case update). And a NEWS entry. -- Joseph S. Myers joseph@codesourcery.com
[-- Attachment #1: Type: text/plain, Size: 442 bytes --] Updated patch attached. Tested using: sudo alternatives --set ld /usr/bin/ld.bfd mkdir build.tmp cd build.tmp ../configure --quiet --disable-sanity-checks make PARALLELMFLAGS=-j$(nproc) make -r PARALLELMFLAGS=-j$(nproc) -C $PWD/../time objdir=$(pwd) check ./testrun.sh time/tst-strftime && echo ok Note even though the code is trivial here, %q is useful as from the shell you need to: $(( ($(date +%-m)-1)/3+1 )) thanks, Pádraig. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: glibc-strftime-%q.patch --] [-- Type: text/x-patch; name="glibc-strftime-%q.patch", Size: 2977 bytes --] From 137cc31d7870e3ecda6c67cda47e29ace2c5acf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com> Date: Thu, 3 Nov 2016 19:36:59 +0000 Subject: [PATCH] strftime: support %q to output the quarter of year This is already supported by gnulib. * manual/time.texi: Document %q outputs quarter 1..4. * time/strftime_l.c: Implement %q. * time/tst-strftime.c: Add a test case. * NEWS: Mention the new feature. --- NEWS | 2 ++ manual/time.texi | 6 ++++++ time/strftime_l.c | 4 ++++ time/tst-strftime.c | 27 +++++++++++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/NEWS b/NEWS index 65184b1..9b9fa33 100644 --- a/NEWS +++ b/NEWS @@ -119,6 +119,8 @@ Version 2.25 variable for a particular architecture in the GCC source file 'gcc/config.gcc'. +* strftime now supports the %q directive to output the quarter of the year. + Security related changes: On ARM EABI (32-bit), generating a backtrace for execution contexts which diff --git a/manual/time.texi b/manual/time.texi index 6a899b7..b6466d1 100644 --- a/manual/time.texi +++ b/manual/time.texi @@ -1510,6 +1510,12 @@ most locales @samp{AM}/@samp{PM} format is not supported, in such cases This format is a GNU extension. +@item %q +Quarter of the year (@samp{1}@dots{}@samp{4}), +with January starting the first quarter. + +This format is a GNU extension. + @item %r The complete calendar time using the AM/PM format of the current locale. diff --git a/time/strftime_l.c b/time/strftime_l.c index 1205035..25746a0 100644 --- a/time/strftime_l.c +++ b/time/strftime_l.c @@ -1085,6 +1085,10 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format, goto underlying_strftime; #endif + case L_('q'): /* GNU extension. */ + DO_NUMBER (1, tp->tm_mon / 3 + 1); + break; + case L_('R'): subfmt = L_("%H:%M"); goto subformat; diff --git a/time/tst-strftime.c b/time/tst-strftime.c index af3ff72..d087266 100644 --- a/time/tst-strftime.c +++ b/time/tst-strftime.c @@ -154,6 +154,33 @@ do_test (void) } } + /* Check %q. */ + for (size_t mon = 1; mon <= 12; mon++) + { + char out[2]; + char exp[2] = {0,}; + struct tm qtm = { .tm_mon = mon - 1 }; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" + size_t r = strftime (out, sizeof (out), "%q", &qtm); +#pragma GCC diagnostic pop + if (r == 0) + { + puts ("strftime(\"%q\") failed"); + result = 1; + break; + } + + exp[0] = mon < 4 ? '1' : mon < 7 ? '2' : mon < 10 ? '3' : '4'; + if (strcmp (out, exp) != 0) + { + printf ("strftime %%q: expected \"%s\", got \"%s\"\n", exp, out); + result = 1; + break; + } + } + return result + do_bz18985 (); } -- 2.5.5
Pádraig Brady wrote:
> + DO_NUMBER (1, tp->tm_mon / 3 + 1);
I couldn't resist puzzling this one out. We can assume 0 <= tp->tm_mon < 12, so
this should be a tad more efficient:
DO_NUMBER (1, ((tp->tm_mon * 11) >> 5) + 1);
With gcc 6.2.0 -O2 x86-64, the former uses imull with 6 insns, the latter just
leal with 4 insns. Perhaps GCC should be smart enough to figure this out on its
own, but what would be the fun of that?
Hi, Shouldn't strptime() family also support the same? Regards, Rafal
On 03/11/16 19:46, Pádraig Brady wrote:
> This is already supported by gnulib.
why?
On 04/11/16 11:41, Szabolcs Nagy wrote: > On 03/11/16 19:46, Pádraig Brady wrote: >> This is already supported by gnulib. > why? It's a marginal benefit, but as noted in the cover of my updated patch: "Note even though the code is trivial here, %q is useful from the shell as there you need to: $(( ($(date +%-m)-1)/3+1 ))". I'll add that to the actual commit.
On 04/11/16 12:00, Pádraig Brady wrote:
> On 04/11/16 11:41, Szabolcs Nagy wrote:
>> On 03/11/16 19:46, Pádraig Brady wrote:
>>> This is already supported by gnulib.
>
>> why?
>
> It's a marginal benefit, but as
> noted in the cover of my updated patch:
>
> "Note even though the code is trivial here,
> %q is useful from the shell as there you need to:
> $(( ($(date +%-m)-1)/3+1 ))".
>
> I'll add that to the actual commit.
this can conflict with future standard, so
there need to be a strong reason for adding
such extensions to portability libraries
such as gnulib or to c runtimes.
how does gnulib plan to deal with the conflict
once posix adds %q with different meaning?
On 04/11/16 12:07, Szabolcs Nagy wrote:
> On 04/11/16 12:00, Pádraig Brady wrote:
>> On 04/11/16 11:41, Szabolcs Nagy wrote:
>>> On 03/11/16 19:46, Pádraig Brady wrote:
>>>> This is already supported by gnulib.
>>
>>> why?
>>
>> It's a marginal benefit, but as
>> noted in the cover of my updated patch:
>>
>> "Note even though the code is trivial here,
>> %q is useful from the shell as there you need to:
>> $(( ($(date +%-m)-1)/3+1 ))".
>>
>> I'll add that to the actual commit.
>
> this can conflict with future standard, so
> there need to be a strong reason for adding
> such extensions to portability libraries
> such as gnulib or to c runtimes.
>
> how does gnulib plan to deal with the conflict
> once posix adds %q with different meaning?
Perl's date lib also uses %q for quarter.
So between that and gnulib (and glibc?)
POSIX would be unlikely to choose %q for something else.
In any case I intend to propose it to the POSIX folks.
thanks,
Pádraig
On 04/11/16 12:23, Pádraig Brady wrote: > On 04/11/16 12:07, Szabolcs Nagy wrote: >> On 04/11/16 12:00, Pádraig Brady wrote: >>> On 04/11/16 11:41, Szabolcs Nagy wrote: >>>> On 03/11/16 19:46, Pádraig Brady wrote: >>>>> This is already supported by gnulib. >>> >>>> why? >>> >>> It's a marginal benefit, but as >>> noted in the cover of my updated patch: >>> >>> "Note even though the code is trivial here, >>> %q is useful from the shell as there you need to: >>> $(( ($(date +%-m)-1)/3+1 ))". >>> >>> I'll add that to the actual commit. >> >> this can conflict with future standard, so >> there need to be a strong reason for adding >> such extensions to portability libraries >> such as gnulib or to c runtimes. >> >> how does gnulib plan to deal with the conflict >> once posix adds %q with different meaning? > > Perl's date lib also uses %q for quarter. i don't know what "Perl's date lib" is, the perl DateTime module does not seem to support %q. https://metacpan.org/pod/DateTime#strftime-Patterns > So between that and gnulib (and glibc?) > POSIX would be unlikely to choose %q for something else. > In any case I intend to propose it to the POSIX folks. > > thanks, > Pádraig >
On 04/11/16 12:41, Szabolcs Nagy wrote: > On 04/11/16 12:23, Pádraig Brady wrote: >> On 04/11/16 12:07, Szabolcs Nagy wrote: >>> On 04/11/16 12:00, Pádraig Brady wrote: >>>> On 04/11/16 11:41, Szabolcs Nagy wrote: >>>>> On 03/11/16 19:46, Pádraig Brady wrote: >>>>>> This is already supported by gnulib. >>>> >>>>> why? >>>> >>>> It's a marginal benefit, but as >>>> noted in the cover of my updated patch: >>>> >>>> "Note even though the code is trivial here, >>>> %q is useful from the shell as there you need to: >>>> $(( ($(date +%-m)-1)/3+1 ))". >>>> >>>> I'll add that to the actual commit. >>> >>> this can conflict with future standard, so >>> there need to be a strong reason for adding >>> such extensions to portability libraries >>> such as gnulib or to c runtimes. >>> >>> how does gnulib plan to deal with the conflict >>> once posix adds %q with different meaning? >> >> Perl's date lib also uses %q for quarter. > > i don't know what "Perl's date lib" is, > the perl DateTime module does not seem to support %q. > https://metacpan.org/pod/DateTime#strftime-Patterns Sorry Perl's Date::Format supports %q https://metacpan.org/pod/Date::Format#CONVERSION-SPECIFICATION
ISO 30112 will poropose %q in the new revision.
I think it is difficult for POSIX then to do something else.
Have you got standardese for the %q spec, which I can use in 30112?
Best regards
keld
On Fri, Nov 04, 2016 at 12:23:28PM +0000, Pádraig Brady wrote:
> On 04/11/16 12:07, Szabolcs Nagy wrote:
> > On 04/11/16 12:00, Pádraig Brady wrote:
> >> On 04/11/16 11:41, Szabolcs Nagy wrote:
> >>> On 03/11/16 19:46, Pádraig Brady wrote:
> >>>> This is already supported by gnulib.
> >>
> >>> why?
> >>
> >> It's a marginal benefit, but as
> >> noted in the cover of my updated patch:
> >>
> >> "Note even though the code is trivial here,
> >> %q is useful from the shell as there you need to:
> >> $(( ($(date +%-m)-1)/3+1 ))".
> >>
> >> I'll add that to the actual commit.
> >
> > this can conflict with future standard, so
> > there need to be a strong reason for adding
> > such extensions to portability libraries
> > such as gnulib or to c runtimes.
> >
> > how does gnulib plan to deal with the conflict
> > once posix adds %q with different meaning?
>
> Perl's date lib also uses %q for quarter.
> So between that and gnulib (and glibc?)
> POSIX would be unlikely to choose %q for something else.
> In any case I intend to propose it to the POSIX folks.
>
> thanks,
> Pádraig
On 04/11/16 13:12, keld@keldix.com wrote:
> ISO 30112 will poropose %q in the new revision.
> I think it is difficult for POSIX then to do something else.
this should be the other way around: propose the interface
to posix, then add locale specifications later, otherwise
the two standards can diverge.
[-- Attachment #1: Type: text/plain, Size: 289 bytes --] On 04/11/16 11:33, Rafal Luzynski wrote: > Hi, > > Shouldn't strptime() family also support the same? I was debating that, but you're right, strptime() should support that for consistency. Updated patch is attached, which also adjusts to Paul Eggert's optimization. thanks, Pádraig [-- Attachment #2: glibc-strptime-%q.patch --] [-- Type: text/x-patch, Size: 5387 bytes --] From ad0ed0247612bf7d85afe1af0c8a61e804db274c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com> Date: Thu, 3 Nov 2016 19:36:59 +0000 Subject: [PATCH] strftime,strptime: have %q represent the quarter of year This is already supported by gnulib, and for example simplifies quarter determination at the shell, which currently needs to use "$(( ($(date +%-m)-1)/3+1 ))". * manual/time.texi: Document %q for str[fp]time. * time/strftime_l.c: Implement %q. * time/strptime_l.c: Likewise. * time/tst-strftime.c: Add a test case. * time/tst-strptime3.c: Likewise. * NEWS: Mention the new feature. --- NEWS | 3 +++ manual/time.texi | 12 ++++++++++++ time/strftime_l.c | 7 +++++++ time/strptime_l.c | 18 ++++++++++++++++++ time/tst-strftime.c | 25 +++++++++++++++++++++++++ time/tst-strptime3.c | 20 ++++++++++++++++++++ 6 files changed, 85 insertions(+) diff --git a/NEWS b/NEWS index 65184b1..e08f9ed 100644 --- a/NEWS +++ b/NEWS @@ -119,6 +119,9 @@ Version 2.25 variable for a particular architecture in the GCC source file 'gcc/config.gcc'. +* strftime and strptime now support the %q directive to represent + the quarter of the year, with January starting the first quarter. + Security related changes: On ARM EABI (32-bit), generating a backtrace for execution contexts which diff --git a/manual/time.texi b/manual/time.texi index 6a899b7..5ba0558 100644 --- a/manual/time.texi +++ b/manual/time.texi @@ -1510,6 +1510,12 @@ most locales @samp{AM}/@samp{PM} format is not supported, in such cases This format is a GNU extension. +@item %q +Quarter of the year (@samp{1}@dots{}@samp{4}), +with January starting the first quarter. + +This format is a GNU extension. + @item %r The complete calendar time using the AM/PM format of the current locale. @@ -1926,6 +1932,12 @@ all and therefore the conversion fails. @code{%P} is a GNU extension following a GNU extension to @code{strftime}. +@item %q +Quarter of the year (@samp{1}@dots{}@samp{4}), +with January starting the first quarter. + +This format is a GNU extension. + @item %r The complete time using the AM/PM format of the current locale. diff --git a/time/strftime_l.c b/time/strftime_l.c index 1205035..09d9373 100644 --- a/time/strftime_l.c +++ b/time/strftime_l.c @@ -1085,6 +1085,13 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format, goto underlying_strftime; #endif + case L_('q'): /* Quarter of year. GNU extension. */ + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (1, ((tp->tm_mon * 11) >> 5) + 1); + break; + case L_('R'): subfmt = L_("%H:%M"); goto subformat; diff --git a/time/strptime_l.c b/time/strptime_l.c index 3a56947..f957e40 100644 --- a/time/strptime_l.c +++ b/time/strptime_l.c @@ -593,6 +593,15 @@ __strptime_internal (const char *rp, const char *fmt, struct tm *tmp, else s.is_pm = 0; break; + case 'q': + /* Match quarter of year. GNU extension. */ + get_number (1, 4, 1); + tm->tm_mon = (val - 1) * 3; + tm->tm_mday = 1; + s.have_mon = 1; + s.have_mday = 1; + s.want_xday = 1; + break; case 'r': #ifdef _NL_CURRENT if (s.decided != raw) @@ -1050,6 +1059,15 @@ __strptime_internal (const char *rp, const char *fmt, struct tm *tmp, get_alt_number (0, 59, 2); tm->tm_min = val; break; + case 'q': + /* Match quarter using alternate numeric symbols. */ + get_alt_number (1, 4, 1); + tm->tm_mon = (val - 1) * 3; + tm->tm_mday = 1; + s.have_mon = 1; + s.have_mday = 1; + s.want_xday = 1; + break; case 'S': /* Match seconds using alternate numeric symbols. */ get_alt_number (0, 61, 2); diff --git a/time/tst-strftime.c b/time/tst-strftime.c index af3ff72..62ee6c0 100644 --- a/time/tst-strftime.c +++ b/time/tst-strftime.c @@ -154,6 +154,31 @@ do_test (void) } } + /* Check %q. */ + for (size_t mon = 1; mon <= 12; mon++) + { + char out[2]; + char exp[2] = {0,}; + struct tm qtm = { .tm_mon = mon - 1 }; + char fmt[3] = {'%','q','\0'}; + + size_t r = strftime (out, sizeof (out), fmt, &qtm); + if (r == 0) + { + puts ("strftime(\"%q\") failed"); + result = 1; + break; + } + + exp[0] = mon < 4 ? '1' : mon < 7 ? '2' : mon < 10 ? '3' : '4'; + if (strcmp (out, exp) != 0) + { + printf ("strftime %%q: expected \"%s\", got \"%s\"\n", exp, out); + result = 1; + break; + } + } + return result + do_bz18985 (); } diff --git a/time/tst-strptime3.c b/time/tst-strptime3.c index d53f51e..b08f6f4 100644 --- a/time/tst-strptime3.c +++ b/time/tst-strptime3.c @@ -48,6 +48,26 @@ do_test (void) result = 1; } + memset (&tm, 0xaa, sizeof (tm)); + for (size_t q = 1; q <= 4; q++) + { + char in[2] = {0,}; + in[0] = q + '0'; + int exp_mon = q == 1 ? 0 : q == 2 ? 3 : q == 3 ? 6 : 9; + char fmt[3] = {'%','q','\0'}; + + if (strptime (in, fmt, &tm) == NULL) + { + puts ("strptime failed"); + result = 1; + } + if (tm.tm_mon != exp_mon || tm.tm_mday != 1) + { + puts ("unexpected tm content"); + result = 1; + } + } + return result; } -- 2.5.5
On 04/11/2016 12:12, Szabolcs Nagy wrote:
> On 04/11/16 13:12, keld@keldix.com wrote:
>> ISO 30112 will poropose %q in the new revision.
>> I think it is difficult for POSIX then to do something else.
>
> this should be the other way around: propose the interface
> to posix, then add locale specifications later, otherwise
> the two standards can diverge.
I tend to agree with this rationale.
On Fri, Nov 04, 2016 at 02:12:28PM +0000, Szabolcs Nagy wrote:
> On 04/11/16 13:12, keld@keldix.com wrote:
> > ISO 30112 will poropose %q in the new revision.
> > I think it is difficult for POSIX then to do something else.
>
> this should be the other way around: propose the interface
> to posix, then add locale specifications later, otherwise
> the two standards can diverge.
Oh, well, 30112 has taken the lead on many i18n issues, and this is also the agreement with the posix folks.
Best regards
keld