/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* Time_t conversion support
*
* scan date expression in s using format
* if non-null, e points to the first invalid sequence in s
* if non-null, f points to the first unused format char
* t provides default values
*/
#include <tmx.h>
#include <ctype.h>
typedef struct
{
int year;
int mon;
int week;
int weektype;
int yday;
int mday;
int wday;
int hour;
int min;
int sec;
int meridian;
int zone;
} Set_t;
#define CLEAR(s) (s.year=s.mon=s.week=s.weektype=s.yday=s.mday=s.wday=s.hour=s.min=s.sec=s.meridian=(-1),s.nsec=1000000000L,s.zone=TM_LOCALZONE)
#define INDEX(m,x) (((n)>=((x)-(m)))?((n)-=((x)-(m))):(n))
#define NUMBER(d,m,x) do \
{ \
n = 0; \
u = (char*)s; \
while (s < (const char*)(u + d) && *s >= '0' && *s <= '9') \
n = n * 10 + *s++ - '0'; \
if (u == (char*)s || n < m || n > x) \
goto next; \
} while (0)
/*
* generate a Time_t from tm + set
*/
static Time_t
{
register int n;
int z;
Time_t t;
{
}
{
{
}
}
{
{
}
}
{
}
{
}
{
}
{
}
{
z = 1;
}
{
z = 1;
n += 7;
}
else
z = 0;
{
if (!z)
{
z = 1;
}
}
}
/*
* the format scan workhorse
*/
static Time_t
{
register int d;
register int n;
register char* p;
const char* b;
char* u;
int m;
int hi;
int lo;
int pedantic;
Time_t x;
while (isspace(*s))
s++;
b = s;
for (;;)
{
if (!(d = *format++))
{
{
format--;
break;
}
}
else if (!*s)
{
format--;
break;
}
{
more:
switch (d)
{
case 'a':
lo = TM_DAY_ABBREV;
goto get_wday;
case 'A':
goto next;
s = u;
continue;
case 'b':
case 'h':
goto get_mon;
case 'B':
hi = TM_DAY_ABBREV;
goto next;
s = u;
continue;
case 'c':
p = "%a %b %e %T %Y";
break;
case 'C':
continue;
case 'd':
goto next;
/*FALLTHROUGH*/
case 'e':
continue;
case 'D':
p = "%m/%d/%y";
break;
case 'E':
case 'O':
if (*format)
{
d = *format++;
goto more;
}
continue;
case 'F':
p = "%Y-%m-%d";
break;
case 'H':
case 'k':
continue;
case 'I':
case 'l':
continue;
case 'j':
continue;
case 'm':
continue;
case 'M':
continue;
case 'n':
if (pedantic)
while (*s == '\n')
s++;
else
while (isspace(*s))
s++;
continue;
case 'N':
continue;
case 'p':
goto next;
s = u;
continue;
case 'r':
p = "%I:%M:%S %p";
break;
case 'R':
p = "%H:%M:%S";
break;
case 's':
x = strtoul(s, &u, 0);
if (s == u)
goto next;
s = u;
continue;
case 'S':
continue;
case 'u':
continue;
case 'U':
continue;
case 'V':
continue;
case 'w':
continue;
case 'W':
continue;
case 'x':
break;
case 'X':
break;
case 'y':
if (n < TM_WINDOW)
n += 100;
continue;
case 'Y':
continue;
case 'Z':
case 'q':
{
s = u;
}
else
u = 0;
if (d == 'q')
continue;
case 'z':
{
s = u;
}
continue;
case '|':
s = b;
goto again;
case '&':
x = tmxdate(s, e, t);
if (s == (const char*)*e)
goto next;
t = x;
s = (const char*)*e;
goto done;
goto again;
default:
goto next;
}
goto next;
format = (const char*)p;
}
else if (isspace(d))
while (isspace(*s))
s++;
else if (*s != d)
break;
else
s++;
}
next:
if (*format)
{
p = (char*)format;
if (!*s && *p == '%' && *(p + 1) == '|')
else
while (*p)
if (*p++ == '%' && *p && *p++ == '|' && *p)
{
format = (const char*)p;
s = b;
goto again;
}
}
done:
if (e)
{
while (isspace(*s))
s++;
*e = (char*)s;
}
if (f)
{
format++;
*f = (char*)format;
}
return t;
}
/*
* format==0 DATEMSK
* *format==0 DATEMSK and tmxdate()
* *format!=0 format
*/
{
register char* v;
register char** p;
char* q;
char* r;
Time_t x;
static int initialized;
static char** datemask;
tmlocale();
{
if (!initialized)
{
register int n;
off_t m;
initialized = 1;
{
if (p = newof(0, char*, n, m))
{
v = (char*)(p + n);
{
free(p);
p = 0;
}
else
{
datemask = p;
v[m] = 0;
while (*v)
{
*p++ = v;
if (!(v = strchr(v, '\n')))
break;
*v++ = 0;
}
*p = 0;
}
}
}
}
if (p = datemask)
while (v = *p++)
{
if (!*q && !*r)
{
if (e)
*e = q;
if (f)
*f = r;
return x;
}
}
if (f)
*f = (char*)format;
if (format)
return tmxdate(s, e, t);
if (e)
*e = (char*)s;
return 0;
}
}