/* This file is in the public domain. */ #include #include "ctype.h" #include "time.h" TIMEINTVL timeintvl_parse(const char *s, void (*err)(const char *, ...)) { struct { char letter; unsigned int val; int have; } specs[] = { { 'y' }, #define PTI_SX_Y 0 { 'm' }, #define PTI_SX_M1 1 { 'w' }, #define PTI_SX_W 2 { 'd' }, #define PTI_SX_D 3 { 'h' }, #define PTI_SX_H 4 { 'm' }, #define PTI_SX_M2 5 { 's' } }; #define PTI_SX_S 6 #define PTI_N_SPECS (sizeof(specs)/sizeof(specs[0])) const char *s0; int sx; unsigned long int ulv; unsigned int uv; char *e; for (sx=PTI_N_SPECS-1;sx>=0;sx--) { specs[sx].have = 0; specs[sx].val = 0; } s0 = s; sx = 0; while (1) { while (*s && UCisspace(*s)) s ++; if (! *s) break; ulv = strtoul(s,&e,10); if (e == s) (*err)("%s: bad number",s0); if (! *e) (*err)("%s: missing unit",s0); uv = ulv; if (uv != ulv) (*err)("%s: out-of-range number",s0); while (1) { if (sx >= PTI_N_SPECS) (*err)("%s: bad unit `%c'",s0,*e); if (*e == specs[sx].letter) break; sx ++; } specs[sx].have = 1; specs[sx].val = uv; sx ++; s = e + 1; } if ( specs[PTI_SX_M1].have && !specs[PTI_SX_M2].have && !specs[PTI_SX_W].have && !specs[PTI_SX_D].have && !specs[PTI_SX_H].have ) { if (specs[PTI_SX_Y].have && !specs[PTI_SX_S].have) { /* do nothing, already correct */ } else if (specs[PTI_SX_S].have && !specs[PTI_SX_Y].have) { specs[PTI_SX_M2].have = 1; specs[PTI_SX_M2].val = specs[PTI_SX_M1].val; specs[PTI_SX_M1].have = 0; specs[PTI_SX_M1].val = 0; } else { (*err)("%s: ambiguous `m'",s0); } } return( ( (specs[PTI_SX_Y ].val * 31556952LL) + (specs[PTI_SX_M1].val * 2629746LL) + (specs[PTI_SX_W ].val * 604800LL) + (specs[PTI_SX_D ].val * 86400LL) + (specs[PTI_SX_H ].val * 3600LL) + (specs[PTI_SX_M2].val * 60LL) + (specs[PTI_SX_S ].val * 1LL) ) * 1000000000LL ); } TIMESTAMP timestamp_parse(const char *s, void (*err)(const char *, ...)) { unsigned long long int ts; char *ep; ts = strtoull(s,&ep,10); if ((ep == s) || *ep) { printf("bad timestamp\n"); // debugging (*err)("%s: invalid timestamp value",s); } return(ts); }