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;
}
Exemple #2
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);
}