Formerly ../time/tzfile.c.~11~
[kopensolaris-gnu/glibc.git] / time / tzfile.c
index cd43018..4b1aff4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -26,6 +26,12 @@ Cambridge, MA 02139, USA.  */
 #define        NOID
 #include <tzfile.h>
 
+#ifndef        HAVE_GNU_LD
+#define        __tzname        tzname
+#define        __daylight      daylight
+#define        __timezone      timezone
+#endif
+
 int __use_tzfile = 0;
 
 struct ttinfo
@@ -108,27 +114,32 @@ DEFUN(__tzfile_read, (file), CONST char *file)
   num_types = (size_t) uc2ul(tzhead.tzh_typecnt);
   chars = (size_t) uc2ul(tzhead.tzh_charcnt);
   num_leaps = (size_t) uc2ul(tzhead.tzh_leapcnt);
-#if 0
   num_isstd = (size_t) uc2ul(tzhead.tzh_ttisstdcnt);
-#else
-  num_isstd = 0;
-#endif
 
-  transitions = (time_t *) malloc(num_transitions * sizeof(time_t));
-  if (transitions == NULL)
-    goto lose;
-  type_idxs = (unsigned char *) malloc(num_transitions);
-  if (type_idxs == NULL)
-    goto lose;
-  types = (struct ttinfo *) malloc(num_types * sizeof(struct ttinfo));
-  if (types == NULL)
-    goto lose;
-  zone_names = (char *) malloc(chars);
-  if (zone_names == NULL)
-    goto lose;
-  if (num_leaps != 0)
+  if (num_transitions > 0)
+    {
+      transitions = (time_t *) malloc (num_transitions * sizeof(time_t));
+      if (transitions == NULL)
+       goto lose;
+      type_idxs = (unsigned char *) malloc (num_transitions);
+      if (type_idxs == NULL)
+       goto lose;
+    }
+  if (num_types > 0)
     {
-      leaps = (struct leap *) malloc(num_leaps * sizeof(struct leap));
+      types = (struct ttinfo *) malloc (num_types * sizeof (struct ttinfo));
+      if (types == NULL)
+       goto lose;
+    }
+  if (chars > 0)
+    {
+      zone_names = (char *) malloc (chars);
+      if (zone_names == NULL)
+       goto lose;
+    }
+  if (num_leaps > 0)
+    {
+      leaps = (struct leap *) malloc (num_leaps * sizeof (struct leap));
       if (leaps == NULL)
        goto lose;
     }
@@ -138,6 +149,9 @@ DEFUN(__tzfile_read, (file), CONST char *file)
       fread((PTR) type_idxs, 1, num_transitions, f) != num_transitions)
     goto lose;
 
+  for (i = 0; i < num_transitions; ++i)
+    transitions[i] = uc2ul (&transitions[i]);
+
   for (i = 0; i < num_types; ++i)
     {
       unsigned char x[4];
@@ -187,14 +201,25 @@ DEFUN(__tzfile_compute, (timer, tm), time_t timer AND struct tm tm)
   struct ttinfo *info;
   register size_t i;
 
-  /* Find the first transition after TIMER, and then go back one.  */
-  i = 0;
-  while (i < num_transitions && transitions[i] < timer)
-    ++i;
-  if (i == num_transitions)
-    i = 0;
+  if (num_transitions == 0 || timer < transitions[0])
+    {
+      /* TIMER is before any transition (or there are no transitions).
+        Choose the first non-DST type
+        (or the first if they're all DST types).  */
+      i = 0;
+      while (i < num_types && types[i].isdst)
+       ++i;
+      if (i == num_types)
+       i = 0;
+    }
   else
-    --i;
+    {
+      /* Find the first transition after TIMER, and then go back one.  */
+      i = 1;
+      while (i < num_transitions && transitions[i] < timer)
+       ++i;
+      --i;
+    }
 
   info = &types[type_idxs[i]];
   __daylight = info->isdst;
@@ -202,6 +227,8 @@ DEFUN(__tzfile_compute, (timer, tm), time_t timer AND struct tm tm)
   for (i = 0; i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]);
        ++i)
     __tzname[types[i].isdst] = &zone_names[types[i].idx];
+  if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0]))
+    __tzname[info->isdst] = &zone_names[info->idx];
 
   i = num_leaps;
   do