/* skip system */ static int skipp(__skipspec_t ss, struct dt_dt_s dt) { dt_dow_t dow; /* common case first */ if (ss == 0) { return 0; } dow = dt_get_wday(dt.d); /* just check if the bit in the bitset `skip' is set */ return (ss & (1 << dow)) != 0; }
static struct dt_d_s dround_ddur(struct dt_d_s d, struct dt_ddur_s dur, bool nextp) { switch (dur.durtyp) { unsigned int tgt; bool forw; case DT_DURD: if (dur.dv > 0) { tgt = dur.dv; forw = true; } else if (dur.dv < 0) { tgt = -dur.dv; forw = false; } else { /* user is an idiot */ break; } switch (d.typ) { unsigned int mdays; case DT_YMD: if ((forw && d.ymd.d < tgt) || (!forw && d.ymd.d > tgt)) { /* no month or year adjustment */ ; } else if (d.ymd.d == tgt && !nextp) { /* we're ON the date already and no * next/prev date is requested */ ; } else if (forw) { if (LIKELY(d.ymd.m < GREG_MONTHS_P_YEAR)) { d.ymd.m++; } else { d.ymd.m = 1; d.ymd.y++; } } else { if (UNLIKELY(--d.ymd.m < 1)) { d.ymd.m = GREG_MONTHS_P_YEAR; d.ymd.y--; } } /* get ultimo */ mdays = __get_mdays(d.ymd.y, d.ymd.m); if (UNLIKELY(tgt > mdays)) { tgt = mdays; } /* final assignment */ d.ymd.d = tgt; break; default: break; } break; case DT_DURBD: /* bizsis only work on bizsidurs atm */ if (dur.dv > 0) { tgt = dur.dv; forw = true; } else if (dur.dv < 0) { tgt = -dur.dv; forw = false; } else { /* user is an idiot */ break; } switch (d.typ) { unsigned int bdays; case DT_BIZDA: if ((forw && d.bizda.bd < tgt) || (!forw && d.bizda.bd > tgt)) { /* no month or year adjustment */ ; } else if (d.bizda.bd == tgt && !nextp) { /* we're ON the date already and no * next/prev date is requested */ ; } else if (forw) { if (LIKELY(d.bizda.m < GREG_MONTHS_P_YEAR)) { d.bizda.m++; } else { d.bizda.m = 1; d.bizda.y++; } } else { if (UNLIKELY(--d.bizda.m < 1)) { d.bizda.m = GREG_MONTHS_P_YEAR; d.bizda.y--; } } /* get ultimo */ bdays = __get_bdays(d.bizda.y, d.bizda.m); if (UNLIKELY(tgt > bdays)) { tgt = bdays; } /* final assignment */ d.bizda.bd = tgt; break; default: break; } break; case DT_DURYMD: switch (d.typ) { unsigned int mdays; case DT_YMD: tgt = dur.ymd.m; forw = !dt_dur_neg_p(dur); if ((forw && d.ymd.m < tgt) || (!forw && d.ymd.m > tgt)) { /* no year adjustment */ ; } else if (d.ymd.m == tgt && !nextp) { /* we're IN the month already and no * next/prev date is requested */ ; } else if (forw) { /* years don't wrap around */ d.ymd.y++; } else { /* years don't wrap around */ d.ymd.y--; } /* final assignment */ d.ymd.m = tgt; /* fixup ultimo mismatches */ mdays = __get_mdays(d.ymd.y, d.ymd.m); if (UNLIKELY(d.ymd.d > mdays)) { d.ymd.d = mdays; } break; default: break; } break; case DT_DURYMCW: { struct dt_d_s tmp; unsigned int wday; signed int diff; forw = !dt_dur_neg_p(dur); tgt = dur.ymcw.w; tmp = dt_dconv(DT_DAISY, d); wday = dt_get_wday(tmp); diff = (signed)tgt - (signed)wday; if ((forw && wday < tgt) || (!forw && wday > tgt)) { /* nothing to do */ ; } else if (wday == tgt && !nextp) { /* we're on WDAY already, do fuckall */ ; } else if (forw) { /* week wrap */ diff += 7; } else { /* week wrap */ diff -= 7; } /* final assignment */ tmp.daisy += diff; d = dt_dconv(d.typ, tmp); break; } case DT_DURWK: if (dur.dv > 0) { tgt = dur.dv; forw = true; } else if (dur.dv < 0) { tgt = -dur.dv; forw = false; } else { /* user is an idiot */ break; } switch (d.typ) { unsigned int nw; case DT_YWD: if ((forw && d.ywd.c < tgt) || (!forw && d.ywd.c > tgt)) { /* no year adjustment */ ; } else if (d.ywd.c == tgt && !nextp) { /* we're IN the week already and no * next/prev date is requested */ ; } else if (forw) { /* years don't wrap around */ d.ywd.y++; } else { /* years don't wrap around */ d.ywd.y--; } /* final assignment */ d.ywd.c = tgt; /* fixup ultimo mismatches */ nw = __get_isowk(d.ywd.y); if (UNLIKELY(d.ywd.c > nw)) { d.ywd.c = nw; } break; default: break; } break; default: break; } return d; }
static bool dexkv_matches_p(const_dexkv_t dkv, struct dt_dt_s d) { signed int cmp; bool res; if (dkv->sp.spfl == DT_SPFL_N_STD) { if ((cmp = __cmp(d, dkv->d)) == -2) { return false; } switch (dkv->op) { case OP_UNK: case OP_EQ: res = cmp == 0; break; case OP_LT: res = cmp < 0; break; case OP_LE: res = cmp <= 0; break; case OP_GT: res = cmp > 0; break; case OP_GE: res = cmp >= 0; break; case OP_NE: res = cmp != 0; break; case OP_TRUE: res = true; break; default: res = false; break; } return res; } /* otherwise it's stuff that uses the S slot */ switch (dkv->sp.spfl) { case DT_SPFL_N_YEAR: cmp = dt_get_year(d.d); break; case DT_SPFL_N_MON: case DT_SPFL_S_MON: cmp = dt_get_mon(d.d); break; case DT_SPFL_N_DCNT_MON: cmp = dt_get_mday(d.d); break; case DT_SPFL_N_DCNT_WEEK: case DT_SPFL_S_WDAY: cmp = dt_get_wday(d.d); break; case DT_SPFL_N_WCNT_MON: /* exotic function, needs extern'ing */ cmp = /*dt_get_count(d)*/0; break; case DT_SPFL_N_DCNT_YEAR: cmp = dt_get_yday(d.d); break; case DT_SPFL_N_WCNT_YEAR: /* %C/%W week count */ switch (d.d.typ) { case DT_YMD: if (dkv->sp.cnt_weeks_iso) { cmp = __ymd_get_wcnt_iso(d.d.ymd); } else { cmp = __ymd_get_wcnt( d.d.ymd, dkv->sp.cnt_wdays_from); } break; case DT_YMCW: cmp = __ymcw_get_yday(d.d.ymcw); break; default: cmp = 0; break; } break; case DT_SPFL_N_STD: default: return false; } /* now do the actual comparison */ switch (dkv->op) { case OP_EQ: res = dkv->s == cmp; break; case OP_LT: res = dkv->s < cmp; break; case OP_LE: res = dkv->s <= cmp; break; case OP_GT: res = dkv->s > cmp; break; case OP_GE: res = dkv->s >= cmp; break; case OP_NE: res = dkv->s != cmp; break; case OP_TRUE: res = true; break; default: case OP_UNK: res = false; break; } return res; }