From 28eda668032a73e2a433d84b23b8e2a92d04663f Mon Sep 17 00:00:00 2001 From: "Yury V. Zaytsev" Date: Sun, 2 May 2010 13:07:16 +0200 Subject: [PATCH] Ticket #1671: i18n_checktimelength may vary depending on the season On some systems i18n_checktimelength may vary not only depending on the locale but also on the current month. This patch introduces a cyclic check that loops through all of the months to find out which one has the longest name. However, since this function is called on every pannel reload and now makes 24 calls to str_term_width1 and strftime it makes sense to introduce a cache for the resulting value. Thanks to Sergey Fionov for the initial patch. Signed-off-by: Yury V. Zaytsev --- lib/util.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/util.c b/lib/util.c index 406becced..2b7576198 100644 --- a/lib/util.c +++ b/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 *