(my_strftime): Delay use of *tp values until latest possible point to
authordrepper <drepper>
Fri, 11 Sep 1998 17:48:32 +0000 (17:48 +0000)
committerdrepper <drepper>
Fri, 11 Sep 1998 17:48:32 +0000 (17:48 +0000)
allow partly initialized structures (e.g., from strptime).

time/strftime.c

index f724bf3..594cbbf 100644 (file)
@@ -416,15 +416,25 @@ my_strftime (s, maxsize, format, tp)
 {
   int hour12 = tp->tm_hour;
 #ifdef _NL_CURRENT
-  const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
-  const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
-  const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
-  const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
-  const char *const ampm = _NL_CURRENT (LC_TIME,
-                                       hour12 > 11 ? PM_STR : AM_STR);
-  size_t aw_len = strlen (a_wkday);
-  size_t am_len = strlen (a_month);
-  size_t ap_len = strlen (ampm);
+  /* We cannot make the following values variables since we must dealy
+     the evaluation of these values until really needed since some
+     expressions might not be valid in every situation.  The `struct tm'
+     might be generated by a strptime() call and therefore initialized
+     only a few elements.  Dereference the pointers only if the format
+     requires this.  Then it is ok to fail if the pointers are invalid.  */
+# define a_wkday _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday)
+# define f_wkday _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday)
+# define f_wkday _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday)
+# define a_month _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon)
+# define f_month _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon)
+# define ampm _NL_CURRENT (LC_TIME, hour12 > 11 ? PM_STR : AM_STR)
+
+# define aw_len strlen (a_wkday)
+# define am_len strlen (a_month)
+# define ap_len strlen (ampm)
+
+# define wkday_len strlen (f_wkday)
+# define month_len strlen (f_month)
 #else
 # if !HAVE_STRFTIME
   const char *const f_wkday = weekday_name[tp->tm_wday];
@@ -435,14 +445,12 @@ my_strftime (s, maxsize, format, tp)
   size_t aw_len = 3;
   size_t am_len = 3;
   size_t ap_len = 2;
-# endif
-#endif
-#if defined _NL_CURRENT || !HAVE_STRFTIME
+
   size_t wkday_len = strlen (f_wkday);
   size_t month_len = strlen (f_month);
+# endif
 #endif
   const char *zone;
-  size_t zonelen;
   size_t i = 0;
   char *p = s;
   const char *f;
@@ -457,21 +465,12 @@ my_strftime (s, maxsize, format, tp)
      POSIX does not require it.  Do the right thing instead.  */
   zone = (const char *) tp->tm_zone;
 #endif
-#if HAVE_TZNAME
+#if HAVE_TZNAME && HAVE_TZSET
   /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
      time zone names contained in the external variable `tzname' shall
      be set as if the tzset() function had been called.  */
-# if HAVE_TZSET
   tzset ();
-# endif
-
-  if (!(zone && *zone) && tp->tm_isdst >= 0)
-    zone = tzname[tp->tm_isdst];
 #endif
-  if (! zone)
-    zone = "";         /* POSIX.2 requires the empty string here.  */
-
-  zonelen = strlen (zone);
 
   if (hour12 > 12)
     hour12 -= 12;
@@ -1146,7 +1145,16 @@ my_strftime (s, maxsize, format, tp)
              to_uppcase = 0;
              to_lowcase = 1;
            }
-         cpy (zonelen, zone);
+
+#if HAVE_TZNAME
+         /* The tzset() call might have changed the value.  */
+         if (!(zone && *zone) && tp->tm_isdst >= 0)
+           zone = tzname[tp->tm_isdst];
+#endif
+         if (! zone)
+           zone = "";          /* POSIX.2 requires the empty string here.  */
+
+         cpy (strlen (zone), zone);
          break;
 
        case 'z':               /* GNU extension.  */