This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi, I just applied the below patch to strftime.c. On systems which define the struct tm members __TM_GMTOFF and __TM_ZONE, use them directly for 'z' and 'Z' formats. This is more correct than always using the values from __tzinfo and __tzname, since the latter only reflect the *current* timezone information for *our* timezone. The members of struct tm, on the other hand, may reflect a date of another timezone, or of a timezone which is valid at this time in the past. For Cygwin I had to add a function call because Cygwin has to take backward compatibility into account. Pulling in Cygwin version checks into newlib would certainly have been more ugly than to call into the Cygwin DLL so I think this is the lesser of two evils. Corinna * libc/time/strftime.c (__strftime): Utilize __TM_GMTOFF and __TM_ZONE on systems where available. On Cygwin, call function to get values. Add comment to explain why. Drop TZ_LOCK/TZ_UNLOCK in 'z' case since it's not necessary. In 'Z' case, add a comment to document a potential codeset problem. Index: libc/time/strftime.c =================================================================== RCS file: /cvs/src/src/newlib/libc/time/strftime.c,v retrieving revision 1.23 diff -u -p -r1.23 strftime.c --- libc/time/strftime.c 4 Sep 2014 08:27:03 -0000 1.23 +++ libc/time/strftime.c 8 Jan 2015 09:50:47 -0000 @@ -1283,13 +1283,24 @@ recurse: if (tim_p->tm_isdst >= 0) { long offset; + +#if defined (__CYGWIN__) + /* Cygwin must check if the application has been built with or + without the extra tm members for backward compatibility, and + then use either that or the old method fetching from tzinfo. + Rather than pulling in the version check infrastructure, we + just call a Cygwin function. */ + extern long __cygwin_gettzoffset (const struct tm *tmp); + offset = __cygwin_gettzoffset (tim_p); +#elif defined (__TM_GMTOFF) + offset = tim_p->__TM_GMTOFF; +#else __tzinfo_type *tz = __gettzinfo (); - TZ_LOCK; /* The sign of this is exactly opposite the envvar TZ. We - could directly use the global _timezone for tm_isdst==0, - but have to use __tzrule for daylight savings. */ + could directly use the global _timezone for tm_isdst==0, + but have to use __tzrule for daylight savings. */ offset = -tz->__tzrule[tim_p->tm_isdst > 0].offset; - TZ_UNLOCK; +#endif len = snprintf (&s[count], maxsize - count, CQ("%+03ld%.2ld"), offset / SECSPERHOUR, labs (offset / SECSPERMIN) % 60L); @@ -1300,12 +1311,27 @@ recurse: if (tim_p->tm_isdst >= 0) { size_t size; + const char *tznam; + TZ_LOCK; - size = strlen(_tzname[tim_p->tm_isdst > 0]); +#if defined (__CYGWIN__) + /* See above. */ + extern const char *__cygwin_gettzname (const struct tm *tmp); + tznam = __cygwin_gettzname (tim_p); +#elif defined (__TM_ZONE) + tznam = tim_p->__TM_ZONE; +#else + tznam = _tzname[tim_p->tm_isdst > 0]; +#endif + /* Note that in case of wcsftime this loop only works for + timezone abbreviations using the portable codeset (aka ASCII). + This seems to be the case, but if that ever changes, this + loop needs revisiting. */ + size = strlen (tznam); for (i = 0; i < size; i++) { if (count < maxsize - 1) - s[count++] = _tzname[tim_p->tm_isdst > 0][i]; + s[count++] = tznam[i]; else { TZ_UNLOCK; -- Corinna Vinschen Cygwin Maintainer Red Hat
Attachment:
pgptmMMoZrUpM.pgp
Description: PGP signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |