Browse Source

Merge branch '1671_i18n_checktimelength'

* 1671_i18n_checktimelength:
  Ticket #1671: i18n_checktimelength may vary depending on the season
Yury V. Zaytsev 15 years ago
parent
commit
66ff918624
1 changed files with 27 additions and 10 deletions
  1. 27 10
      lib/util.c

+ 27 - 10
lib/util.c

@@ -67,6 +67,13 @@ int kilobyte_si = 0;
 char *user_recent_timeformat = NULL;    /* time format string for recent dates */
 char *user_old_timeformat = NULL;       /* time format string for older dates */
 
+/*
+ * Cache variable for the i18n_checktimelength function,
+ * initially set to a clearly invalid value to show that
+ * it hasn't been initialized yet.
+ */
+static size_t i18n_timelength_cache = MAX_I18NTIMELENGTH + 1;
+
 extern void
 str_replace (char *s, char from, char to)
 {
@@ -690,14 +697,17 @@ load_mc_home_file (const char *_mc_home, const char *_mc_home_alt, const char *f
 }
 
 /* Check strftime() results. Some systems (i.e. Solaris) have different
-   short-month-name sizes for different locales */
+   short-month and month name sizes for different locales */
 size_t
 i18n_checktimelength (void)
 {
-    size_t length;
-    time_t testtime = time (NULL);
+    size_t length = 0;
+    const time_t testtime = time (NULL);
     struct tm *lt = localtime (&testtime);
 
+    if (i18n_timelength_cache <= MAX_I18NTIMELENGTH)
+        return i18n_timelength_cache;
+
     if (lt == NULL)
     {
         /* huh, localtime() doesnt seem to work ... falling back to "(invalid)" */
@@ -706,14 +716,18 @@ i18n_checktimelength (void)
     else
     {
         char buf[MB_LEN_MAX * MAX_I18NTIMELENGTH + 1];
-        size_t a, b;
 
-        strftime (buf, sizeof (buf) - 1, user_recent_timeformat, lt);
-        a = str_term_width1 (buf);
-        strftime (buf, sizeof (buf) - 1, user_old_timeformat, lt);
-        b = str_term_width1 (buf);
+        /* We are interested in the longest possible date */
+        lt->tm_sec = lt->tm_min = lt->tm_hour = lt->tm_mday = 10;
+
+        /* Loop through all months to find out the longest one */
+        for (lt->tm_mon = 0; lt->tm_mon < 12; lt->tm_mon++) {
+            strftime (buf, sizeof(buf) - 1, user_recent_timeformat, lt);
+            length = max ((size_t) str_term_width1 (buf), length);
+            strftime (buf, sizeof(buf) - 1, user_old_timeformat, lt);
+            length = max ((size_t) str_term_width1 (buf), length);
+        }
 
-        length = max (a, b);
         length = max ((size_t) str_term_width1 (_(INVALID_TIME_TEXT)), length);
     }
 
@@ -721,7 +735,10 @@ i18n_checktimelength (void)
     if (length > MAX_I18NTIMELENGTH || length < MIN_I18NTIMELENGTH)
         length = STD_I18NTIMELENGTH;
 
-    return length;
+    /* Save obtained value to the cache */
+    i18n_timelength_cache = length;
+
+    return i18n_timelength_cache;
 }
 
 const char *