Proposed changes to asctime.c, zdump.c, and localtime.c

Olson, Arthur David (NIH/NCI) olsona at dc37a.nci.nih.gov
Mon Dec 27 14:26:15 UTC 2004


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 at 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 at 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;



More information about the tz mailing list