#include "prjlibs-include/standards.h" #include #include "skalibs/include/stddjb.h" #include "prjlibs-include/constants.h" #include "runwhen.h" extern char const* PROG; static void die_malformed(char const*) gccattr_noreturn; static void die_malformed(char const* stamp) { strerr_die3x(100, PROG, ": malformed timestamp: ", stamp); } static struct taia const zero=TAIA_ZERO; void rw_scan(struct taia* stamp, char const* text) { unsigned int i, scale; uint64 u; char const* x; switch (text[0]) { case '$': x=env_get(text+1); if (x==null) die_malformed(text); text=x; i=tain_scan(text, stamp); break; case '@': ++text; i=tain_scan(text, stamp); break; case 'n': i=1; taia_now(stamp); break; case 'd': ++text; i=uint64_scan(text, &u); scale=1; switch (text[i]) { case 'W': scale*= 7; case 'd': scale*=24; case 'H': scale*=60; case 'M': scale*=60; case 'S': break; default: die_malformed(text); } ++i; if (u*scale/scale!=u) strerr_die2x(100, PROG, ": arithmetic overflow"); u*=scale; *stamp=zero; tai_u64(taia_secp(stamp), u); break; case 't': ++text; i=uint64_scan(text, &u); *stamp=zero; tai_unix(taia_secp(stamp), u); break; case 'i': { struct caltime ct; struct tm tm; time_t t; struct timeval tv; ++text; i=caltime_scan(text, &ct); tm.tm_year=ct.date.year-1900; tm.tm_mon =ct.date.month-1; tm.tm_mday=ct.date.day; tm.tm_hour=ct.hour; tm.tm_min =ct.minute; tm.tm_sec =ct.second; tm.tm_isdst=-1; t=mktime(&tm);; if (t==(time_t)-1) strerr_die2x(100, PROG, ": timestamp out of range"); tv.tv_sec=t; tv.tv_usec=0; taia_from_timeval(stamp, &tv); break; } default: die_malformed(text); } if (i==0 || text[i]!='\0') die_malformed(text); }