/* This file is in the public domain. */ #include #include "ctype.h" #include "timeint.h" TIMEINTVL parse_time_interval(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])) 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; } sx = 0; while (1) { while (*s && UCisspace(*s)) s ++; if (! *s) break; ulv = strtoul(s,&e,10); if (e == s) (*err)("bad number in time interval"); if (! *e) (*err)("missing unit in time interval"); uv = ulv; if (uv != ulv) (*err)("out-of-range number in time interval"); while (1) { if (sx >= PTI_N_SPECS) (*err)("bad unit `%c' in time interval",*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)("ambiguous `m' in time interval"); } } return( (specs[PTI_SX_Y ].val * 31556952) + (specs[PTI_SX_M1].val * 2629746) + (specs[PTI_SX_W ].val * 604800) + (specs[PTI_SX_D ].val * 86400) + (specs[PTI_SX_H ].val * 3600) + (specs[PTI_SX_M2].val * 60) + (specs[PTI_SX_S ].val * 1) ); }