FW: environment independent time functions...
Christos Zoulas
christos at zoulas.com
Fri Oct 1 14:53:40 UTC 2010
On Oct 1, 9:29am, abbotti at mev.co.uk (Ian Abbott) wrote:
-- Subject: Re: FW: environment independent time functions...
| > Has anyone done this work or similar?
|
| There are some functions and data structures in the latest stable GNOME
| GLib library (GLib 2.26) for handling time zones and time conversions:
|
| http://library.gnome.org/devel/glib/unstable/glib-GTimeZone.html
I apologize if I did not make myself clear in the previous message.
My goal was not to re-think and redesign the posix time interfaces,
but to make reentrant and thread-safe in an orthogonal manner,
minimizing code changes and re-using as much code as possible.
Also I wanted to make things fail on unknown timezones on the new
interfaces, not fall back to GMT. Here's my current diff. Most of
it has to do with ansifying, removing register, and making timezone_t
the first argument for orthogonality. Comments are welcome.
[the ifdef HIDE stuff should be removed; I just have it here so I can
use the new functions without collisions with libc]
Best,
christos
Index: localtime.c
===================================================================
RCS file: /src/twosigma/cvsroot/external/public/tzcode/localtime.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- localtime.c 30 Sep 2010 20:38:51 -0000 1.1.1.1
+++ localtime.c 30 Sep 2010 21:44:22 -0000 1.3
@@ -16,10 +16,31 @@
/*LINTLIBRARY*/
+#ifdef HIDE
+#define ctime __ctime
+#define ctime_r __ctime_r
+#define gmtime __gmtime
+#define gmtime_r __gmtime_r
+#define localtime __localtime
+#define localtime_r __localtime_r
+#define tzset __tzset
+#define tzsetwall __tzsetwall
+#define offtime __offtime
+#define offtime_r __offtime_r
+#define mktime __mktime
+#define timelocal __timelocal
+#define timegm __timegm
+#define timeoff __timeoff
+#define posix2time __posix2time
+#define time2posix __time2posix
+#define tzname __tzname
+#endif
+
#include "private.h"
#include "tzfile.h"
#include "fcntl.h"
#include "float.h" /* for FLT_MAX and DBL_MAX */
+#include "timeextra.h"
#ifndef TZ_ABBR_MAX_LEN
#define TZ_ABBR_MAX_LEN 16
@@ -70,7 +91,7 @@
static char wildabbr[] = WILDABBR;
-static const char gmt[] = "GMT";
+static char gmt[] = "GMT";
/*
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
@@ -105,7 +126,7 @@
#define MY_TZNAME_MAX 255
#endif /* !defined TZNAME_MAX */
-struct state {
+struct __state {
int leapcnt;
int timecnt;
int typecnt;
@@ -132,6 +153,8 @@
#define DAY_OF_YEAR 1 /* n - day of year */
#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+typedef struct tm *(*subfun_t)(const timezone_t sp, const time_t *timep,
+ long offset, struct tm *tmp);
/*
** Prototypes for static functions.
*/
@@ -146,11 +169,11 @@
static const char * getsecs(const char * strp, long * secsp);
static const char * getoffset(const char * strp, long * offsetp);
static const char * getrule(const char * strp, struct rule * rulep);
-static void gmtload(struct state * sp);
-static struct tm * gmtsub(const time_t * timep, long offset,
- struct tm * tmp);
-static struct tm * localsub(const time_t * timep, long offset,
- struct tm * tmp);
+static void gmtload(timezone_t sp);
+static struct tm * gmtsub(const timezone_t sp, const time_t *timep,
+ long offset, struct tm * tmp);
+static struct tm * localsub(const timezone_t sp, const time_t *timep,
+ long offset, struct tm *tmp);
static int increment_overflow(int * number, int delta);
static int leaps_thru_end_of(int y);
static int long_increment_overflow(long * number, int delta);
@@ -159,41 +182,27 @@
static int normalize_overflow(int * tensptr, int * unitsptr,
int base);
static void settzname(void);
-static time_t time1(struct tm * tmp,
- struct tm * (*funcp)(const time_t *,
- long, struct tm *),
- long offset);
-static time_t time2(struct tm *tmp,
- struct tm * (*funcp)(const time_t *,
- long, struct tm*),
- long offset, int * okayp);
-static time_t time2sub(struct tm *tmp,
- struct tm * (*funcp)(const time_t *,
- long, struct tm*),
+static time_t time1(const timezone_t sp, struct tm *tmp,
+ subfun_t funcp, long offset);
+static time_t time2(const timezone_t sp, struct tm *tmp,
+ subfun_t funcp, long offset, int *okayp);
+static time_t time2sub(const timezone_t sp, struct tm *tmp,
+ subfun_t funcp,
long offset, int * okayp, int do_norm_secs);
-static struct tm * timesub(const time_t * timep, long offset,
- const struct state * sp, struct tm * tmp);
+static struct tm * timesub(const timezone_t sp, const time_t * timep,
+ long offset, struct tm * tmp);
static int tmcomp(const struct tm * atmp,
const struct tm * btmp);
static time_t transtime(time_t janfirst, int year,
const struct rule * rulep, long offset);
-static int typesequiv(const struct state * sp, int a, int b);
-static int tzload(const char * name, struct state * sp,
+static int typesequiv(const timezone_t sp, int a, int b);
+static int tzload(timezone_t sp, const char * name,
int doextend);
-static int tzparse(const char * name, struct state * sp,
+static int tzparse(timezone_t sp, const char *name,
int lastditch);
-#ifdef ALL_STATE
-static struct state * lclptr;
-static struct state * gmtptr;
-#endif /* defined ALL_STATE */
-
-#ifndef ALL_STATE
-static struct state lclmem;
-static struct state gmtmem;
-#define lclptr (&lclmem)
-#define gmtptr (&gmtmem)
-#endif /* State Farm */
+static timezone_t lclptr;
+static timezone_t gmtptr;
#ifndef TZ_STRLEN_MAX
#define TZ_STRLEN_MAX 255
@@ -228,11 +237,10 @@
#endif /* defined ALTZONE */
static long
-detzcode(codep)
-const char * const codep;
+detzcode(const char *const codep)
{
- register long result;
- register int i;
+ long result;
+ int i;
result = (codep[0] & 0x80) ? ~0L : 0;
for (i = 0; i < 4; ++i)
@@ -241,11 +249,10 @@
}
static time_t
-detzcode64(codep)
-const char * const codep;
+detzcode64(const char *const codep)
{
- register time_t result;
- register int i;
+ time_t result;
+ int i;
result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0;
for (i = 0; i < 8; ++i)
@@ -253,11 +260,49 @@
return result;
}
+const char *
+tzgetname(const timezone_t sp, int isdst)
+{
+ int i;
+ for (i = 0; i < sp->timecnt; ++i) {
+ const struct ttinfo *const ttisp = &sp->ttis[sp->types[i]];
+
+ if (ttisp->tt_isdst == isdst)
+ return &sp->chars[ttisp->tt_abbrind];
+ }
+ return NULL;
+}
+
+static void
+settzname_z(timezone_t sp)
+{
+ int i;
+
+ /*
+ ** Scrub the abbreviations.
+ ** First, replace bogus characters.
+ */
+ for (i = 0; i < sp->charcnt; ++i)
+ if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
+ sp->chars[i] = TZ_ABBR_ERR_CHAR;
+ /*
+ ** Second, truncate long abbreviations.
+ */
+ for (i = 0; i < sp->typecnt; ++i) {
+ const struct ttinfo * const ttisp = &sp->ttis[i];
+ char * cp = &sp->chars[ttisp->tt_abbrind];
+
+ if (strlen(cp) > TZ_ABBR_MAX_LEN &&
+ strcmp(cp, GRANDPARENTED) != 0)
+ *(cp + TZ_ABBR_MAX_LEN) = '\0';
+ }
+}
+
static void
settzname(void)
{
- register struct state * const sp = lclptr;
- register int i;
+ timezone_t const sp = lclptr;
+ int i;
tzname[0] = wildabbr;
tzname[1] = wildabbr;
@@ -268,17 +313,15 @@
#ifdef ALTZONE
altzone = 0;
#endif /* defined ALTZONE */
-#ifdef ALL_STATE
if (sp == NULL) {
tzname[0] = tzname[1] = gmt;
return;
}
-#endif /* defined ALL_STATE */
/*
** And to get the latest zone names into tzname. . .
*/
for (i = 0; i < sp->timecnt; ++i) {
- register const struct ttinfo * const ttisp =
+ const struct ttinfo * const ttisp =
&sp->ttis[
sp->types[i]];
@@ -295,30 +338,11 @@
altzone = -(ttisp->tt_gmtoff);
#endif /* defined ALTZONE */
}
- /*
- ** Finally, scrub the abbreviations.
- ** First, replace bogus characters.
- */
- for (i = 0; i < sp->charcnt; ++i)
- if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
- sp->chars[i] = TZ_ABBR_ERR_CHAR;
- /*
- ** Second, truncate long abbreviations.
- */
- for (i = 0; i < sp->typecnt; ++i) {
- register const struct ttinfo * const ttisp = &sp->ttis[i];
- register char * cp = &sp->chars[ttisp->tt_abbrind];
-
- if (strlen(cp) > TZ_ABBR_MAX_LEN &&
- strcmp(cp, GRANDPARENTED) != 0)
- *(cp + TZ_ABBR_MAX_LEN) = '\0';
- }
+ settzname_z(sp);
}
static int
-differ_by_repeat(t1, t0)
-const time_t t1;
-const time_t t0;
+differ_by_repeat(const time_t t1, const time_t t0)
{
if (TYPE_INTEGRAL(time_t) &&
TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
@@ -327,16 +351,13 @@
}
static int
-tzload(name, sp, doextend)
-register const char * name;
-register struct state * const sp;
-register const int doextend;
-{
- register const char * p;
- register int i;
- register int fid;
- register int stored;
- register int nread;
+tzload(timezone_t sp, const char *name, const int doextend)
+{
+ const char * p;
+ int i;
+ int fid;
+ int stored;
+ int nread;
union {
struct tzhead tzhead;
char buf[2 * sizeof(struct tzhead) +
@@ -348,7 +369,7 @@
if (name == NULL && (name = TZDEFAULT) == NULL)
return -1;
{
- register int doaccess;
+ int doaccess;
/*
** Section 4.9.1 of the C standard says that
** "FILENAME_MAX expands to an integral constant expression
@@ -422,7 +443,7 @@
return -1;
}
for (i = 0; i < sp->typecnt; ++i) {
- register struct ttinfo * ttisp;
+ struct ttinfo * ttisp;
ttisp = &sp->ttis[i];
ttisp->tt_gmtoff = detzcode(p);
@@ -439,7 +460,7 @@
sp->chars[i] = *p++;
sp->chars[i] = '\0'; /* ensure '\0' at end */
for (i = 0; i < sp->leapcnt; ++i) {
- register struct lsinfo * lsisp;
+ struct lsinfo * lsisp;
lsisp = &sp->lsis[i];
lsisp->ls_trans = (stored == 4) ?
@@ -449,7 +470,7 @@
p += 4;
}
for (i = 0; i < sp->typecnt; ++i) {
- register struct ttinfo * ttisp;
+ struct ttinfo * ttisp;
ttisp = &sp->ttis[i];
if (ttisstdcnt == 0)
@@ -462,7 +483,7 @@
}
}
for (i = 0; i < sp->typecnt; ++i) {
- register struct ttinfo * ttisp;
+ struct ttinfo * ttisp;
ttisp = &sp->ttis[i];
if (ttisgmtcnt == 0)
@@ -491,7 +512,7 @@
/*
** Ignore the beginning (harder).
*/
- register int j;
+ int j;
for (j = 0; j + i < sp->timecnt; ++j) {
sp->ats[j] = sp->ats[j + i];
@@ -518,11 +539,11 @@
if (doextend && nread > 2 &&
u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
sp->typecnt + 2 <= TZ_MAX_TYPES) {
- struct state ts;
- register int result;
+ struct __state ts;
+ int result;
u.buf[nread - 1] = '\0';
- result = tzparse(&u.buf[1], &ts, FALSE);
+ result = tzparse(&ts, &u.buf[1], FALSE);
if (result == 0 && ts.typecnt == 2 &&
sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
for (i = 0; i < 2; ++i)
@@ -570,20 +591,17 @@
}
static int
-typesequiv(sp, a, b)
-const struct state * const sp;
-const int a;
-const int b;
+typesequiv(const timezone_t sp, const int a, const int b)
{
- register int result;
+ int result;
if (sp == NULL ||
a < 0 || a >= sp->typecnt ||
b < 0 || b >= sp->typecnt)
result = FALSE;
else {
- register const struct ttinfo * ap = &sp->ttis[a];
- register const struct ttinfo * bp = &sp->ttis[b];
+ const struct ttinfo * ap = &sp->ttis[a];
+ const struct ttinfo * bp = &sp->ttis[b];
result = ap->tt_gmtoff == bp->tt_gmtoff &&
ap->tt_isdst == bp->tt_isdst &&
ap->tt_ttisstd == bp->tt_ttisstd &&
@@ -611,9 +629,9 @@
static const char *
getzname(strp)
-register const char * strp;
+const char * strp;
{
- register char c;
+ char c;
while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
c != '+')
@@ -631,9 +649,9 @@
*/
static const char *
-getqzname(register const char *strp, const int delim)
+getqzname(const char *strp, const int delim)
{
- register int c;
+ int c;
while ((c = *strp) != '\0' && c != delim)
++strp;
@@ -649,13 +667,13 @@
static const char *
getnum(strp, nump, min, max)
-register const char * strp;
+const char * strp;
int * const nump;
const int min;
const int max;
{
- register char c;
- register int num;
+ char c;
+ int num;
if (strp == NULL || !is_digit(c = *strp))
return NULL;
@@ -681,9 +699,7 @@
*/
static const char *
-getsecs(strp, secsp)
-register const char * strp;
-long * const secsp;
+getsecs(const char *strp, long *const secsp)
{
int num;
@@ -723,11 +739,9 @@
*/
static const char *
-getoffset(strp, offsetp)
-register const char * strp;
-long * const offsetp;
+getoffset(const char *strp, long *const offsetp)
{
- register int neg = 0;
+ int neg = 0;
if (*strp == '-') {
neg = 1;
@@ -750,9 +764,7 @@
*/
static const char *
-getrule(strp, rulep)
-const char * strp;
-register struct rule * const rulep;
+getrule(const char *strp, struct rule *const rulep)
{
if (*strp == 'J') {
/*
@@ -804,15 +816,12 @@
*/
static time_t
-transtime(janfirst, year, rulep, offset)
-const time_t janfirst;
-const int year;
-register const struct rule * const rulep;
-const long offset;
-{
- register int leapyear;
- register time_t value;
- register int i;
+transtime(const time_t janfirst, const int year, const struct rule *const rulep,
+ const long offset)
+{
+ int leapyear;
+ time_t value;
+ int i;
int d, m1, yy0, yy1, yy2, dow;
INITIALIZE(value);
@@ -899,10 +908,7 @@
*/
static int
-tzparse(name, sp, lastditch)
-const char * name;
-register struct state * const sp;
-const int lastditch;
+tzparse(timezone_t sp, const char *name, const int lastditch)
{
const char * stdname;
const char * dstname;
@@ -910,10 +916,10 @@
size_t dstlen;
long stdoffset;
long dstoffset;
- register time_t * atp;
- register unsigned char * typep;
- register char * cp;
- register int load_result;
+ time_t * atp;
+ unsigned char * typep;
+ char * cp;
+ int load_result;
INITIALIZE(dstname);
stdname = name;
@@ -942,7 +948,7 @@
if (name == NULL)
return -1;
}
- load_result = tzload(TZDEFRULES, sp, FALSE);
+ load_result = tzload(sp, TZDEFRULES, FALSE);
if (load_result != 0)
sp->leapcnt = 0; /* so, we're off a little */
if (*name != '\0') {
@@ -968,8 +974,8 @@
if (*name == ',' || *name == ';') {
struct rule start;
struct rule end;
- register int year;
- register time_t janfirst;
+ int year;
+ time_t janfirst;
time_t starttime;
time_t endtime;
@@ -1025,12 +1031,12 @@
janfirst = newfirst;
}
} else {
- register long theirstdoffset;
- register long theirdstoffset;
- register long theiroffset;
- register int isdst;
- register int i;
- register int j;
+ long theirstdoffset;
+ long theirdstoffset;
+ long theiroffset;
+ int isdst;
+ int i;
+ int j;
if (*name != '\0')
return -1;
@@ -1134,11 +1140,30 @@
}
static void
-gmtload(sp)
-struct state * const sp;
+gmtload(timezone_t sp)
+{
+ if (tzload(sp, gmt, TRUE) != 0)
+ (void) tzparse(sp, gmt, TRUE);
+}
+
+const timezone_t
+tzalloc(const char *name)
+{
+ timezone_t sp = calloc(1, sizeof *sp);
+ if (sp == NULL)
+ return NULL;
+ if (tzload(sp, name, TRUE) != 0) {
+ free(sp);
+ return NULL;
+ }
+ settzname_z(sp);
+ return sp;
+}
+
+void
+tzfree(const timezone_t sp)
{
- if (tzload(gmt, sp, TRUE) != 0)
- (void) tzparse(gmt, sp, TRUE);
+ free((void *)(intptr_t)sp);
}
#ifndef STD_INSPIRED
@@ -1155,16 +1180,14 @@
return;
lcl_is_set = -1;
-#ifdef ALL_STATE
if (lclptr == NULL) {
- lclptr = (struct state *) calloc(1, sizeof *lclptr);
+ lclptr = calloc(1, sizeof *lclptr);
if (lclptr == NULL) {
settzname(); /* all we can do */
return;
}
}
-#endif /* defined ALL_STATE */
- if (tzload((char *) NULL, lclptr, TRUE) != 0)
+ if (tzload(lclptr, NULL, TRUE) != 0)
gmtload(lclptr);
settzname();
}
@@ -1172,7 +1195,7 @@
void
tzset(void)
{
- register const char * name;
+ const char * name;
name = getenv("TZ");
if (name == NULL) {
@@ -1186,15 +1209,13 @@
if (lcl_is_set)
(void) strcpy(lcl_TZname, name);
-#ifdef ALL_STATE
if (lclptr == NULL) {
- lclptr = (struct state *) calloc(1, sizeof *lclptr);
+ lclptr = calloc(1, sizeof *lclptr);
if (lclptr == NULL) {
settzname(); /* all we can do */
return;
}
}
-#endif /* defined ALL_STATE */
if (*name == '\0') {
/*
** User wants it fast rather than right.
@@ -1206,8 +1227,8 @@
lclptr->ttis[0].tt_gmtoff = 0;
lclptr->ttis[0].tt_abbrind = 0;
(void) strcpy(lclptr->chars, gmt);
- } else if (tzload(name, lclptr, TRUE) != 0)
- if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
+ } else if (tzload(lclptr, name, TRUE) != 0)
+ if (name[0] == ':' || tzparse(lclptr, name, FALSE) != 0)
(void) gmtload(lclptr);
settzname();
}
@@ -1223,28 +1244,20 @@
/*ARGSUSED*/
static struct tm *
-localsub(timep, offset, tmp)
-const time_t * const timep;
-const long offset;
-struct tm * const tmp;
-{
- register struct state * sp;
- register const struct ttinfo * ttisp;
- register int i;
- register struct tm * result;
+localsub(const timezone_t sp, const time_t * const timep, const long offset,
+ struct tm *const tmp)
+{
+ const struct ttinfo * ttisp;
+ int i;
+ struct tm * result;
const time_t t = *timep;
- sp = lclptr;
-#ifdef ALL_STATE
- if (sp == NULL)
- return gmtsub(timep, offset, tmp);
-#endif /* defined ALL_STATE */
if ((sp->goback && t < sp->ats[0]) ||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
time_t newt = t;
- register time_t seconds;
- register time_t tcycles;
- register int_fast64_t icycles;
+ time_t seconds;
+ time_t tcycles;
+ int_fast64_t icycles;
if (t < sp->ats[0])
seconds = sp->ats[0] - t;
@@ -1264,9 +1277,9 @@
if (newt < sp->ats[0] ||
newt > sp->ats[sp->timecnt - 1])
return NULL; /* "cannot happen" */
- result = localsub(&newt, offset, tmp);
+ result = localsub(sp, &newt, offset, tmp);
if (result == tmp) {
- register time_t newy;
+ time_t newy;
newy = tmp->tm_year;
if (t < sp->ats[0])
@@ -1286,11 +1299,11 @@
break;
}
} else {
- register int lo = 1;
- register int hi = sp->timecnt;
+ int lo = 1;
+ int hi = sp->timecnt;
while (lo < hi) {
- register int mid = (lo + hi) >> 1;
+ int mid = (lo + hi) >> 1;
if (t < sp->ats[mid])
hi = mid;
@@ -1305,7 +1318,7 @@
** t += ttisp->tt_gmtoff;
** timesub(&t, 0L, sp, tmp);
*/
- result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
+ result = timesub(sp, &t, ttisp->tt_gmtoff, tmp);
tmp->tm_isdst = ttisp->tt_isdst;
tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
#ifdef TM_ZONE
@@ -1315,46 +1328,48 @@
}
struct tm *
-localtime(timep)
-const time_t * const timep;
+localtime_r(const time_t *const timep, struct tm *tmp)
+{
+ if (lclptr == NULL)
+ return gmtsub(NULL, timep, 0L, tmp);
+ return localtime_z(lclptr, timep, tmp);
+}
+
+struct tm *
+localtime(const time_t *const timep)
{
tzset();
- return localsub(timep, 0L, &tm);
+ return localtime_r(timep, &tm);
}
/*
** Re-entrant version of localtime.
*/
-
struct tm *
-localtime_r(timep, tmp)
-const time_t * const timep;
-struct tm * tmp;
+localtime_z(const timezone_t sp, const time_t *const timep, struct tm *tmp)
{
- return localsub(timep, 0L, tmp);
+ return localsub(sp, timep, 0L, tmp);
}
+
+
/*
** gmtsub is to gmtime as localsub is to localtime.
*/
static struct tm *
-gmtsub(timep, offset, tmp)
-const time_t * const timep;
-const long offset;
-struct tm * const tmp;
+gmtsub(const timezone_t sp, const time_t * const timep, const long offset,
+ struct tm *const tmp)
{
- register struct tm * result;
+ struct tm * result;
if (!gmt_is_set) {
gmt_is_set = TRUE;
-#ifdef ALL_STATE
- gmtptr = (struct state *) calloc(1, sizeof *gmtptr);
+ gmtptr = calloc(1, sizeof *gmtptr);
if (gmtptr != NULL)
-#endif /* defined ALL_STATE */
gmtload(gmtptr);
}
- result = timesub(timep, offset, gmtptr, tmp);
+ result = timesub(gmtptr, timep, offset, tmp);
#ifdef TM_ZONE
/*
** Could get fancy here and deliver something such as
@@ -1364,24 +1379,18 @@
if (offset != 0)
tmp->TM_ZONE = wildabbr;
else {
-#ifdef ALL_STATE
if (gmtptr == NULL)
tmp->TM_ZONE = gmt;
else tmp->TM_ZONE = gmtptr->chars;
-#endif /* defined ALL_STATE */
-#ifndef ALL_STATE
- tmp->TM_ZONE = gmtptr->chars;
-#endif /* State Farm */
}
#endif /* defined TM_ZONE */
return result;
}
struct tm *
-gmtime(timep)
-const time_t * const timep;
+gmtime(const time_t *const timep)
{
- return gmtsub(timep, 0L, &tm);
+ return gmtsub(NULL, timep, 0L, &tm);
}
/*
@@ -1389,21 +1398,23 @@
*/
struct tm *
-gmtime_r(timep, tmp)
-const time_t * const timep;
-struct tm * tmp;
+gmtime_r(const time_t * const timep, struct tm *tmp)
{
- return gmtsub(timep, 0L, tmp);
+ return gmtsub(NULL, timep, 0L, tmp);
}
#ifdef STD_INSPIRED
struct tm *
-offtime(timep, offset)
-const time_t * const timep;
-const long offset;
+offtime(const time_t *const timep, const long offset)
+{
+ return gmtsub(timep, offset, &tm, NULL);
+}
+
+struct tm *
+offtime_r(const time_t *const timep, const long offset, struct tm *tmp)
{
- return gmtsub(timep, offset, &tm);
+ return gmtsub(timep, offset, tmp, NULL);
}
#endif /* defined STD_INSPIRED */
@@ -1414,38 +1425,29 @@
*/
static int
-leaps_thru_end_of(y)
-register const int y;
+leaps_thru_end_of(const int y)
{
return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
-(leaps_thru_end_of(-(y + 1)) + 1);
}
static struct tm *
-timesub(timep, offset, sp, tmp)
-const time_t * const timep;
-const long offset;
-register const struct state * const sp;
-register struct tm * const tmp;
-{
- register const struct lsinfo * lp;
- register time_t tdays;
- register int idays; /* unsigned would be so 2003 */
- register long rem;
- int y;
- register const int * ip;
- register long corr;
- register int hit;
- register int i;
+timesub(const timezone_t sp, const time_t *const timep, const long offset,
+ struct tm *const tmp)
+{
+ const struct lsinfo * lp;
+ time_t tdays;
+ int idays; /* unsigned would be so 2003 */
+ long rem;
+ int y;
+ const int * ip;
+ long corr;
+ int hit;
+ int i;
corr = 0;
hit = 0;
-#ifdef ALL_STATE
i = (sp == NULL) ? 0 : sp->leapcnt;
-#endif /* defined ALL_STATE */
-#ifndef ALL_STATE
- i = sp->leapcnt;
-#endif /* State Farm */
while (--i >= 0) {
lp = &sp->lsis[i];
if (*timep >= lp->ls_trans) {
@@ -1471,9 +1473,9 @@
rem = *timep - tdays * SECSPERDAY;
while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
int newy;
- register time_t tdelta;
- register int idelta;
- register int leapdays;
+ time_t tdelta;
+ int idelta;
+ int leapdays;
tdelta = tdays / DAYSPERLYEAR;
idelta = tdelta;
@@ -1491,7 +1493,7 @@
y = newy;
}
{
- register long seconds;
+ long seconds;
seconds = tdays * SECSPERDAY + 0.5;
tdays = seconds / SECSPERDAY;
@@ -1556,8 +1558,7 @@
}
char *
-ctime(timep)
-const time_t * const timep;
+ctime(const time_t *const timep)
{
/*
** Section 4.12.3.2 of X3.159-1989 requires that
@@ -1569,15 +1570,21 @@
}
char *
-ctime_r(timep, buf)
-const time_t * const timep;
-char * buf;
+ctime_r(const time_t *const timep, char *buf)
{
struct tm mytm;
return asctime_r(localtime_r(timep, &mytm), buf);
}
+char *
+ctime_z(const timezone_t sp, const time_t *const timep, char *buf)
+{
+ struct tm mytm;
+
+ return asctime_r(localtime_z(sp, timep, &mytm), buf);
+}
+
/*
** Adapted from code provided by Robert Elz, who writes:
** The "best" way to do mktime I think is based on an idea of Bob
@@ -1596,9 +1603,7 @@
*/
static int
-increment_overflow(number, delta)
-int * number;
-int delta;
+increment_overflow(int *number, int delta)
{
int number0;
@@ -1608,9 +1613,7 @@
}
static int
-long_increment_overflow(number, delta)
-long * number;
-int delta;
+long_increment_overflow(long *number, int delta)
{
long number0;
@@ -1620,12 +1623,9 @@
}
static int
-normalize_overflow(tensptr, unitsptr, base)
-int * const tensptr;
-int * const unitsptr;
-const int base;
+normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
{
- register int tensdelta;
+ int tensdelta;
tensdelta = (*unitsptr >= 0) ?
(*unitsptr / base) :
@@ -1635,12 +1635,10 @@
}
static int
-long_normalize_overflow(tensptr, unitsptr, base)
-long * const tensptr;
-int * const unitsptr;
-const int base;
+long_normalize_overflow(long *const tensptr, int *const unitsptr,
+ const int base)
{
- register int tensdelta;
+ int tensdelta;
tensdelta = (*unitsptr >= 0) ?
(*unitsptr / base) :
@@ -1650,11 +1648,9 @@
}
static int
-tmcomp(atmp, btmp)
-register const struct tm * const atmp;
-register const struct tm * const btmp;
+tmcomp(const struct tm *const atmp, const struct tm *const btmp)
{
- register int result;
+ int result;
if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
(result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
@@ -1666,20 +1662,15 @@
}
static time_t
-time2sub(tmp, funcp, offset, okayp, do_norm_secs)
-struct tm * const tmp;
-struct tm * (* const funcp)(const time_t*, long, struct tm*);
-const long offset;
-int * const okayp;
-const int do_norm_secs;
-{
- register const struct state * sp;
- register int dir;
- register int i, j;
- register int saved_seconds;
- register long li;
- register time_t lo;
- register time_t hi;
+time2sub(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
+ const long offset, int *const okayp, const int do_norm_secs)
+{
+ int dir;
+ int i, j;
+ int saved_seconds;
+ long li;
+ time_t lo;
+ time_t hi;
long y;
time_t newt;
time_t t;
@@ -1775,7 +1766,7 @@
t = lo;
else if (t > hi)
t = hi;
- if ((*funcp)(&t, offset, &mytm) == NULL) {
+ if ((*funcp)(sp, &t, offset, &mytm) == NULL) {
/*
** Assume that t is too extreme to be represented in
** a struct tm; arrange things so that it is less
@@ -1810,12 +1801,8 @@
** It's okay to guess wrong since the guess
** gets checked.
*/
- sp = (const struct state *)
- ((funcp == localsub) ? lclptr : gmtptr);
-#ifdef ALL_STATE
if (sp == NULL)
return WRONG;
-#endif /* defined ALL_STATE */
for (i = sp->typecnt - 1; i >= 0; --i) {
if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
continue;
@@ -1824,7 +1811,7 @@
continue;
newt = t + sp->ttis[j].tt_gmtoff -
sp->ttis[i].tt_gmtoff;
- if ((*funcp)(&newt, offset, &mytm) == NULL)
+ if ((*funcp)(sp, &newt, offset, &mytm) == NULL)
continue;
if (tmcomp(&mytm, &yourtm) != 0)
continue;
@@ -1844,17 +1831,14 @@
if ((newt < t) != (saved_seconds < 0))
return WRONG;
t = newt;
- if ((*funcp)(&t, offset, tmp))
+ if ((*funcp)(sp, &t, offset, tmp))
*okayp = TRUE;
return t;
}
static time_t
-time2(tmp, funcp, offset, okayp)
-struct tm * const tmp;
-struct tm * (* const funcp)(const time_t*, long, struct tm*);
-const long offset;
-int * const okayp;
+time2(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
+ const long offset, int *const okayp)
{
time_t t;
@@ -1863,22 +1847,19 @@
** (in case tm_sec contains a value associated with a leap second).
** If that fails, try with normalization of seconds.
*/
- t = time2sub(tmp, funcp, offset, okayp, FALSE);
- return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
+ t = time2sub(sp, tmp, funcp, offset, okayp, FALSE);
+ return *okayp ? t : time2sub(sp, tmp, funcp, offset, okayp, TRUE);
}
static time_t
-time1(tmp, funcp, offset)
-struct tm * const tmp;
-struct tm * (* const funcp)(const time_t *, long, struct tm *);
-const long offset;
-{
- register time_t t;
- register const struct state * sp;
- register int samei, otheri;
- register int sameind, otherind;
- register int i;
- register int nseen;
+time1(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
+ const long offset)
+{
+ time_t t;
+ int samei, otheri;
+ int sameind, otherind;
+ int i;
+ int nseen;
int seen[TZ_MAX_TYPES];
int types[TZ_MAX_TYPES];
int okay;
@@ -1889,7 +1870,7 @@
}
if (tmp->tm_isdst > 1)
tmp->tm_isdst = 1;
- t = time2(tmp, funcp, offset, &okay);
+ t = time2(sp, tmp, funcp, offset, &okay);
#ifdef PCTS
/*
** PCTS code courtesy Grant Sullivan.
@@ -1909,11 +1890,8 @@
** We try to divine the type they started from and adjust to the
** type they need.
*/
- sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr);
-#ifdef ALL_STATE
if (sp == NULL)
return WRONG;
-#endif /* defined ALL_STATE */
for (i = 0; i < sp->typecnt; ++i)
seen[i] = FALSE;
nseen = 0;
@@ -1933,7 +1911,7 @@
tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
sp->ttis[samei].tt_gmtoff;
tmp->tm_isdst = !tmp->tm_isdst;
- t = time2(tmp, funcp, offset, &okay);
+ t = time2(sp, tmp, funcp, offset, &okay);
if (okay)
return t;
tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
@@ -1945,18 +1923,33 @@
}
time_t
-mktime(tmp)
-struct tm * const tmp;
+mktime_z(const timezone_t sp, struct tm *const tmp)
+{
+ return time1(sp, tmp, localsub, 0L);
+}
+
+time_t
+mktime(struct tm *const tmp)
{
tzset();
- return time1(tmp, localsub, 0L);
+ if (lclptr == NULL)
+ return time1(NULL, tmp, gmtsub, 0L);
+ else
+ return time1(lclptr, tmp, localsub, 0L);
}
#ifdef STD_INSPIRED
time_t
-timelocal(tmp)
-struct tm * const tmp;
+timelocal_z(const timezone_t sp, struct tm *const tmp)
+{
+ if (tmp != NULL)
+ tmp->tm_isdst = -1; /* in case it wasn't initialized */
+ return mktime_z(tmp, sp);
+}
+
+time_t
+timelocal(struct tm *const tmp)
{
if (tmp != NULL)
tmp->tm_isdst = -1; /* in case it wasn't initialized */
@@ -1964,22 +1957,19 @@
}
time_t
-timegm(tmp)
-struct tm * const tmp;
+timegm(struct tm *const tmp)
{
if (tmp != NULL)
tmp->tm_isdst = 0;
- return time1(tmp, gmtsub, 0L);
+ return time1(gmtptr, tmp, gmtsub, 0L);
}
time_t
-timeoff(tmp, offset)
-struct tm * const tmp;
-const long offset;
+timeoff(struct tm *const tmp, const long offset)
{
if (tmp != NULL)
tmp->tm_isdst = 0;
- return time1(tmp, gmtsub, offset);
+ return time1(gmtptr, tmp, gmtsub, offset);
}
#endif /* defined STD_INSPIRED */
@@ -1992,10 +1982,9 @@
*/
long
-gtime(tmp)
-struct tm * const tmp;
+gtime(struct tm *const tmp)
{
- const time_t t = mktime(tmp);
+ const time_t t = mktime(tmp);
if (t == WRONG)
return -1;
@@ -2019,14 +2008,11 @@
*/
static long
-leapcorr(timep)
-time_t * timep;
+leapcorr(const timezone_t sp, time_t *timep)
{
- register struct state * sp;
- register struct lsinfo * lp;
- register int i;
+ struct lsinfo * lp;
+ int i;
- sp = lclptr;
i = sp->leapcnt;
while (--i >= 0) {
lp = &sp->lsis[i];
@@ -2037,45 +2023,54 @@
}
time_t
-time2posix(t)
-time_t t;
+time2posix_z(const timezone_t sp, time_t t)
{
- tzset();
- return t - leapcorr(&t);
+ return t - leapcorr(sp, &t);
+}
+
+time_t
+time2posix(time_t t)
+{
+ return time2posix_z(lclptr, t);
}
+
time_t
-posix2time(t)
-time_t t;
+posix2time_z(const timezone_t sp, time_t t)
{
time_t x;
time_t y;
- tzset();
/*
** For a positive leap second hit, the result
** is not unique. For a negative leap second
** hit, the corresponding time doesn't exist,
** so we return an adjacent second.
*/
- x = t + leapcorr(&t);
- y = x - leapcorr(&x);
+ x = t + leapcorr(sp, &t);
+ y = x - leapcorr(sp, &x);
if (y < t) {
do {
x++;
- y = x - leapcorr(&x);
+ y = x - leapcorr(sp, &x);
} while (y < t);
if (t != y)
return x - 1;
} else if (y > t) {
do {
--x;
- y = x - leapcorr(&x);
+ y = x - leapcorr(sp, &x);
} while (y > t);
if (t != y)
return x + 1;
}
return x;
+}
+
+time_t
+posix2time(time_t t)
+{
+ return posix2time_z(lclptr, t);
}
#endif /* defined STD_INSPIRED */
Index: strftime.c
===================================================================
RCS file: /src/twosigma/cvsroot/external/public/tzcode/strftime.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- strftime.c 30 Sep 2010 20:38:51 -0000 1.1.1.1
+++ strftime.c 30 Sep 2010 21:44:22 -0000 1.2
@@ -36,6 +36,11 @@
#include "tzfile.h"
#include "fcntl.h"
#include "locale.h"
+#include "timeextra.h"
+
+#ifdef HIDE
+#define strftime __strftime
+#endif
struct lc_time_T {
const char * mon[MONSPERYEAR];
@@ -108,8 +113,8 @@
static char * _add(const char *, char *, const char *);
static char * _conv(int, const char *, char *, const char *);
-static char * _fmt(const char *, const struct tm *, char *, const char *,
- int *);
+static char * _fmt(const timezone_t, const char *, const struct tm *, char *,
+ const char *, int *);
static char * _yconv(int, int, int, int, char *, const char *);
extern char * tzname[];
@@ -124,21 +129,18 @@
#define IN_ALL 3
size_t
-strftime(s, maxsize, format, t)
-char * const s;
-const size_t maxsize;
-const char * const format;
-const struct tm * const t;
+strftime_z(const timezone_t sp, char * const s, const size_t maxsize,
+ const char * const format, const struct tm * const t)
{
char * p;
int warn;
- tzset();
#ifdef LOCALE_HOME
localebuf.mon[0] = 0;
#endif /* defined LOCALE_HOME */
warn = IN_NONE;
- p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
+ p = _fmt(sp, ((format == NULL) ? "%c" : format), t, s, s + maxsize,
+ &warn);
#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
(void) fprintf(stderr, "\n");
@@ -162,12 +164,8 @@
}
static char *
-_fmt(format, t, pt, ptlim, warnp)
-const char * format;
-const struct tm * const t;
-char * pt;
-const char * const ptlim;
-int * warnp;
+_fmt(const timezone_t sp, const char *format, const struct tm * const t,
+ char *pt, const char *const ptlim, int *warnp)
{
for ( ; *format; ++format) {
if (*format == '%') {
@@ -216,7 +214,7 @@
{
int warn2 = IN_SOME;
- pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
+ pt = _fmt(sp, Locale->c_fmt, t, pt, ptlim, &warn2);
if (warn2 == IN_ALL)
warn2 = IN_THIS;
if (warn2 > *warnp)
@@ -224,7 +222,7 @@
}
continue;
case 'D':
- pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
+ pt = _fmt(sp, "%m/%d/%y", t, pt, ptlim, warnp);
continue;
case 'd':
pt = _conv(t->tm_mday, "%02d", pt, ptlim);
@@ -245,7 +243,7 @@
pt = _conv(t->tm_mday, "%2d", pt, ptlim);
continue;
case 'F':
- pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
+ pt = _fmt(sp, "%Y-%m-%d", t, pt, ptlim, warnp);
continue;
case 'H':
pt = _conv(t->tm_hour, "%02d", pt, ptlim);
@@ -309,10 +307,10 @@
pt, ptlim);
continue;
case 'R':
- pt = _fmt("%H:%M", t, pt, ptlim, warnp);
+ pt = _fmt(sp, "%H:%M", t, pt, ptlim, warnp);
continue;
case 'r':
- pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
+ pt = _fmt(sp, "%I:%M:%S %p", t, pt, ptlim, warnp);
continue;
case 'S':
pt = _conv(t->tm_sec, "%02d", pt, ptlim);
@@ -335,7 +333,7 @@
}
continue;
case 'T':
- pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
+ pt = _fmt(sp, "%H:%M:%S", t, pt, ptlim, warnp);
continue;
case 't':
pt = _add("\t", pt, ptlim);
@@ -450,7 +448,7 @@
** "date as dd-bbb-YYYY"
** (ado, 1993-05-24)
*/
- pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
+ pt = _fmt(sp, "%e-%b-%Y", t, pt, ptlim, warnp);
continue;
case 'W':
pt = _conv((t->tm_yday + DAYSPERWEEK -
@@ -463,13 +461,13 @@
pt = _conv(t->tm_wday, "%d", pt, ptlim);
continue;
case 'X':
- pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
+ pt = _fmt(sp, Locale->X_fmt, t, pt, ptlim, warnp);
continue;
case 'x':
{
int warn2 = IN_SOME;
- pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
+ pt = _fmt(sp, Locale->x_fmt, t, pt, ptlim, &warn2);
if (warn2 == IN_ALL)
warn2 = IN_THIS;
if (warn2 > *warnp)
@@ -492,8 +490,10 @@
else
#endif /* defined TM_ZONE */
if (t->tm_isdst >= 0)
- pt = _add(tzname[t->tm_isdst != 0],
- pt, ptlim);
+ pt = _add((sp ?
+ tzgetname(sp, t->tm_isdst) :
+ tzname[t->tm_isdst != 0]),
+ pt, ptlim);
/*
** C99 says that %Z must be replaced by the
** empty string if the time zone is not
@@ -554,7 +554,7 @@
}
continue;
case '+':
- pt = _fmt(Locale->date_fmt, t, pt, ptlim,
+ pt = _fmt(sp, Locale->date_fmt, t, pt, ptlim,
warnp);
continue;
case '%':
@@ -572,6 +572,14 @@
*pt++ = *format;
}
return pt;
+}
+
+size_t
+strftime(char * const s, const size_t maxsize,
+ const char * const format, const struct tm * const t)
+{
+ tzset();
+ return strftime_z(NULL, s, maxsize, format, t);
}
static char *
--- /dev/null 2005-11-17 13:47:49.000000000 -0500
+++ timeextra.h 2010-09-30 17:04:29.734633589 -0400
@@ -0,0 +1,23 @@
+
+#ifndef _TIMEEXTRA_H_
+#define _TIMEEXTRA_H_
+
+#include <time.h>
+
+__BEGIN_DECLS
+typedef struct __state *timezone_t;
+
+const timezone_t tzalloc(const char *);
+void tzfree(const timezone_t);
+const char * tzgetname(const timezone_t, int);
+struct tm * localtime_z(const timezone_t, const time_t *, struct tm *);
+char * ctime_z(const timezone_t, const time_t *, char *);
+time_t timelocal_z(const timezone_t, struct tm *);
+time_t mktime_z(const timezone_t, struct tm *);
+time_t time2posix_z(const timezone_t, time_t);
+time_t posix2time_z(const timezone_t, time_t);
+size_t strftime_z(const timezone_t, char *, size_t, const char *,
+ const struct tm *);
+__END_DECLS
+
+#endif /* _TIMEEXTRA_H_ */
More information about the tz
mailing list