summaryrefslogtreecommitdiff
path: root/time/strftime.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-09-11 17:48:44 +0000
committerUlrich Drepper <drepper@redhat.com>1998-09-11 17:48:44 +0000
commit81e0cb2da50c12ebafed2e17c1df0cc26c8bad3e (patch)
treeb345b8ac5490615e1002bb07578f877277eda488 /time/strftime.c
parentec04e9baf6def57a05da896ff89acc95c1840fc7 (diff)
downloadglibc-81e0cb2da50c12ebafed2e17c1df0cc26c8bad3e.tar.gz
Update.
* time/strftime.c (my_strftime): Delay use of *tp values until latest possible point to allow partly initialized structures (e.g., from strptime). * sysdeps/unix/sysv/linux/init-first.c [!PIC]: Define __libc_init_first using init-first.h. 1998-04-30 18:20 H.J. Lu <hjl@gnu.org> * elf/dl-load.c (_dl_init_paths): Don't check the dynamic loader if PIC is not defined. 1998-09-11 Ulrich Drepper <drepper@cygnus.com>
Diffstat (limited to 'time/strftime.c')
-rw-r--r--time/strftime.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/time/strftime.c b/time/strftime.c
index f724bf3e3b..594cbbfe16 100644
--- a/time/strftime.c
+++ b/time/strftime.c
@@ -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. */