This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Avoid unnecessary multiple tzset calls in strftime (BZ #5184)


Hi!

For one strftime_l call it is enough to call tzset just once, if we recurse
there is no reason to repeat that.
As an additional cleanup the internal routine could be perhaps renamed
and exported as hidden, so that strftime and wcstime could save 2 insns or
so.  But that can IMHO be done later on.

2007-10-16  Jakub Jelinek  <jakub@redhat.com>

	[BZ #5184]
	* time/strftime_l.c: Include stdbool.h.
	(my_strftime): New wrapper, old function renamed to...
	(__strftime_internal): ... new function.  Add tzset_called
	argument, pass it down to recursive calls, don't call tzset ()
	if already true, set to true after call to tzset ().

--- libc/time/strftime_l.c.jj	2004-09-14 06:24:53.000000000 +0200
+++ libc/time/strftime_l.c	2007-10-16 19:44:17.000000000 +0200
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2004, 2007 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
@@ -84,6 +84,7 @@ extern char *tzname[];
 # include <stddef.h>
 # include <stdlib.h>
 # include <string.h>
+# include <stdbool.h>
 #else
 # ifndef HAVE_MEMCPY
 #  define memcpy(d, s, n) bcopy ((s), (d), (n))
@@ -453,27 +454,9 @@ static CHAR_T const month_name[][10] =
 # define ut 0
 #endif
 
-#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
-  /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
-     Work around this bug by copying *tp before it might be munged.  */
-  size_t _strftime_copytm (char *, size_t, const char *,
-			   const struct tm * ut_argument_spec_iso) __THROW;
-  size_t
-  my_strftime (s, maxsize, format, tp ut_argument)
-      CHAR_T *s;
-      size_t maxsize;
-      const CHAR_T *format;
-      const struct tm *tp;
-      ut_argument_spec
-  {
-    struct tm tmcopy;
-    tmcopy = *tp;
-    return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument);
-  }
-# undef my_strftime
-# define my_strftime _strftime_copytm
-#endif
-
+static size_t __strftime_internal (CHAR_T *, size_t, const CHAR_T *,
+				   const struct tm *, bool ut_argument_spec_iso
+				   LOCALE_PARAM_PROTO) __THROW;
 
 /* Write information from TP into S according to the format
    string FORMAT, writing no more that MAXSIZE characters
@@ -481,12 +464,38 @@ static CHAR_T const month_name[][10] =
    characters written.  If S is NULL, nothing will be written
    anywhere, so to determine how many characters would be
    written, use NULL for S and (size_t) UINT_MAX for MAXSIZE.  */
+
 size_t
 my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
+     CHAR_T *s;
+     size_t maxsize;
+     const CHAR_T *format;
+     const struct tm *tp;
+     ut_argument_spec
+     LOCALE_PARAM_DECL
+{
+#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
+  /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
+     Work around this bug by copying *tp before it might be munged.  */
+  struct tm tmcopy;
+  tmcopy = *tp;
+  tp = &tmcopy;
+#endif
+  return __strftime_internal (s, maxsize, format, tp, false
+			      ut_argument LOCALE_ARG);
+}
+#ifdef _LIBC
+libc_hidden_def (my_strftime)
+#endif
+
+static size_t
+__strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+		     LOCALE_PARAM)
       CHAR_T *s;
       size_t maxsize;
       const CHAR_T *format;
       const struct tm *tp;
+      bool tzset_called;
       ut_argument_spec
       LOCALE_PARAM_DECL
 {
@@ -559,7 +568,9 @@ my_strftime (s, maxsize, format, tp ut_a
       /* POSIX.1 requires that local time zone information is used as
 	 though strftime called tzset.  */
 # if HAVE_TZSET
-      tzset ();
+      if (!tzset_called)
+	tzset ();
+      tzset_called = true;
 # endif
     }
 #endif
@@ -834,10 +845,12 @@ my_strftime (s, maxsize, format, tp ut_a
 	subformat:
 	  {
 	    CHAR_T *old_start = p;
-	    size_t len = my_strftime (NULL, (size_t) -1, subfmt,
-				      tp ut_argument LOCALE_ARG);
-	    add (len, my_strftime (p, maxsize - i, subfmt,
-				   tp ut_argument LOCALE_ARG));
+	    size_t len = __strftime_internal (NULL, (size_t) -1, subfmt,
+					      tp, tzset_called ut_argument
+					      LOCALE_ARG);
+	    add (len, __strftime_internal (p, maxsize - i, subfmt,
+					   tp, tzset_called ut_argument
+					   LOCALE_ARG));
 
 	    if (to_uppcase)
 	      while (old_start < p)
@@ -1409,9 +1422,6 @@ my_strftime (s, maxsize, format, tp ut_a
     *p = L_('\0');
   return i;
 }
-#ifdef _LIBC
-libc_hidden_def (my_strftime)
-#endif
 
 
 #ifdef emacs

	Jakub


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