예제 #1
0
/* 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);
}
예제 #2
0
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();
}