mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
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 <fionov@gmail.com> for the initial patch. Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
This commit is contained in:
parent
5ba9fde28c
commit
28eda66803
37
lib/util.c
37
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 *
|
||||
|
Loading…
Reference in New Issue
Block a user