DEFUN int __strpdt_card(struct strpdt_s *d, const char *sp, struct dt_spec_s s, char **ep) { int res = 0; switch (s.spfl) { default: case DT_SPFL_UNK: res = -1; break; case DT_SPFL_N_DSTD: case DT_SPFL_N_YEAR: case DT_SPFL_N_MON: case DT_SPFL_N_DCNT_MON: case DT_SPFL_N_DCNT_WEEK: case DT_SPFL_N_DCNT_YEAR: case DT_SPFL_N_WCNT_MON: case DT_SPFL_N_WCNT_YEAR: case DT_SPFL_S_WDAY: case DT_SPFL_S_MON: case DT_SPFL_S_QTR: case DT_SPFL_N_QTR: res = __strpd_card(&d->sd, sp, s, ep); goto out_direct; case DT_SPFL_N_TSTD: case DT_SPFL_N_HOUR: case DT_SPFL_N_MIN: case DT_SPFL_N_SEC: case DT_SPFL_N_NANO: case DT_SPFL_S_AMPM: res = __strpt_card(&d->st, sp, s, ep); goto out_direct; case DT_SPFL_N_EPOCH: /* read over @ */ if (UNLIKELY(*sp == '@')) { sp++; } d->i = strtoi(sp, &sp); break; case DT_SPFL_N_ZDIFF: { const char *tp; if ((d->zdiff = try_zone(sp, &tp)) || tp > sp) { d->zngvn = 1; } sp = tp; break; } case DT_SPFL_LIT_PERCENT: if (*sp++ != '%') { res = -1; } break; case DT_SPFL_LIT_TAB: if (*sp++ != '\t') { res = -1; } break; case DT_SPFL_LIT_NL: if (*sp++ != '\n') { res = -1; } break; } /* assign end pointer */ if (ep != NULL) { *ep = (char*)sp; } out_direct: return res; }
/* 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); }