static int parse_chain(const char **p, CalendarComponent **c) { const char *t; CalendarComponent *cc = NULL; int r; assert(p); assert(c); t = *p; if (t[0] == '*') { *p = t + 1; *c = NULL; return 0; } r = prepend_component(&t, &cc); if (r < 0) { free_chain(cc); return r; } *p = t; *c = cc; return 0; }
static int parse_chain(const char **p, bool usec, CalendarComponent **c) { const char *t; CalendarComponent *cc = NULL; int r; assert(p); assert(c); t = *p; if (t[0] == '*') { if (usec) { r = const_chain(0, c); if (r < 0) return r; (*c)->repeat = USEC_PER_SEC; } else *c = NULL; *p = t + 1; return 0; } r = prepend_component(&t, usec, 0, &cc); if (r < 0) { free_chain(cc); return r; } *p = t; *c = cc; return 0; }
static int prepend_component(const char **p, bool usec, unsigned nesting, CalendarComponent **c) { int r, start, stop = -1, repeat = 0; CalendarComponent *cc; const char *e = *p; assert(p); assert(c); if (nesting > CALENDARSPEC_COMPONENTS_MAX) return -ENOBUFS; r = parse_component_decimal(&e, usec, &start); if (r < 0) return r; if (e[0] == '.' && e[1] == '.') { e += 2; r = parse_component_decimal(&e, usec, &stop); if (r < 0) return r; repeat = usec ? USEC_PER_SEC : 1; } if (*e == '/') { e++; r = parse_component_decimal(&e, usec, &repeat); if (r < 0) return r; if (repeat == 0) return -ERANGE; } if (!IN_SET(*e, 0, ' ', ',', '-', '~', ':')) return -EINVAL; cc = new0(CalendarComponent, 1); if (!cc) return -ENOMEM; cc->start = start; cc->stop = stop; cc->repeat = repeat; cc->next = *c; *p = e; *c = cc; if (*e ==',') { *p += 1; return prepend_component(p, usec, nesting + 1, c); } return 0; }
static int prepend_component(const char **p, bool usec, CalendarComponent **c) { unsigned long start, stop = -1, repeat = 0; CalendarComponent *cc; int r; const char *e; assert(p); assert(c); e = *p; r = parse_component_decimal(&e, usec, &start); if (r < 0) return r; if (e[0] == '.' && e[1] == '.') { e += 2; r = parse_component_decimal(&e, usec, &stop); if (r < 0) return r; repeat = usec ? USEC_PER_SEC : 1; } if (*e == '/') { e++; r = parse_component_decimal(&e, usec, &repeat); if (r < 0) return r; if (repeat == 0) return -ERANGE; } if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != '~' && *e != ':') return -EINVAL; cc = new0(CalendarComponent, 1); if (!cc) return -ENOMEM; cc->start = start; cc->stop = stop; cc->repeat = repeat; cc->next = *c; *p = e; *c = cc; if (*e ==',') { *p += 1; return prepend_component(p, usec, c); } return 0; }
static int prepend_component(const char **p, CalendarComponent **c) { unsigned long value, repeat = 0; char *e = NULL, *ee = NULL; CalendarComponent *cc; assert(p); assert(c); errno = 0; value = strtoul(*p, &e, 10); if (errno != 0) return -errno; if (e == *p) return -EINVAL; if ((unsigned long) (int) value != value) return -ERANGE; if (*e == '/') { repeat = strtoul(e+1, &ee, 10); if (errno != 0) return -errno; if (ee == e+1) return -EINVAL; if ((unsigned long) (int) repeat != repeat) return -ERANGE; if (repeat <= 0) return -ERANGE; e = ee; } if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != ':') return -EINVAL; cc = new0(CalendarComponent, 1); if (!cc) return -ENOMEM; cc->value = value; cc->repeat = repeat; cc->next = *c; *p = e; *c = cc; if (*e ==',') { *p += 1; return prepend_component(p, c); } return 0; }
static int prepend_component(const char **p, bool usec, CalendarComponent **c) { unsigned long value, repeat = 0; CalendarComponent *cc; int r; const char *e; assert(p); assert(c); e = *p; r = parse_component_decimal(&e, usec, &value); if (r < 0) return r; if (*e == '/') { e++; r = parse_component_decimal(&e, usec, &repeat); if (r < 0) return r; if (repeat == 0) return -ERANGE; } if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != ':') return -EINVAL; cc = new0(CalendarComponent, 1); if (!cc) return -ENOMEM; cc->value = value; cc->repeat = repeat; cc->next = *c; *p = e; *c = cc; if (*e ==',') { *p += 1; return prepend_component(p, usec, c); } return 0; }