[tz] Rerun of proposed localtime.c changes

Arthur David Olson arthurdavidolson at gmail.com
Sun Nov 25 21:56:52 UTC 2012


Now that silly season seems to be over, two reruns. First, changes to
localtime.c (both attached and below, with tabs mangled).
These are designed to address two issues noted earlier this year by Doug
Bailey: ensuring that "tzname" values are set, and
getting proper behavior when the software is being run on an
unsigned-time_t system but is using data files generated on a
signed-time_t system. These changes have been updated to be relative to
tz2012j.

        --ado

*** tz2012j/localtime.c    2012-10-26 20:37:42.000000000 -0400
--- tznew/localtime.c    2012-11-25 16:11:23.833188100 -0500
***************
*** 271,276 ****
--- 271,281 ----
      /*
      ** And to get the latest zone names into tzname. . .
      */
+     for (i = 0; i < sp->typecnt; ++i) {
+         register const struct ttinfo * const    ttisp = &sp->ttis[i];
+
+         tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
+     }
      for (i = 0; i < sp->timecnt; ++i) {
          register const struct ttinfo * const    ttisp =
                              &sp->ttis[
***************
*** 479,498 ****
          ** signed time_t system but using a data file with
          ** unsigned values (or vice versa).
          */
!         for (i = 0; i < sp->timecnt - 2; ++i)
!             if (sp->ats[i] > sp->ats[i + 1]) {
!                 ++i;
                  if (TYPE_SIGNED(time_t)) {
                      /*
                      ** Ignore the end (easy).
                      */
!                     sp->timecnt = i;
                  } else {
                      /*
                      ** Ignore the beginning (harder).
                      */
                      register int    j;

                      for (j = 0; j + i < sp->timecnt; ++j) {
                          sp->ats[j] = sp->ats[j + i];
                          sp->types[j] = sp->types[j + i];
--- 484,514 ----
          ** signed time_t system but using a data file with
          ** unsigned values (or vice versa).
          */
!         for (i = 0; i < sp->timecnt; ++i)
!             if ((i < sp->timecnt - 1 &&
!                 sp->ats[i] > sp->ats[i + 1]) ||
!                 (i == sp->timecnt - 1 && !TYPE_SIGNED(time_t) &&
!                 sp->ats[i] >
!                 ((stored == 4) ? INT32_MAX : INT64_MAX))) {
                  if (TYPE_SIGNED(time_t)) {
                      /*
                      ** Ignore the end (easy).
                      */
!                     sp->timecnt = i + 1;
                  } else {
                      /*
                      ** Ignore the beginning (harder).
                      */
                      register int    j;

+                     /*
+                     ** Keep the record right before the
+                     ** epoch boundary,
+                     ** but tweak it so that it starts
+                     ** right with the epoch
+                     ** (thanks to Doug Bailey).
+                     */
+                     sp->ats[i] = 0;
                      for (j = 0; j + i < sp->timecnt; ++j) {
                          sp->ats[j] = sp->ats[j + i];
                          sp->types[j] = sp->types[j + i];
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mm.icann.org/pipermail/tz/attachments/20121125/a7f46068/attachment.htm>
-------------- next part --------------
*** tz2012j/localtime.c	2012-10-26 20:37:42.000000000 -0400
--- tznew/localtime.c	2012-11-25 16:11:23.833188100 -0500
***************
*** 271,276 ****
--- 271,281 ----
  	/*
  	** And to get the latest zone names into tzname. . .
  	*/
+ 	for (i = 0; i < sp->typecnt; ++i) {
+ 		register const struct ttinfo * const	ttisp = &sp->ttis[i];
+ 
+ 		tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
+ 	}	
  	for (i = 0; i < sp->timecnt; ++i) {
  		register const struct ttinfo * const	ttisp =
  							&sp->ttis[
***************
*** 479,498 ****
  		** signed time_t system but using a data file with
  		** unsigned values (or vice versa).
  		*/
! 		for (i = 0; i < sp->timecnt - 2; ++i)
! 			if (sp->ats[i] > sp->ats[i + 1]) {
! 				++i;
  				if (TYPE_SIGNED(time_t)) {
  					/*
  					** Ignore the end (easy).
  					*/
! 					sp->timecnt = i;
  				} else {
  					/*
  					** Ignore the beginning (harder).
  					*/
  					register int	j;
  
  					for (j = 0; j + i < sp->timecnt; ++j) {
  						sp->ats[j] = sp->ats[j + i];
  						sp->types[j] = sp->types[j + i];
--- 484,514 ----
  		** signed time_t system but using a data file with
  		** unsigned values (or vice versa).
  		*/
! 		for (i = 0; i < sp->timecnt; ++i)
! 			if ((i < sp->timecnt - 1 &&
! 			    sp->ats[i] > sp->ats[i + 1]) ||
! 			    (i == sp->timecnt - 1 && !TYPE_SIGNED(time_t) &&
! 			    sp->ats[i] >
! 			    ((stored == 4) ? INT32_MAX : INT64_MAX))) {
  				if (TYPE_SIGNED(time_t)) {
  					/*
  					** Ignore the end (easy).
  					*/
! 					sp->timecnt = i + 1;
  				} else {
  					/*
  					** Ignore the beginning (harder).
  					*/
  					register int	j;
  
+ 					/*
+ 					** Keep the record right before the
+ 					** epoch boundary,
+ 					** but tweak it so that it starts
+ 					** right with the epoch
+ 					** (thanks to Doug Bailey).
+ 					*/
+ 					sp->ats[i] = 0;
  					for (j = 0; j + i < sp->timecnt; ++j) {
  						sp->ats[j] = sp->ats[j + i];
  						sp->types[j] = sp->types[j + i];


More information about the tz mailing list