/* the next two functions are implicitely thread safe,
as they are only called by setup() which uses a mutex.
*/
static void setupLocaleMapper()
{
#ifdef Q_OS_WIN32
localeMapper = QTextCodec::codecForName("System");
#else
#if defined (_XOPEN_UNIX) && !defined(Q_OS_QNX6) && !defined(Q_OS_OSF) && !defined(Q_OS_MAC)
char *charset = nl_langinfo (CODESET);
if (charset)
localeMapper = QTextCodec::codecForName(charset);
#endif
if (!localeMapper) {
// Very poorly defined and followed standards causes lots of code
// to try to get all the cases...
// Try to determine locale codeset from locale name assigned to
// LC_CTYPE category.
// First part is getting that locale name. First try setlocale() which
// definitely knows it, but since we cannot fully trust it, get ready
// to fall back to environment variables.
char * ctype = qstrdup(setlocale(LC_CTYPE, 0));
// Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG
// environment variables.
char * lang = qstrdup(qgetenv("LC_ALL").constData());
if (!lang || lang[0] == 0 || strcmp(lang, "C") == 0) {
if (lang) delete [] lang;
lang = qstrdup(qgetenv("LC_CTYPE").constData());
}
if (!lang || lang[0] == 0 || strcmp(lang, "C") == 0) {
if (lang) delete [] lang;
lang = qstrdup(qgetenv("LANG").constData());
}
// Now try these in order:
// 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15)
// 2. CODESET from lang if it contains a .CODESET part
// 3. ctype (maybe the locale is named "ISO-8859-1" or something)
// 4. locale (ditto)
// 5. check for "@euro"
// 6. guess locale from ctype unless ctype is "C"
// 7. guess locale from lang
// 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15)
char * codeset = ctype ? strchr(ctype, '.') : 0;
if (codeset && *codeset == '.')
localeMapper = checkForCodec(codeset + 1);
// 2. CODESET from lang if it contains a .CODESET part
codeset = lang ? strchr(lang, '.') : 0;
if (!localeMapper && codeset && *codeset == '.')
localeMapper = checkForCodec(codeset + 1);
// 3. ctype (maybe the locale is named "ISO-8859-1" or something)
if (!localeMapper && ctype && *ctype != 0 && strcmp (ctype, "C") != 0)
localeMapper = checkForCodec(ctype);
// 4. locale (ditto)
if (!localeMapper && lang && *lang != 0)
localeMapper = checkForCodec(lang);
// 5. "@euro"
if (!localeMapper && ctype && strstr(ctype, "@euro") || lang && strstr(lang, "@euro"))
localeMapper = checkForCodec("ISO 8859-15");
// 6. guess locale from ctype unless ctype is "C"
// 7. guess locale from lang
char * try_by_name = ctype;
if (ctype && *ctype != 0 && strcmp (ctype, "C") != 0)
try_by_name = lang;
// Now do the guessing.
if (lang && *lang && !localeMapper && try_by_name && *try_by_name) {
if (try_locale_list(iso8859_15locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-15");
else if (try_locale_list(iso8859_2locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-2");
else if (try_locale_list(iso8859_3locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-3");
else if (try_locale_list(iso8859_4locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-4");
else if (try_locale_list(iso8859_5locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-5");
else if (try_locale_list(iso8859_6locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-6");
else if (try_locale_list(iso8859_7locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-7");
else if (try_locale_list(iso8859_8locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-8-I");
else if (try_locale_list(iso8859_9locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-9");
else if (try_locale_list(iso8859_13locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-13");
else if (try_locale_list(tis_620locales, lang))
localeMapper = QTextCodec::codecForName("ISO 8859-11");
else if (try_locale_list(koi8_ulocales, lang))
localeMapper = QTextCodec::codecForName("KOI8-U");
else if (try_locale_list(cp_1251locales, lang))
localeMapper = QTextCodec::codecForName("CP 1251");
else if (try_locale_list(pt_154locales, lang))
localeMapper = QTextCodec::codecForName("PT 154");
else if (try_locale_list(probably_koi8_rlocales, lang))
localeMapper = ru_RU_hack(lang);
}
delete [] ctype;
delete [] lang;
}
// If everything failed, we default to 8859-1
// We could perhaps default to 8859-15.
if (!localeMapper)
localeMapper = QTextCodec::codecForName("ISO 8859-1");
#endif
}