Below find proposed changes, all (I hope) noncontroversial:
1. The addition of a comment to asctime.c warning against relying
completely on strftime.
2. Changes to zdump.c to improve the output when gmtime() returns NULL and
time_t is a strange type.
3. A fix to the declaration of wildabbr in localtime.c
4. Changes to some localtime.c internal functions from returning voids to
returning struct tm *s.
The last above is in preparation for doing a better job of handling the
situation where a time_t value is fed to localtime or gmtime but the year
associated with the time_t value won't fit in an int (as can happen if, for
example, time_t is double).
--ado
------- asctime.c -------
*** /tmp/geta3717 Mon Dec 27 09:18:15 2004
--- /tmp/getb3717 Mon Dec 27 09:18:15 2004
***************
*** 3,11 ****
** 1996-06-05 by Arthur David Olson (arthur_david_olson(a)nih.gov)
*/
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)asctime.c 7.29";
#endif /* !defined NOID */
#endif /* !defined lint */
--- 3,17 ----
** 1996-06-05 by Arthur David Olson (arthur_david_olson(a)nih.gov)
*/
+ /*
+ ** Avoid the temptation to punt entirely to strftime;
+ ** the output of strftime is supposed to be locale specific
+ ** whereas the output of asctime is supposed to be constant.
+ */
+
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)asctime.c 7.30";
#endif /* !defined NOID */
#endif /* !defined lint */
------- zdump.c -------
*** /tmp/geta3736 Mon Dec 27 09:18:15 2004
--- /tmp/getb3736 Mon Dec 27 09:18:15 2004
***************
*** 1,4 ****
! static char elsieid[] = "@(#)zdump.c 7.57";
/*
** This code has been made independent of the rest of the time
--- 1,4 ----
! static char elsieid[] = "@(#)zdump.c 7.58";
/*
** This code has been made independent of the rest of the time
***************
*** 151,156 ****
--- 151,157 ----
static time_t hunt P((char * name, time_t lot, time_t hit));
static void setabsolutes();
static void show P((char * zone, time_t t, int v));
+ static char * tformat P((void));
static time_t yeartot P((long y));
int
***************
*** 469,475 ****
if (v) {
tmp = gmtime(&t);
if (tmp == NULL) {
! (void) printf("%g", (double) t);
} else {
dumptime(tmp);
(void) printf(" UTC");
--- 470,476 ----
if (v) {
tmp = gmtime(&t);
if (tmp == NULL) {
! (void) printf(tformat(), t);
} else {
dumptime(tmp);
(void) printf(" UTC");
***************
*** 504,509 ****
--- 505,529 ----
return (result == NULL) ? &nada : result;
}
+ static char *
+ tformat()
+ {
+ if (0.5 == (time_t) 0.5) /* floating */
+ return "%g";
+ if (0 > (time_t) -1) { /* signed */
+ if (sizeof (time_t) > sizeof (long))
+ return "%lld";
+ if (sizeof (time_t) == sizeof (long))
+ return "%ld";
+ return "%d";
+ }
+ if (sizeof (time_t) > sizeof (unsigned long))
+ return "%llu";
+ if (sizeof (time_t) == sizeof (unsigned long))
+ return "%lu";
+ return "%u";
+ }
+
static void
dumptime(timeptr)
register const struct tm * timeptr;
------- localtime.c -------
*** /tmp/geta3754 Mon Dec 27 09:18:15 2004
--- /tmp/getb3754 Mon Dec 27 09:18:15 2004
***************
*** 2,7 ****
--- 2,8 ----
** XXX--do the right thing if time_t is double and
** the value fed to gmtime or localtime is very very negative or
** very very positive (which causes problems with the days-and-rem logic).
+ ** Also: do the right thing in mktime if time_t is double.
*/
/*
***************
*** 11,17 ****
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)localtime.c 7.83";
#endif /* !defined NOID */
#endif /* !defined lint */
--- 12,18 ----
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)localtime.c 7.85";
#endif /* !defined NOID */
#endif /* !defined lint */
***************
*** 61,67 ****
#define WILDABBR " "
#endif /* !defined WILDABBR */
! static char wildabbr[] = "WILDABBR";
static const char gmt[] = "GMT";
--- 62,68 ----
#define WILDABBR " "
#endif /* !defined WILDABBR */
! static char wildabbr[] = WILDABBR;
static const char gmt[] = "GMT";
***************
*** 135,143 ****
static const char * getoffset P((const char * strp, long * offsetp));
static const char * getrule P((const char * strp, struct rule * rulep));
static void gmtload P((struct state * sp));
! static void gmtsub P((const time_t * timep, long offset,
struct tm * tmp));
! static void localsub P((const time_t * timep, long offset,
struct tm * tmp));
static int increment_overflow P((int * number, int delta));
static int long_increment_overflow P((long * number, int
delta));
--- 136,144 ----
static const char * getoffset P((const char * strp, long * offsetp));
static const char * getrule P((const char * strp, struct rule * rulep));
static void gmtload P((struct state * sp));
! static struct tm * gmtsub P((const time_t * timep, long offset,
struct tm * tmp));
! static struct tm * localsub P((const time_t * timep, long offset,
struct tm * tmp));
static int increment_overflow P((int * number, int delta));
static int long_increment_overflow P((long * number, int
delta));
***************
*** 147,164 ****
int base));
static void settzname P((void));
static time_t time1 P((struct tm * tmp,
! void(*funcp) P((const time_t *,
long, struct tm *)),
long offset));
static time_t time2 P((struct tm *tmp,
! void(*funcp) P((const time_t *,
long, struct tm*)),
long offset, int * okayp));
static time_t time2sub P((struct tm *tmp,
! void(*funcp) P((const time_t *,
long, struct tm*)),
long offset, int * okayp, int
do_norm_secs));
! static void timesub P((const time_t * timep, long offset,
const struct state * sp, struct tm * tmp));
static int tmcomp P((const struct tm * atmp,
const struct tm * btmp));
--- 148,165 ----
int base));
static void settzname P((void));
static time_t time1 P((struct tm * tmp,
! struct tm * (*funcp) P((const time_t *,
long, struct tm *)),
long offset));
static time_t time2 P((struct tm *tmp,
! struct tm * (*funcp) P((const time_t *,
long, struct tm*)),
long offset, int * okayp));
static time_t time2sub P((struct tm *tmp,
! struct tm * (*funcp) P((const time_t *,
long, struct tm*)),
long offset, int * okayp, int
do_norm_secs));
! static struct tm * timesub P((const time_t * timep, long offset,
const struct state * sp, struct tm * tmp));
static int tmcomp P((const struct tm * atmp,
const struct tm * btmp));
***************
*** 1033,1039 ****
*/
/*ARGSUSED*/
! static void
localsub(timep, offset, tmp)
const time_t * const timep;
const long offset;
--- 1034,1040 ----
*/
/*ARGSUSED*/
! static struct tm *
localsub(timep, offset, tmp)
const time_t * const timep;
const long offset;
***************
*** 1042,1055 ****
register struct state * sp;
register const struct ttinfo * ttisp;
register int i;
const time_t t = *timep;
sp = lclptr;
#ifdef ALL_STATE
! if (sp == NULL) {
! gmtsub(timep, offset, tmp);
! return;
! }
#endif /* defined ALL_STATE */
if (sp->timecnt == 0 || t < sp->ats[0]) {
i = 0;
--- 1043,1055 ----
register struct state * sp;
register const struct ttinfo * ttisp;
register int i;
+ register 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->timecnt == 0 || t < sp->ats[0]) {
i = 0;
***************
*** 1071,1082 ****
** t += ttisp->tt_gmtoff;
** timesub(&t, 0L, sp, tmp);
*/
! timesub(&t, ttisp->tt_gmtoff, sp, tmp);
tmp->tm_isdst = ttisp->tt_isdst;
tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
#ifdef TM_ZONE
tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
#endif /* defined TM_ZONE */
}
struct tm *
--- 1071,1083 ----
** t += ttisp->tt_gmtoff;
** timesub(&t, 0L, sp, tmp);
*/
! result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
tmp->tm_isdst = ttisp->tt_isdst;
tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
#ifdef TM_ZONE
tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
#endif /* defined TM_ZONE */
+ return result;
}
struct tm *
***************
*** 1084,1091 ****
const time_t * const timep;
{
tzset();
! localsub(timep, 0L, &tm);
! return &tm;
}
/*
--- 1085,1091 ----
const time_t * const timep;
{
tzset();
! return localsub(timep, 0L, &tm);
}
/*
***************
*** 1097,1104 ****
const time_t * const timep;
struct tm * tm;
{
! localsub(timep, 0L, tm);
! return tm;
}
/*
--- 1097,1103 ----
const time_t * const timep;
struct tm * tm;
{
! return localsub(timep, 0L, tm);
}
/*
***************
*** 1105,1116 ****
** gmtsub is to gmtime as localsub is to localtime.
*/
! static void
gmtsub(timep, offset, tmp)
const time_t * const timep;
const long offset;
struct tm * const tmp;
{
if (!gmt_is_set) {
gmt_is_set = TRUE;
#ifdef ALL_STATE
--- 1104,1117 ----
** 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;
{
+ register struct tm * result;
+
if (!gmt_is_set) {
gmt_is_set = TRUE;
#ifdef ALL_STATE
***************
*** 1119,1125 ****
#endif /* defined ALL_STATE */
gmtload(gmtptr);
}
! timesub(timep, offset, gmtptr, tmp);
#ifdef TM_ZONE
/*
** Could get fancy here and deliver something such as
--- 1120,1126 ----
#endif /* defined ALL_STATE */
gmtload(gmtptr);
}
! result = timesub(timep, offset, gmtptr, tmp);
#ifdef TM_ZONE
/*
** Could get fancy here and deliver something such as
***************
*** 1139,1144 ****
--- 1140,1146 ----
#endif /* State Farm */
}
#endif /* defined TM_ZONE */
+ return result;
}
struct tm *
***************
*** 1145,1152 ****
gmtime(timep)
const time_t * const timep;
{
! gmtsub(timep, 0L, &tm);
! return &tm;
}
/*
--- 1147,1153 ----
gmtime(timep)
const time_t * const timep;
{
! return gmtsub(timep, 0L, &tm);
}
/*
***************
*** 1158,1165 ****
const time_t * const timep;
struct tm * tm;
{
! gmtsub(timep, 0L, tm);
! return tm;
}
#ifdef STD_INSPIRED
--- 1159,1165 ----
const time_t * const timep;
struct tm * tm;
{
! return gmtsub(timep, 0L, tm);
}
#ifdef STD_INSPIRED
***************
*** 1169,1181 ****
const time_t * const timep;
const long offset;
{
! gmtsub(timep, offset, &tm);
! return &tm;
}
#endif /* defined STD_INSPIRED */
! static void
timesub(timep, offset, sp, tmp)
const time_t * const timep;
const long offset;
--- 1169,1180 ----
const time_t * const timep;
const long offset;
{
! return gmtsub(timep, offset, &tm);
}
#endif /* defined STD_INSPIRED */
! static struct tm *
timesub(timep, offset, sp, tmp)
const time_t * const timep;
const long offset;
***************
*** 1275,1280 ****
--- 1274,1280 ----
#ifdef TM_GMTOFF
tmp->TM_GMTOFF = offset;
#endif /* defined TM_GMTOFF */
+ return tmp;
}
char *
***************
*** 1391,1397 ****
static time_t
time2sub(tmp, funcp, offset, okayp, do_norm_secs)
struct tm * const tmp;
! void (* const funcp) P((const time_t*, long, struct tm*));
const long offset;
int * const okayp;
const int do_norm_secs;
--- 1391,1397 ----
static time_t
time2sub(tmp, funcp, offset, okayp, do_norm_secs)
struct tm * const tmp;
! struct tm * (* const funcp) P((const time_t*, long, struct tm*));
const long offset;
int * const okayp;
const int do_norm_secs;
***************
*** 1486,1492 ****
*/
t = TYPE_SIGNED(time_t) ? 0 : (((unsigned long) 1) << bits);
for ( ; ; ) {
! (*funcp)(&t, offset, &mytm);
dir = tmcomp(&mytm, &yourtm);
if (dir != 0) {
if (bits-- < 0)
--- 1486,1492 ----
*/
t = TYPE_SIGNED(time_t) ? 0 : (((unsigned long) 1) << bits);
for ( ; ; ) {
! /* XXX */ (void) (*funcp)(&t, offset, &mytm);
dir = tmcomp(&mytm, &yourtm);
if (dir != 0) {
if (bits-- < 0)
***************
*** 1524,1530 ****
continue;
newt = t + sp->ttis[j].tt_gmtoff -
sp->ttis[i].tt_gmtoff;
! (*funcp)(&newt, offset, &mytm);
if (tmcomp(&mytm, &yourtm) != 0)
continue;
if (mytm.tm_isdst != yourtm.tm_isdst)
--- 1524,1530 ----
continue;
newt = t + sp->ttis[j].tt_gmtoff -
sp->ttis[i].tt_gmtoff;
! /* XXX */ (void) (*funcp)(&newt, offset,
&mytm);
if (tmcomp(&mytm, &yourtm) != 0)
continue;
if (mytm.tm_isdst != yourtm.tm_isdst)
***************
*** 1543,1550 ****
if ((newt < t) != (saved_seconds < 0))
return WRONG;
t = newt;
! (*funcp)(&t, offset, tmp);
! *okayp = TRUE;
return t;
}
--- 1543,1550 ----
if ((newt < t) != (saved_seconds < 0))
return WRONG;
t = newt;
! if ((*funcp)(&t, offset, tmp))
! *okayp = TRUE;
return t;
}
***************
*** 1551,1557 ****
static time_t
time2(tmp, funcp, offset, okayp)
struct tm * const tmp;
! void (* const funcp) P((const time_t*, long, struct tm*));
const long offset;
int * const okayp;
{
--- 1551,1557 ----
static time_t
time2(tmp, funcp, offset, okayp)
struct tm * const tmp;
! struct tm * (* const funcp) P((const time_t*, long, struct tm*));
const long offset;
int * const okayp;
{
***************
*** 1569,1575 ****
static time_t
time1(tmp, funcp, offset)
struct tm * const tmp;
! void (* const funcp) P((const time_t *, long, struct tm *));
const long offset;
{
register time_t t;
--- 1569,1575 ----
static time_t
time1(tmp, funcp, offset)
struct tm * const tmp;
! struct tm * (* const funcp) P((const time_t *, long, struct tm *));
const long offset;
{
register time_t t;