All pastes #167016 Raw Edit

Someone

public text v1 · immutable
·published 2006-09-11 15:26 UTC
rendered paste body
#include <stdio.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;
}





bool checkForCodec(const char* codec) {
	printf("checkForCodec: %s\n", codec);
	return false;
}

bool codecForName(const char* name) {
	printf("codecForName: %s\n", name);
	return false;
}

void main() {
	bool localeMapper = false;
	
	// 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 = strdup(setlocale(LC_CTYPE, 0));

	// Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG
	// environment variables.
	char * lang = strdup(getenv("LC_ALL"));
	if (!lang || lang[0] == 0 || strcmp(lang, "C") == 0) {
		if (lang) free(lang);
		lang = strdup(getenv("LC_CTYPE"));
	}
	if (!lang || lang[0] == 0 || strcmp(lang, "C") == 0) {
		if (lang) free(lang);
		lang = 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);*/
	}

	free(ctype);
	free(lang);

	// If everything failed, we default to 8859-1
	// We could perhaps default to 8859-15.
	if (!localeMapper)
		localeMapper = codecForName("ISO 8859-1");
}