/* extended duration reader */ static int dt_io_strpdtrnd(struct __strpdtdur_st_s *st, const char *str) { char *sp = NULL; struct strpd_s d = strpd_initialiser(); struct dt_spec_s s = spec_initialiser(); struct dt_dtdur_s payload = {(dt_dtdurtyp_t)DT_DURUNK}; bool negp = false; bool coclp = true; if (dt_io_strpdtdur(st, str) >= 0) { return 0; } /* check for co-classes */ if (*str == '/') { coclp = true; str++; } /* check if there's a sign + or - */ if (*str == '-') { negp = true; str++; } else if (*str == '+') { str++; } /* try weekdays, set up s */ s.spfl = DT_SPFL_S_WDAY; s.abbr = DT_SPMOD_NORM; if (__strpd_card(&d, str, s, &sp) >= 0) { #if defined HAVE_ANON_STRUCTS_INIT payload.d = (struct dt_ddur_s){ DT_DURYMCW, .neg = negp, .cocl = coclp, .ymcw.w = d.w, }; #else payload.d.durtyp = DT_DURYMCW; payload.d.neg = negp; payload.d.cocl = coclp; payload.d.ymcw.w = d.w; #endif goto out; } /* try months, set up s */ s.spfl = DT_SPFL_S_MON; s.abbr = DT_SPMOD_NORM; if (__strpd_card(&d, str, s, &sp) >= 0) { #if defined HAVE_ANON_STRUCTS_INIT payload.d = (struct dt_ddur_s){ DT_DURYMD, .neg = negp, .ymd.m = d.m, }; #else payload.d.durtyp = DT_DURYMD; payload.d.neg = negp; payload.d.ymd.m = d.m; #endif goto out; } /* bugger */ st->istr = str; return -1; out: st->sign = 0; st->cont = NULL; return __add_dur(st, payload); }
DEFUN struct dt_d_s __strpd_std(const char *str, char **ep) { /* code dupe, see __strpdt_std() */ struct dt_d_s res; struct strpd_s d; const char *sp; if ((sp = str) == NULL) { goto out; } d = strpd_initialiser(); /* read the year */ if ((d.y = strtoi_lim(sp, &sp, DT_MIN_YEAR, DT_MAX_YEAR)) < 0 || *sp++ != '-') { goto f****d; } /* check for ywd dates */ if (UNLIKELY(*sp == 'W')) { /* brilliant */ if ((sp++, d.c = strtoi_lim(sp, &sp, 0, 53)) < 0 || *sp++ != '-') { goto f****d; } d.flags.c_wcnt_p = 1; d.flags.wk_cnt = YWD_ISOWK_CNT; goto dow; } /* read the month */ if ((d.m = strtoi_lim(sp, &sp, 0, GREG_MONTHS_P_YEAR)) < 0 || *sp++ != '-') { goto f****d; } /* read the day or the count */ if ((d.d = strtoi_lim(sp, &sp, 0, 31)) < 0) { /* didn't work, f**k off */ goto f****d; } /* check the date type */ switch (*sp) { case '-': /* it is a YMCW date */ if ((d.c = d.d) > 5) { /* nope, it was bollocks */ break; } d.d = 0; sp++; dow: if ((d.w = strtoi_lim(sp, &sp, 0, GREG_DAYS_P_WEEK)) < 0) { /* didn't work, f**k off */ goto f****d; } break; case 'B': /* it's a bizda/YMDU before ultimo date */ d.flags.ab = BIZDA_BEFORE; case 'b': /* it's a bizda/YMDU after ultimo date */ d.flags.bizda = 1; d.b = d.d; d.d = 0; sp++; break; default: /* we don't care */ break; } /* guess what we're doing */ res = __guess_dtyp(d); out: if (ep != NULL) { *ep = (char*)sp; } return res; f****d: if (ep != NULL) { *ep = (char*)str; } return dt_d_initialiser(); }