This is the mail archive of the cygwin-developers@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

strftime and timezone patch patched


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 <stdio.h>
#include <stdlib.h>
#include <time.h>

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: <CET-1CEST>
tzname[0]: <GMT>
tzname[1]: <   >
timezone(): <GMT+2:00>
strftime(): <Fri Aug 20 00:31:14     1999>

while the expected output would be:

TZ: <CET-1CEST>
tzname[0]: <CET>
tzname[1]: <CEST>
timezone(): <GMT+2:00>
strftime(): <Fri Aug 20 00:31:14 CEST 1999>

Regards,
Corinna

ChangeLog:
==========

Thu Aug 20 0:45:00  Corinna Vinschen  <corinna@vinschen.de>

	* 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  <corinna@vinschen.de>

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.
--- 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 <sys/timeb.h>
 #include <utime.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <errno.h>
 #include "winsup.h"
+#include <ctype.h>
 
 #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;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]