#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