/* 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 }