X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fcalendarspec.c;h=2fde3e107e0a81345cb39350290376554ec52eb3;hp=da920b6dd919f51acf0cdfab87dc16ca2de9641e;hb=01c94c5d0aff09b4c0e429d483c8eeba40017071;hpb=272ac205176dc922a2da87d212fd2c88ece4231e diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c index da920b6dd..2fde3e107 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; @@ -120,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); @@ -154,7 +156,7 @@ _pure_ static bool chain_valid(CalendarComponent *c, int from, int to) { _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)) @@ -194,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++) { @@ -259,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); } @@ -474,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; @@ -693,8 +695,10 @@ 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 */ ) { + } else if (strcaseeq(p, "annually") || + strcaseeq(p, "yearly") || + strcaseeq(p, "anually") /* backwards compatibility */ ) { + r = const_chain(1, &c->month); if (r < 0) goto fail; @@ -725,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) @@ -827,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;