Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Unsubscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com Message-ID: <37BC8D4A.7D8C6F55@vinschen.de> Date: Fri, 20 Aug 1999 01:03:38 +0200 From: Corinna Vinschen X-Mailer: Mozilla 4.6 [en] (WinNT; I) X-Accept-Language: de,en MIME-Version: 1.0 To: DJ Delorie CC: cygdev Subject: strftime and timezone patch patched References: <199908190308 DOT XAA11621 AT envy DOT delorie DOT com> Content-Type: multipart/mixed; boundary="------------0F06452AE8C16D0309FBDE85" This is a multi-part message in MIME format. --------------0F06452AE8C16D0309FBDE85 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit DJ Delorie wrote: > > This is about the strftime patches you submitted recently; the TZ > variable is allowed to have extra characters after the second zone > name, but your code doesn't appear to support that. > [...] > On Wed, Aug 18, 1999 at 10:06:34PM -0400, DJ Delorie wrote: > >Actually, it will fail with the auto-detected timezone, which is like > >"EST5EDT4,4.2.10/2,10.2.10/1". It needs to do the isalpha() scan for > >the second name also. I have patched it. > >The new localtime.c exports the two timezone names itself, too. The call to cygwin_tzset must be made again. It's currently #if 0'd. The localtime.c code itself results in unsatisfactory output in my timezone. I have a simple test program: ---- snip ---- #include #include #include int main() { time_t t; struct tm *ts; char buf[256]; tzset(); time(&t); ts = localtime(&t); printf("TZ: <%s>\ntzname[0]: <%s>\ntzname[1]: <%s>\ntimezone(): <%s>\n", getenv("TZ"), _tzname[0], _tzname[1], timezone()); strftime(buf, 256, "%a %b %e %H:%M:%S %Z %Y", ts); printf("strftime(): <%s>\n", buf); return 0; } ---- snap ---- results in: TZ: tzname[0]: tzname[1]: < > timezone(): strftime(): while the expected output would be: TZ: tzname[0]: tzname[1]: timezone(): strftime(): Regards, Corinna ChangeLog: ========== Thu Aug 20 0:45:00 Corinna Vinschen * times.cc: Additional scan for the end of the second time string. * localtime.c: calls cygwin_tzset again. Thu Jul 1 14:44:00 Corinna Vinschen shellutils: ----------- * lib/strftime.c: Added define for __CYGWIN__ * config.h.in: define HAVE_TZNAME by default. newlib: ------- * libc/include/time.h: Added preprocessor control path for compile time behaviour. * libc/time/strftime.c (strftime): Calling tzset() as required by POSIX.1. Added support for '%e' (blank padded day of week) as suggested by POSIX.2 (and often used by date(1) command). Added support for '%Z' (timezone string). winsup: ------- * times.cc (cygwin_tzset): examines TZ now. --------------0F06452AE8C16D0309FBDE85 Content-Type: text/plain; charset=us-ascii; name="tz-patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="tz-patch" --- shellutils/lib/strftime.c.old Thu Jul 01 12:58:01 1999 +++ shellutils/lib/strftime.c Thu Jul 01 12:40:29 1999 @@ -50,7 +50,11 @@ # endif #endif #if HAVE_TZNAME +#ifdef __CYGWIN__ +#define tzname _tzname +#else extern char *tzname[]; +#endif #endif /* Do multibyte processing if multibytes are supported, unless --- shellutils/config.h.in.old Thu Jul 01 13:05:07 1999 +++ shellutils/config.h.in Thu Jul 01 13:33:42 1999 @@ -53,7 +53,7 @@ /* Define if you don't have tm_zone but do have the external array tzname. */ -#undef HAVE_TZNAME +#define HAVE_TZNAME 1 /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF --- newlib/libc/include/time.h.old Thu Jul 01 12:04:26 1999 +++ newlib/libc/include/time.h Thu Jul 01 12:02:48 1999 @@ -73,6 +73,11 @@ struct tm *_EXFUN(gmtime_r, (const time_ struct tm *_EXFUN(localtime_r, (const time_t *, struct tm *)); #ifdef __CYGWIN32__ +#ifdef _COMPILING_NEWLIB +extern time_t _timezone; +extern int _daylight; +extern char *_tzname[2]; +#else #ifndef __STRICT_ANSI__ extern time_t _timezone __declspec(dllimport); extern int _daylight __declspec(dllimport); @@ -80,6 +85,7 @@ extern char *_tzname[2] __declspec(dllim char *_EXFUN(timezone, (void)); void _EXFUN(tzset, (void)); +#endif #endif #endif /* __CYGWIN32__ */ --- newlib/libc/time/strftime.c.old Thu Jul 01 11:30:20 1999 +++ newlib/libc/time/strftime.c Thu Jul 01 13:19:52 1999 @@ -168,6 +168,9 @@ _DEFUN (strftime, (s, maxsize, format, t size_t count = 0; int i; + /* POSIX.1 8.1.1 requires setting of tzname whenever strftime is called */ + tzset (); + for (;;) { while (*format && *format != '%') @@ -256,6 +259,16 @@ _DEFUN (strftime, (s, maxsize, format, t else return 0; break; + case 'e': + if (count < maxsize - 2) + { + sprintf (&s[count], "%2d", + tim_p->tm_mday); + count += 2; + } + else + return 0; + break; case 'H': if (count < maxsize - 2) { @@ -425,6 +438,11 @@ _DEFUN (strftime, (s, maxsize, format, t return 0; break; case 'Z': + if (count < maxsize - strlen (_tzname[tim_p->tm_isdst])) + { + strcpy (&s[count], _tzname[tim_p->tm_isdst]); + count += strlen (_tzname[tim_p->tm_isdst]); + } break; case '%': if (count < maxsize - 1) --- winsup/localtime.c 1999/08/19 19:42:56 1.1.1.1 +++ winsup/localtime.c 1999/08/19 22:38:14 @@ -1485,7 +1485,7 @@ tzset P((void)) { const char * name = getenv("TZ"); -#if 0 /* we set it more accurately in tzsetwall() */ +#if 1 /* we set it more accurately in tzsetwall() */ #if defined(__CYGWIN32__) || defined(__CYGWIN__) static char b[20]; DWORD tzid; --- winsup/times.cc 1999/08/19 19:42:59 1.1.1.1 +++ winsup/times.cc 1999/08/19 22:08:38 @@ -13,8 +13,10 @@ details. */ #include #include #include +#include #include #include "winsup.h" +#include #define FACTOR (0x19db1ded53ea710LL) #define NSPERSEC 10000000LL @@ -585,10 +587,6 @@ cygwin_tzset () static NO_COPY char buf2[33] = {0}; #endif - /* FIXME: This function should examine the TZ environment variable. - Right now it just always sets information based on the system - time zone. */ - DWORD tzid; TIME_ZONE_INFORMATION tz; @@ -599,12 +597,37 @@ cygwin_tzset () else _timezone = (tz.Bias + tz.StandardBias) * SECSPERMIN; _daylight = (tzid == TIME_ZONE_ID_DAYLIGHT); - WideCharToMultiByte (CP_ACP, 0, tz.StandardName, -1, buf1, sizeof buf1 - 1, - NULL, NULL); - buf1[sizeof buf1 - 1] = '\0'; + + char *tzv = getenv ("TZ"); + + if (tzv) + { + if (*tzv == ':') + ++tzv; + strcpy (buf1, tzv); + for (tzv = buf1; *tzv && isalpha (*tzv); ++tzv) + ; + if (*tzv) + { + for (*tzv++ = '\0'; *tzv && ! isalpha (*tzv); ++tzv) + ; + strcpy (buf2, tzv); + for (tzv = buf2; *tzv && isalpha (*tzv); ++tzv) + ; + *tzv = '\0'; + } + else + buf2[0] = '\0'; + } + else + { + WideCharToMultiByte (CP_ACP, 0, tz.StandardName, -1, buf1, + sizeof buf1 - 1, NULL, NULL); + buf1[sizeof buf1 - 1] = '\0'; + WideCharToMultiByte (CP_ACP, 0, tz.DaylightName, -1, buf2, + sizeof buf2 - 1, NULL, NULL); + buf2[sizeof buf2 - 1] = '\0'; + } _tzname[0] = buf1; - WideCharToMultiByte (CP_ACP, 0, tz.DaylightName, -1, buf2, sizeof buf2 - 1, - NULL, NULL); - buf2[sizeof buf2 - 1] = '\0'; _tzname[1] = buf2; } --------------0F06452AE8C16D0309FBDE85--