From 8e1e59b9ade5b737e24a76bae1944ce84acf564c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 10 May 2022 11:35:52 +0200 Subject: shared/calendarspec: fix formatting of entries which collapse to a star MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We canonicalize repeats that cover the whole range: "0:0:0/1" → "0:0:*". But we'd also do "0:0:0/1,0" → "0:0:*,0", which we then refuse to parse. Thus, first go throug the whole chain, and print a '*' and nothing else if any of the components covers the whole range. --- src/shared/calendarspec.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'src/shared') diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c index 273a38f1fa..767c1b7856 100644 --- a/src/shared/calendarspec.c +++ b/src/shared/calendarspec.c @@ -288,17 +288,24 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) { } } -static void format_chain(FILE *f, int space, const CalendarComponent *c, bool usec) { +static bool chain_is_star(const CalendarComponent *c, bool usec) { + /* Return true if the whole chain can be replaced by '*'. + * This happens when the chain is empty or one of the components covers all. */ + if (!c) + return true; + if (usec) + for (; c; c = c->next) + if (c->start == 0 && c->stop < 0 && c->repeat == USEC_PER_SEC) + return true; + return false; +} + +static void _format_chain(FILE *f, int space, const CalendarComponent *c, bool start, bool usec) { int d = usec ? (int) USEC_PER_SEC : 1; assert(f); - if (!c) { - fputc('*', f); - return; - } - - if (usec && c->start == 0 && c->stop < 0 && c->repeat == USEC_PER_SEC && !c->next) { + if (start && chain_is_star(c, usec)) { fputc('*', f); return; } @@ -321,10 +328,14 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c, bool us if (c->next) { fputc(',', f); - format_chain(f, space, c->next, usec); + _format_chain(f, space, c->next, false, usec); } } +static void format_chain(FILE *f, int space, const CalendarComponent *c, bool usec) { + _format_chain(f, space, c, /* start = */ true, usec); +} + int calendar_spec_to_string(const CalendarSpec *c, char **p) { char *buf = NULL; size_t sz = 0; -- cgit v1.2.1