static int parse_time(const char **p, CalendarSpec *c) { CalendarComponent *h = NULL, *m = NULL, *s = NULL; const char *t; int r; assert(p); assert(*p); assert(c); t = *p; if (*t == 0) { /* If no time is specified at all, but a date of some * kind, then this means 00:00:00 */ if (c->day || c->weekdays_bits > 0) goto null_hour; goto finish; } r = parse_chain(&t, &h); if (r < 0) goto fail; if (*t != ':') { r = -EINVAL; goto fail; } t++; r = parse_chain(&t, &m); if (r < 0) goto fail; /* Already at the end? Then it's hours and minutes, and seconds are 0 */ if (*t == 0) { if (m != NULL) goto null_second; goto finish; } if (*t != ':') { r = -EINVAL; goto fail; } t++; r = parse_chain(&t, &s); if (r < 0) goto fail; /* At the end? Then it's hours, minutes and seconds */ if (*t == 0) goto finish; r = -EINVAL; goto fail; null_hour: r = const_chain(0, &h); if (r < 0) goto fail; r = const_chain(0, &m); if (r < 0) goto fail; null_second: r = const_chain(0, &s); if (r < 0) goto fail; finish: *p = t; c->hour = h; c->minute = m; c->second = s; return 0; fail: free_chain(h); free_chain(m); free_chain(s); return r; }
static int parse_calendar_time(const char **p, CalendarSpec *c) { CalendarComponent *h = NULL, *m = NULL, *s = NULL; const char *t; int r; assert(p); assert(*p); assert(c); t = *p; /* If no time is specified at all, then this means 00:00:00 */ if (*t == 0) goto null_hour; r = parse_chain(&t, false, &h); if (r < 0) goto fail; if (*t != ':') { r = -EINVAL; goto fail; } t++; r = parse_chain(&t, false, &m); if (r < 0) goto fail; /* Already at the end? Then it's hours and minutes, and seconds are 0 */ if (*t == 0) goto null_second; if (*t != ':') { r = -EINVAL; goto fail; } t++; r = parse_chain(&t, true, &s); if (r < 0) goto fail; /* At the end? Then it's hours, minutes and seconds */ if (*t == 0) goto finish; r = -EINVAL; goto fail; null_hour: r = const_chain(0, &h); if (r < 0) goto fail; r = const_chain(0, &m); if (r < 0) goto fail; null_second: r = const_chain(0, &s); if (r < 0) goto fail; finish: *p = t; c->hour = h; c->minute = m; c->microsecond = s; return 0; fail: free_chain(h); free_chain(m); free_chain(s); return r; }
static int parse_date(const char **p, CalendarSpec *c) { const char *t; int r; CalendarComponent *first, *second, *third; assert(p); assert(*p); assert(c); t = *p; if (*t == 0) return 0; r = parse_chain(&t, &first); if (r < 0) return r; /* Already the end? A ':' as separator? In that case this was a time, not a date */ if (*t == 0 || *t == ':') { free_chain(first); return 0; } if (*t != '-') { free_chain(first); return -EINVAL; } t++; r = parse_chain(&t, &second); if (r < 0) { free_chain(first); return r; } /* Got two parts, hence it's month and day */ if (*t == ' ' || *t == 0) { *p = t + strspn(t, " "); c->month = first; c->day = second; return 0; } if (*t != '-') { free_chain(first); free_chain(second); return -EINVAL; } t++; r = parse_chain(&t, &third); if (r < 0) { free_chain(first); free_chain(second); return r; } /* Got tree parts, hence it is year, month and day */ if (*t == ' ' || *t == 0) { *p = t + strspn(t, " "); c->year = first; c->month = second; c->day = third; return 0; } free_chain(first); free_chain(second); free_chain(third); return -EINVAL; }
static int parse_date(const char **p, CalendarSpec *c) { const char *t; int r; CalendarComponent *first, *second, *third; assert(p); assert(*p); assert(c); t = *p; if (*t == 0) return 0; /* @TIMESTAMP — UNIX time in seconds since the epoch */ if (*t == '@') { unsigned long value; time_t time; r = parse_one_number(t + 1, &t, &value); if (r < 0) return r; time = value; if ((unsigned long) time != value) return -ERANGE; r = calendarspec_from_time_t(c, time); if (r < 0) return r; *p = t; return 1; /* finito, don't parse H:M:S after that */ } r = parse_chain(&t, false, &first); if (r < 0) return r; /* Already the end? A ':' as separator? In that case this was a time, not a date */ if (IN_SET(*t, 0, ':')) { free_chain(first); return 0; } if (*t == '~') c->end_of_month = true; else if (*t != '-') { free_chain(first); return -EINVAL; } t++; r = parse_chain(&t, false, &second); if (r < 0) { free_chain(first); return r; } /* Got two parts, hence it's month and day */ if (IN_SET(*t, 0, ' ')) { *p = t + strspn(t, " "); c->month = first; c->day = second; return 0; } else if (c->end_of_month) { free_chain(first); free_chain(second); return -EINVAL; } if (*t == '~') c->end_of_month = true; else if (*t != '-') { free_chain(first); free_chain(second); return -EINVAL; } t++; r = parse_chain(&t, false, &third); if (r < 0) { free_chain(first); free_chain(second); return r; } /* Got three parts, hence it is year, month and day */ if (IN_SET(*t, 0, ' ')) { *p = t + strspn(t, " "); c->year = first; c->month = second; c->day = third; return 0; } free_chain(first); free_chain(second); free_chain(third); return -EINVAL; }