Beispiel #1
0
/* 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;
}
Beispiel #2
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;
}
Beispiel #3
0
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;
}