small bug fix and ugliness concentration

Hello, There there were 2 copies of the USG_COMPAT/ALTZONE ugliness and one was incomplete (did not set daylight). I merged them. christos --- localtime.c.orig 2014-10-18 14:07:54.000000000 -0400 +++ localtime.c 2014-11-11 13:39:18.000000000 -0500 @@ -235,6 +235,27 @@ return result; } +static char * +setzone(struct state const *sp, const struct ttinfo *ttisp, int_fast32_t offset) +{ + char *zn = (char *)&sp->chars[ttisp->tt_abbrind]; + if (offset) { +#ifdef USG_COMPAT + if (ttisp->tt_isdst) + daylight = 1; + if (!ttisp->tt_isdst) + timezone = -(ttisp->tt_gmtoff); +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + if (ttisp->tt_isdst) + altzone = -(ttisp->tt_gmtoff); +#endif /* defined ALTZONE */ + } + + tzname[ttisp->tt_isdst] = zn; + return zn; +} + static void settzname(void) { @@ -261,24 +282,8 @@ tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind]; } - for (i = 0; i < sp->timecnt; ++i) { - register const struct ttinfo * const ttisp = - &sp->ttis[ - sp->types[i]]; - - tzname[ttisp->tt_isdst] = - &sp->chars[ttisp->tt_abbrind]; -#ifdef USG_COMPAT - if (ttisp->tt_isdst) - daylight = 1; - if (!ttisp->tt_isdst) - timezone = -(ttisp->tt_gmtoff); -#endif /* defined USG_COMPAT */ -#ifdef ALTZONE - if (ttisp->tt_isdst) - altzone = -(ttisp->tt_gmtoff); -#endif /* defined ALTZONE */ - } + for (i = 0; i < sp->timecnt; ++i) + setzone(sp, &sp->ttis[i], -1); /* ** Finally, scrub the abbreviations. ** First, replace bogus characters. @@ -1393,26 +1398,11 @@ */ result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); if (result) { - bool tm_isdst = ttisp->tt_isdst; - char *tm_zone = (char *) &sp->chars[ttisp->tt_abbrind]; - result->tm_isdst = tm_isdst; + char *zn = setzone(sp, ttisp, offset); + result->tm_isdst = ttisp->tt_isdst; #ifdef TM_ZONE - result->TM_ZONE = tm_zone; + result->TM_ZONE = zn; #endif /* defined TM_ZONE */ - if (offset) { - /* Always set the tzname etc. vars whose values can easily - be determined, as it's too much trouble to tell whether - tzset has already done it correctly. */ - tzname[tm_isdst] = tm_zone; -#ifdef USG_COMPAT - if (!tm_isdst) - timezone = - ttisp->tt_gmtoff; -#endif -#ifdef ALTZONE - if (tm_isdst) - altzone = - ttisp->tt_gmtoff; -#endif - } } return result; }

Christos Zoulas wrote:
There there were 2 copies of the USG_COMPAT/ALTZONE ugliness and one was incomplete (did not set daylight).
It wasn't incomplete, as there is no need to set 'daylight' for a particular time stamp. 'daylight' is a property of the entire time zone setting, not of one particular time stamp using that setting. That being said, your suggestion simplifies the code, so I fixed it up and applied the attached proposed patch. I noticed a related tzalloc bug while looking into this, and will follow up with another proposed patch.

* localtime.c (settzname): Move scrubbing into ... (scrub_abbrs): ... this new function. (zoneinit): Use it here, rather than in settzname. * NEWS: Document this. --- NEWS | 9 +++++++++ localtime.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 98b6e8c..a2ef695 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,14 @@ News for the tz database +Unreleased, experimental changes + + Changes affecting code + + tzalloc now scrubs time zone abbreviations compatibly with the way + that tzset always has, by replacing invalid bytes with '_' and by + shortening too-long abbreviations. + + Release 2014j - 2014-11-10 17:37:11 -0800 Changes affecting current and future time stamps diff --git a/localtime.c b/localtime.c index 5551707..f44390a 100644 --- a/localtime.c +++ b/localtime.c @@ -284,8 +284,13 @@ settzname(void) daylight = 1; #endif /* defined USG_COMPAT */ } +} + +static void +scrub_abbrs(struct state *sp) +{ + int i; /* - ** Finally, scrub the abbreviations. ** First, replace bogus characters. */ for (i = 0; i < sp->charcnt; ++i) @@ -1209,7 +1214,9 @@ zoneinit(struct state *sp, char const *name) } else { int err = tzload(name, sp, true); if (err != 0 && name && name[0] != ':' && tzparse(name, sp, false)) - return 0; + err = 0; + if (err == 0) + scrub_abbrs(sp); return err; } } -- 2.1.0
participants (2)
-
christos@zoulas.com
-
Paul Eggert