rendered paste body#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
/* locale names mostly copied from XFree86 */
static const char * const iso8859_2locales[] = {
"croatian", "cs", "cs_CS", "cs_CZ","cz", "cz_CZ", "czech", "hr",
"hr_HR", "hu", "hu_HU", "hungarian", "pl", "pl_PL", "polish", "ro",
"ro_RO", "rumanian", "serbocroatian", "sh", "sh_SP", "sh_YU", "sk",
"sk_SK", "sl", "sl_CS", "sl_SI", "slovak", "slovene", "sr_SP", 0 };
static const char * const iso8859_3locales[] = {
"eo", 0 };
static const char * const iso8859_4locales[] = {
"ee", "ee_EE", 0 };
static const char * const iso8859_5locales[] = {
"mk", "mk_MK", "sp", "sp_YU", 0 };
static const char * const cp_1251locales[] = {
"be", "be_BY", "bg", "bg_BG", "bulgarian", 0 };
static const char * const pt_154locales[] = {
"ba_RU", "ky", "ky_KG", "kk", "kk_KZ", 0 };
static const char * const iso8859_6locales[] = {
"ar_AA", "ar_SA", "arabic", 0 };
static const char * const iso8859_7locales[] = {
"el", "el_GR", "greek", 0 };
static const char * const iso8859_8locales[] = {
"hebrew", "he", "he_IL", "iw", "iw_IL", 0 };
static const char * const iso8859_9locales[] = {
"tr", "tr_TR", "turkish", 0 };
static const char * const iso8859_13locales[] = {
"lt", "lt_LT", "lv", "lv_LV", 0 };
static const char * const iso8859_15locales[] = {
"et", "et_EE",
// Euro countries
"br_FR", "ca_ES", "de", "de_AT", "de_BE", "de_DE", "de_LU", "en_IE",
"es", "es_ES", "eu_ES", "fi", "fi_FI", "finnish", "fr", "fr_FR",
"fr_BE", "fr_LU", "french", "ga_IE", "gl_ES", "it", "it_IT", "oc_FR",
"nl", "nl_BE", "nl_NL", "pt", "pt_PT", "sv_FI", "wa_BE",
0 };
static const char * const koi8_ulocales[] = {
"uk", "uk_UA", "ru_UA", "ukrainian", 0 };
static const char * const tis_620locales[] = {
"th", "th_TH", "thai", 0 };
// static const char * const tcvnlocales[] = {
// "vi", "vi_VN", 0 };
static bool try_locale_list(const char * const locale[], const char * lang)
{
int i;
for(i=0; locale[i] && *locale[i] && strcmp(locale[i], lang); i++)
;
return locale[i] != 0;
}
char* save_strdup(const char* src) {
if (src)
return strdup(src);
return 0;
}
int checkForCodec(const char* codec) {
printf("checkForCodec: %s\n", codec);
return 0;
}
int codecForName(const char* name) {
printf("codecForName: %s\n", name);
return 0;
}
int main() {
int localeMapper = 0;
// 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 = save_strdup(setlocale(LC_CTYPE, 0));
// Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG
// environment variables.
char * lang = save_strdup(getenv("LC_ALL"));
if (!lang || lang[0] == 0 || strcmp(lang, "C") == 0) {
if (lang) delete[](lang);
lang = save_strdup(getenv("LC_CTYPE"));
}
if (!lang || lang[0] == 0 || strcmp(lang, "C") == 0) {
if (lang) delete[](lang);
lang = save_strdup(getenv("LANG"));
}
// 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 = codecForName("ISO 8859-15");
else if (try_locale_list(iso8859_2locales, lang))
localeMapper = codecForName("ISO 8859-2");
else if (try_locale_list(iso8859_3locales, lang))
localeMapper = codecForName("ISO 8859-3");
else if (try_locale_list(iso8859_4locales, lang))
localeMapper = codecForName("ISO 8859-4");
else if (try_locale_list(iso8859_5locales, lang))
localeMapper = codecForName("ISO 8859-5");
else if (try_locale_list(iso8859_6locales, lang))
localeMapper = codecForName("ISO 8859-6");
else if (try_locale_list(iso8859_7locales, lang))
localeMapper = codecForName("ISO 8859-7");
else if (try_locale_list(iso8859_8locales, lang))
localeMapper = codecForName("ISO 8859-8-I");
else if (try_locale_list(iso8859_9locales, lang))
localeMapper = codecForName("ISO 8859-9");
else if (try_locale_list(iso8859_13locales, lang))
localeMapper = codecForName("ISO 8859-13");
else if (try_locale_list(tis_620locales, lang))
localeMapper = codecForName("ISO 8859-11");
else if (try_locale_list(koi8_ulocales, lang))
localeMapper = codecForName("KOI8-U");
else if (try_locale_list(cp_1251locales, lang))
localeMapper = codecForName("CP 1251");
else if (try_locale_list(pt_154locales, lang))
localeMapper = 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 = codecForName("ISO 8859-1");
return 0;
}