X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fcalendarspec.c;h=19ae8a32335311263b671b92724801e0f2319c22;hp=13f70d8e72edaae269b5fddc5f56142a5b7563e9;hb=b6b1849830f5e4a6065c3b0c993668e500c954d3;hpb=8333c77edf8fd1654cd96f3f6ee0f078dd64b58b diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c index 13f70d8e7..19ae8a323 100644 --- a/src/shared/calendarspec.c +++ b/src/shared/calendarspec.c @@ -24,6 +24,8 @@ #include "calendarspec.h" +#define BITS_WEEKDAYS 127 + static void free_chain(CalendarComponent *c) { CalendarComponent *n; @@ -35,7 +37,9 @@ static void free_chain(CalendarComponent *c) { } void calendar_spec_free(CalendarSpec *c) { - assert(c); + + if (!c) + return; free_chain(c->year); free_chain(c->month); @@ -118,7 +122,7 @@ static void fix_year(CalendarComponent *c) { int calendar_spec_normalize(CalendarSpec *c) { assert(c); - if (c->weekdays_bits <= 0 || c->weekdays_bits >= 127) + if (c->weekdays_bits <= 0 || c->weekdays_bits >= BITS_WEEKDAYS) c->weekdays_bits = -1; fix_year(c->year); @@ -133,7 +137,7 @@ int calendar_spec_normalize(CalendarSpec *c) { return 0; } -static bool chain_valid(CalendarComponent *c, int from, int to) { +_pure_ static bool chain_valid(CalendarComponent *c, int from, int to) { if (!c) return true; @@ -149,10 +153,10 @@ static bool chain_valid(CalendarComponent *c, int from, int to) { return true; } -bool calendar_spec_valid(CalendarSpec *c) { +_pure_ bool calendar_spec_valid(CalendarSpec *c) { assert(c); - if (c->weekdays_bits > 127) + if (c->weekdays_bits > BITS_WEEKDAYS) return false; if (!chain_valid(c->year, 1970, 2199)) @@ -192,7 +196,7 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) { assert(f); assert(c); - assert(c->weekdays_bits > 0 && c->weekdays_bits <= 127); + assert(c->weekdays_bits > 0 && c->weekdays_bits <= BITS_WEEKDAYS); for (x = 0, l = -1; x < (int) ELEMENTSOF(days); x++) { @@ -257,7 +261,7 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) { if (!f) return -ENOMEM; - if (c->weekdays_bits > 0 && c->weekdays_bits <= 127) { + if (c->weekdays_bits > 0 && c->weekdays_bits <= BITS_WEEKDAYS) { format_weekdays(f, c); fputc(' ', f); } @@ -472,7 +476,7 @@ static int const_chain(int value, CalendarComponent **c) { cc->value = value; cc->repeat = 0; - cc->next = NULL; + cc->next = *c; *c = cc; @@ -653,7 +657,12 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { if (!c) return -ENOMEM; - if (strcaseeq(p, "hourly")) { + if (strcaseeq(p, "minutely")) { + r = const_chain(0, &c->second); + if (r < 0) + goto fail; + + } else if (strcaseeq(p, "hourly")) { r = const_chain(0, &c->minute); if (r < 0) goto fail; @@ -686,6 +695,26 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { if (r < 0) goto fail; + } else if (strcaseeq(p, "annually") || + strcaseeq(p, "yearly") || + strcaseeq(p, "anually") /* backwards compatibility */ ) { + + r = const_chain(1, &c->month); + if (r < 0) + goto fail; + r = const_chain(1, &c->day); + if (r < 0) + goto fail; + r = const_chain(0, &c->hour); + if (r < 0) + goto fail; + r = const_chain(0, &c->minute); + if (r < 0) + goto fail; + r = const_chain(0, &c->second); + if (r < 0) + goto fail; + } else if (strcaseeq(p, "weekly")) { c->weekdays_bits = 1; @@ -700,6 +729,57 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { if (r < 0) goto fail; + } else if (strcaseeq(p, "quarterly")) { + + r = const_chain(1, &c->month); + if (r < 0) + goto fail; + r = const_chain(4, &c->month); + if (r < 0) + goto fail; + r = const_chain(7, &c->month); + if (r < 0) + goto fail; + r = const_chain(10, &c->month); + if (r < 0) + goto fail; + r = const_chain(1, &c->day); + if (r < 0) + goto fail; + r = const_chain(0, &c->hour); + if (r < 0) + goto fail; + r = const_chain(0, &c->minute); + if (r < 0) + goto fail; + r = const_chain(0, &c->second); + if (r < 0) + goto fail; + + } else if (strcaseeq(p, "biannually") || + strcaseeq(p, "bi-annually") || + strcaseeq(p, "semiannually") || + strcaseeq(p, "semi-annually")) { + + r = const_chain(1, &c->month); + if (r < 0) + goto fail; + r = const_chain(7, &c->month); + if (r < 0) + goto fail; + r = const_chain(1, &c->day); + if (r < 0) + goto fail; + r = const_chain(0, &c->hour); + if (r < 0) + goto fail; + r = const_chain(0, &c->minute); + if (r < 0) + goto fail; + r = const_chain(0, &c->second); + if (r < 0) + goto fail; + } else { r = parse_weekdays(&p, c); if (r < 0) @@ -802,7 +882,7 @@ static bool matches_weekday(int weekdays_bits, const struct tm *tm) { struct tm t; int k; - if (weekdays_bits < 0 || weekdays_bits >= 127) + if (weekdays_bits < 0 || weekdays_bits >= BITS_WEEKDAYS) return true; t = *tm; @@ -921,7 +1001,6 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next) if (t == (time_t) -1) return -EINVAL; - *next = (usec_t) t * USEC_PER_SEC; return 0; }