static dt_dttyp_t determine_durtype(struct dt_dt_s d1, struct dt_dt_s d2, durfmt_t f) { /* the type-multiplication table looks like: * * - D T DT * D d x d * T x t x * DT d x s * * where d means a ddur type, t a tdur type and s is DT_SEXY */ if ((dt_sandwich_only_d_p(d1) || dt_sandwich_only_d_p(d2)) && (dt_sandwich_only_t_p(d1) || dt_sandwich_only_t_p(d2))) { ; } else if (dt_sandwich_only_d_p(d1) || dt_sandwich_only_d_p(d2)) { if (f.has_week && (f.has_mon || f.has_year)) { return (dt_dttyp_t)DT_YMCW; } else if (f.has_mon || f.has_year) { return (dt_dttyp_t)DT_YMD; } else if (f.has_day && f.has_biz) { return (dt_dttyp_t)DT_BIZSI; } else if (f.has_day || f.has_week || f.flags == 0) { return (dt_dttyp_t)DT_DAISY; } else { return (dt_dttyp_t)DT_MD; } } else if ((dt_sandwich_only_t_p(d1) && dt_sandwich_only_t_p(d2)) || (dt_sandwich_p(d1) && dt_sandwich_p(d2))) { return (dt_dttyp_t)DT_SEXY; } return DT_UNK; }
static size_t __strfdt_xdn(char *buf, size_t bsz, struct dt_dt_s that) { double dn; switch (that.d.typ) { case DT_JDN: dn = (double)that.d.jdn; break; case DT_LDN: dn = (double)that.d.ldn; if (dt_sandwich_only_d_p(that)) { return snprintf(buf, bsz, "%.0f", dn); } break; default: return 0; } if (dt_sandwich_p(that)) { unsigned int ss = __secs_since_midnight(that.t); dn += (double)ss / (double)SECS_PER_DAY; } return snprintf(buf, bsz, "%.6f", dn); }
static int __cmp(struct dt_dt_s stream, struct dt_dt_s cell) { /* special promoting/demoting version of dt_dtcmp() * if CELL is d-only or t-only, demote STREAM */ if (dt_sandwich_only_d_p(cell)) { return dt_dcmp(stream.d, cell.d); } else if (dt_sandwich_only_t_p(cell)) { return dt_tcmp(stream.t, cell.t); } return dt_dtcmp(stream, cell); }
/** * Return a dt object that forgot about DT's zone and uses ZONE instead. */ DEFUN struct dt_dt_s dtz_forgetz(struct dt_dt_s d, zif_t zone) { struct dt_dt_s res; dt_ssexy_t d_unix; if (dt_sandwich_only_d_p(d) || dt_sandwich_only_t_p(d)) { return d; } /* convert date/time part to unix stamp */ d_unix = ____to_unix_epoch(d); d_unix = zif_utc_time(zone, d_unix); /* convert the date part back */ if (d.typ > (dt_dttyp_t)DT_DUNK && d.typ < (dt_dttyp_t)DT_NDTYP) { int32_t sexy = __pos_mod(d_unix, 86400); /* temporarily go daisy */ res.d.typ = DT_DAISY; res.d.daisy = d_unix / 86400 + DAISY_UNIX_BASE; res.d = dt_dconv(d.d.typ, res.d); /* set the other flags too */ res.sandwich = d.sandwich; res.dur = 0; res.neg = 0; /* convert the time part back */ res.t.hms.s = sexy % 60; res.t.hms.m = (sexy % 3600) / 60; res.t.hms.h = sexy / 3600; res.t.hms.ns = d.t.hms.ns; res.t.typ = DT_HMS; res.t.dur = 0; res.t.neg = 0; res.t.carry = 0; } else if (d.typ == DT_SEXY) { res.typ = DT_SEXY; res.sandwich = 0; res.dur = 0; res.neg = 0; res.sxepoch = d_unix; } else { res = dt_dt_initialiser(); } return res; }
static inline struct dt_dt_s dt_conv_to_sexy(struct dt_dt_s dt) { if (dt.typ == DT_SEXY) { return dt; } else if (dt_sandwich_only_t_p(dt)) { dt.sxepoch = (dt.t.hms.h * 60 + dt.t.hms.m) * 60 + dt.t.hms.s; } else if (dt_sandwich_p(dt) || dt_sandwich_only_d_p(dt)) { dt.sxepoch = __to_unix_epoch(dt); } else { dt = dt_dt_initialiser(); } /* make sure we hand out sexies */ dt.typ = DT_SEXY; return dt; }
static inline dt_ssexy_t __to_gps_epoch(struct dt_dt_s dt) { if (dt.typ == DT_SEXY) { /* no way to find out, is there */ return dt.sexy; } else if (dt_sandwich_p(dt) || dt_sandwich_only_d_p(dt)) { dt_daisy_t d = dt_conv_to_daisy(dt.d); dt_ssexy_t res = (d - DAISY_GPS_BASE) * SECS_PER_DAY; if (dt_sandwich_p(dt)) { res += (dt.t.hms.h * 60 + dt.t.hms.m) * 60 + dt.t.hms.s; } return res; } return 0; }
static inline dt_ssexy_t __to_unix_epoch(struct dt_dt_s dt) { /* daisy is competing with the prevalent unix epoch, this is the offset */ if (dt.typ == DT_SEXY) { /* no way to find out, is there */ return dt.sexy; } else if (dt_sandwich_p(dt) || dt_sandwich_only_d_p(dt)) { dt_daisy_t d = dt_conv_to_daisy(dt.d); dt_ssexy_t res = (d - DAISY_UNIX_BASE) * SECS_PER_DAY; if (dt_sandwich_p(dt)) { res += (dt.t.hms.h * 60 + dt.t.hms.m) * 60 + dt.t.hms.s; } return res; } return 0; }
static int test_d_only_no_fmt(void) { static const char str[] = "2012-03-28"; struct dt_dt_s d; int res = 0; /* 2012-03-28 (using no format) */ fprintf(stderr, "testing %s ...\n", str); d = dt_strpdt(str, NULL, NULL); CHECK(d.sandwich, " IS A SANDWICH ... but should be not\n"); CHECK(!dt_sandwich_only_d_p(d), " TYPE is not a d-only\n"); CHECK(d.d.typ != DT_YMD, " TYPE DIFFERS %u ... should be %u\n", (unsigned int)d.d.typ, (unsigned int)DT_YMD); CHECK(d.t.u, " TIME COMPONENT NOT NAUGHT %" PRIu64 "\n", (uint64_t)d.t.u); CHECK(d.dur, " DURATION BIT SET\n"); CHECK(d.neg, " NEGATED BIT SET\n"); CHECK(d.t.dur, " TIME DURATION BIT SET\n"); CHECK(d.t.neg, " TIME NEGATED BIT SET\n"); CHECK(d.d.ymd.y != 2012, " YEAR %u ... should be 2012\n", (unsigned int)d.d.ymd.y); CHECK(d.d.ymd.m != 3, " MONTH %u ... should be 3\n", (unsigned int)d.d.ymd.m); CHECK(d.d.ymd.d != 28, " DAY %u ... should be 28\n", (unsigned int)d.d.ymd.d); /* make sure the padding leaves no garbage, not fatal tho */ CHECK_RES(res, d.d.ymd.u & ~0x1fffff, " PADDING NOT NAUGHT %x\n", (unsigned int)(d.d.ymd.u & ~0x1fffff)); return res; }
static void proc_line(struct prln_ctx_s ctx, char *line, size_t llen) { struct dt_dt_s d; do { char buf[64U]; char *sp, *tp; char *bp = buf; const char *const ep = buf + sizeof(buf); /* find first occurrence then */ d = dt_io_find_strpdt2( line, llen, ctx.ndl, &sp, &tp, ctx.fromz); /* print line, first thing */ safe_write(ctx.outfd, line, llen); /* extend by separator */ *bp++ = '\001'; /* check if line matches */ if (!dt_unk_p(d)) { /* match! */ if (!dt_sandwich_only_t_p(d)) { bp += dt_strfdt(bp, ep - bp, "%F", d); } *bp++ = '\001'; if (!dt_sandwich_only_d_p(d)) { bp += dt_strfdt(bp, ep - bp, "%T", d); } } else { /* just two empty fields then, innit? */ *bp++ = '\001'; } /* finalise the line and print */ *bp++ = '\n'; safe_write(ctx.outfd, buf, bp - buf); } while (0); return; }
int main(int argc, char *argv[]) { static struct dt_dtdur_s ite_p1; yuck_t argi[1U]; struct dt_dt_s tmp; char **ifmt; size_t nifmt; char *ofmt; dt_dttyp_t tgttyp; int rc = 0; struct dseq_clo_s clo = { .ite = &ite_p1, .nite = 1, .altite = NULL, .naltite = 0, .ss = 0, .dir = 0, .flags = 0, }; if (yuck_parse(argi, argc, argv)) { rc = 1; goto out; } /* assign ofmt/ifmt */ ofmt = argi->format_arg; if (argi->backslash_escapes_flag) { dt_io_unescape(ofmt); } nifmt = argi->input_format_nargs; ifmt = argi->input_format_args; if (argi->from_locale_arg) { setilocale(argi->from_locale_arg); } if (argi->locale_arg) { setflocale(argi->locale_arg); } if (argi->base_arg) { struct dt_dt_s base = dt_strpdt(argi->base_arg, NULL, NULL); dt_set_base(base); } for (size_t i = 0; i < argi->skip_nargs; i++) { clo.ss = set_skip(clo.ss, argi->skip_args[i]); } if (argi->alt_inc_arg) { struct __strpdtdur_st_s st = __strpdtdur_st_initialiser(); do { if (dt_io_strpdtdur(&st, argi->alt_inc_arg) < 0) { if (!argi->quiet_flag) { error("Error: \ cannot parse duration string `%s'", argi->alt_inc_arg); } rc = 1; goto out; } } while (__strpdtdur_more_p(&st)); /* assign values */ clo.altite = st.durs; clo.naltite = st.ndurs; } switch (argi->nargs) { struct dt_dt_s fst, lst; default: yuck_auto_help(argi); rc = 1; goto out; case 2: lst = dt_io_strpdt(argi->args[1U], ifmt, nifmt, NULL); if (dt_unk_p(lst)) { if (!argi->quiet_flag) { dt_io_warn_strpdt(argi->args[1U]); } rc = 1; goto out; } else if (UNLIKELY(lst.fix) && !argi->quiet_flag) { rc = 2; } /* fallthrough */ case 1: fst = dt_io_strpdt(argi->args[0U], ifmt, nifmt, NULL); if (dt_unk_p(fst)) { if (!argi->quiet_flag) { dt_io_warn_strpdt(argi->args[0U]); } rc = 1; goto out; } else if (UNLIKELY(fst.fix) && !argi->quiet_flag) { rc = 2; } /* check the input arguments and do the sane thing now * if it's all dates, use DURD iterator * if it's all times, use DURS/DURM/DURH iterators * if one of them is a dt, promote the other */ if (dt_sandwich_only_d_p(fst)) { /* emulates old dseq(1) */ if (argi->nargs == 1U) { lst.d = dt_date(fst.d.typ); dt_make_d_only(&lst, fst.d.typ); } clo.ite->d = dt_make_ddur(DT_DURD, 1); } else if (dt_sandwich_only_t_p(fst)) { /* emulates old tseq(1) */ if (argi->nargs == 1U) { lst.t = dt_time(); dt_make_t_only(&lst, DT_HMS); } } else if (dt_sandwich_p(fst)) { if (argi->nargs == 1U) { lst = dt_datetime(fst.typ); dt_make_sandwich(&lst, fst.d.typ, DT_HMS); } clo.ite->d = dt_make_ddur(DT_DURD, 1); } else { error("\ don't know how to handle single argument case"); rc = 1; goto out; } goto make_compat; case 3: { struct __strpdtdur_st_s st = __strpdtdur_st_initialiser(); /* get lower bound */ fst = dt_io_strpdt(argi->args[0U], ifmt, nifmt, NULL); if (dt_unk_p(fst)) { if (!argi->quiet_flag) { dt_io_warn_strpdt(argi->args[0U]); } rc = 1; goto out; } else if (UNLIKELY(fst.fix) && !argi->quiet_flag) { rc = 2; } /* get increment */ do { if (dt_io_strpdtdur(&st, argi->args[1U]) < 0) { error("Error: \ cannot parse duration string `%s'", argi->args[1U]); rc = 1; goto out; } } while (__strpdtdur_more_p(&st)); /* assign values */ clo.ite = st.durs; clo.nite = st.ndurs; clo.flags |= CLO_FL_FREE_ITE; /* get upper bound */ lst = dt_io_strpdt(argi->args[2U], ifmt, nifmt, NULL); if (dt_unk_p(lst)) { if (!argi->quiet_flag) { dt_io_warn_strpdt(argi->args[2U]); } rc = 1; goto out; } else if (UNLIKELY(lst.fix) && !argi->quiet_flag) { rc = 2; } goto make_compat; } make_compat: if (LIKELY(fst.typ == lst.typ)) { clo.fst = fst; clo.lst = lst; } else { clo.fst = fst; clo.lst = dt_dtconv(fst.typ, lst); } break; } /* promote the args maybe */ if ((dt_sandwich_only_d_p(clo.fst) && dt_sandwich_only_t_p(clo.lst)) || (dt_sandwich_only_t_p(clo.fst) && dt_sandwich_only_d_p(clo.lst))) { error("\ cannot mix dates and times as arguments"); rc = 1; goto out; } else if (dt_sandwich_only_d_p(clo.fst) && dt_sandwich_p(clo.lst)) {