#include "prjlibs-include/standards.h"
#include <time.h>
#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);
}
syntax highlighted by Code2HTML, v. 0.9.1