diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2022-05-10 11:35:52 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2022-05-10 14:35:57 +0200 |
commit | 8e1e59b9ade5b737e24a76bae1944ce84acf564c (patch) | |
tree | aa76a985e1f6c9a74e43b6e295a95c9d1a47d900 /src/shared | |
parent | 3aff2ae9d5427498f673bcb086d3439d2047e6c9 (diff) | |
download | systemd-8e1e59b9ade5b737e24a76bae1944ce84acf564c.tar.gz |
shared/calendarspec: fix formatting of entries which collapse to a star
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.
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/calendarspec.c | 27 |
1 files changed, 19 insertions, 8 deletions
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; |