UTF8_API size_t utf8envlocale() { /* Sources for locales and code pages Windows https://msdn.microsoft.com/en-US/goglobal/bb896001.aspx POSIX https://www-01.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.nlsgdrf/support_languages_locales.htm */ #if WIN32 || _WINDOWS #define UTF8_LOCALE_CHECK(_name, _ansiCodepage, _oemCodepage) \ (codepage == _ansiCodepage || codepage == _oemCodepage) // Microsoft changed the name of the codepage member in VS2015. #if _MSC_VER >= 1900 #define UTF8_CODEPAGE_GET(_locale) ((__crt_locale_data_public*)(_locale)->locinfo)->_locale_lc_codepage #else #define UTF8_CODEPAGE_GET(_locale) (_locale)->locinfo->lc_codepage #endif unsigned int codepage; _locale_t locale = _get_current_locale(); if (locale == 0) { return UTF8_LOCALE_DEFAULT; } codepage = UTF8_CODEPAGE_GET(locale); #else #define UTF8_LOCALE_CHECK(_name, _ansiCodepage, _oemCodepage) \ !strncasecmp(locale, _name, 5) const char* locale = setlocale(LC_ALL, 0); if (locale == 0) { return UTF8_LOCALE_DEFAULT; } #endif if (UTF8_LOCALE_CHECK("lt_lt", 1257, 775)) { return UTF8_LOCALE_LITHUANIAN; } else if ( UTF8_LOCALE_CHECK("tr_tr", 1254, 857) || UTF8_LOCALE_CHECK("az_az", 1254, 857)) { return UTF8_LOCALE_TURKISH_AND_AZERI_LATIN; } return UTF8_LOCALE_DEFAULT; }
void check_locale() { _locale_t currloc = _get_current_locale(); #ifdef _DEBUG puts("Checking decimal point...\n"); #endif lconv * sysloc = localeconv(); if(currloc->locinfo->lconv->decimal_point == (char*)(',')) { //if(sysloc->decimal_point == (char*)(',')) { #ifdef _DEBUG puts(">>>>>>>>>>>>>>>>>>>Warrning: Decimal point changing to '.'!\n"); #endif setlocale(LC_NUMERIC, "C"); } }
//---------------------------------------------------------------- CPUTResult CPUTConfigFile::LoadFile(const cString &szFilename) { // Load the file cString szCurrLine; CPUTConfigBlock *pCurrBlock = NULL; FILE *pFile = NULL; int nCurrBlock = 0; CPUTResult result = CPUTOSServices::GetOSServices()->OpenFile(szFilename, &pFile); if(CPUTFAILED(result)) { return result; } _locale_t locale = _get_current_locale(); /* Determine file size */ fseek(pFile, 0, SEEK_END); int nBytes = ftell(pFile); // for text files, this is an overestimate fseek(pFile, 0, SEEK_SET); /* Read the whole thing */ char *pFileContents = new char[nBytes + 1]; nBytes = (int)fread(pFileContents, 1, nBytes, pFile); fclose(pFile); pFileContents[nBytes] = 0; // add 0-terminator /* Count the number of blocks */ const char *pCur = pFileContents; const char *pStart, *pEnd; while(ReadLine(&pStart, &pEnd, &pCur)) { const char *pOpen = FindFirst(pStart, pEnd, '['); const char *pClose = FindLast(pOpen + 1, pEnd, ']'); if (pOpen < pClose) { // This line is a valid block header mnBlockCount++; } } // For files that don't have any blocks, just add the entire file to one block if(mnBlockCount == 0) { mnBlockCount = 1; } pCur = pFileContents; mpBlocks = new CPUTConfigBlock[mnBlockCount]; pCurrBlock = mpBlocks; /* Find the first block first */ while(ReadLine(&pStart, &pEnd, &pCur)) { const char *pOpen = FindFirst(pStart, pEnd, '['); const char *pClose = FindLast(pOpen + 1, pEnd, ']'); if (pOpen < pClose) { // This line is a valid block header pCurrBlock = mpBlocks + nCurrBlock++; AssignStr(pCurrBlock->mszName, pOpen + 1, pClose, locale); std::transform(pCurrBlock->mszName.begin(), pCurrBlock->mszName.end(), pCurrBlock->mszName.begin(), ::tolower); } else if (pStart < pEnd) { // It's a value if (pCurrBlock == NULL) { continue; } const char *pEquals = FindFirst(pStart, pEnd, '='); if (pEquals == pEnd) { // No value, just a key, save it anyway // Optimistically, we assume it's new cString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName; AssignStr(name, pStart, pEnd, locale); bool dup = false; for(int ii=0;ii<pCurrBlock->mnValueCount;++ii) { if(!pCurrBlock->mpValues[ii].szName.compare(name)) { dup = true; break; } } if(!dup) { pCurrBlock->mnValueCount++; } } else { const char *pNameStart = pStart; const char *pNameEnd = pEquals; const char *pValStart = pEquals + 1; const char *pValEnd = pEnd; RemoveWhitespace(pNameStart, pNameEnd); RemoveWhitespace(pValStart, pValEnd); // Optimistically assume the name is new cString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName; AssignStr(name, pNameStart, pNameEnd, locale); std::transform(name.begin(), name.end(), name.begin(), ::tolower); bool dup = false; for(int ii=0;ii<pCurrBlock->mnValueCount;++ii) { if(!pCurrBlock->mpValues[ii].szName.compare(name)) { dup = true; break; } } if(!dup) { AssignStr(pCurrBlock->mpValues[pCurrBlock->mnValueCount].szValue, pValStart, pValEnd, locale); pCurrBlock->mnValueCount++; } } } } delete[] pFileContents; return CPUT_SUCCESS; }
char *nl_langinfo(nl_item item) { char *l, *p; _locale_t lt; //if (item != DEF_CODESET) // return NULL; //p = local_charset(); p = setlocale(LC_ALL, ""); //p = setlocale(LC_ALL, NULL); if (p) { printf("setlocal: %s\n", p); } lt = _get_current_locale(); if (lt) { int loci = (int)lt->locinfo; //const char *ccp = get_name_from_clid(loci); //const char *ccp2 = get_name_from_clid(item); //SPRTF("Got locinfo %d (0x%08X) %s\n", loci, loci, (ccp2 ? ccp2 : "no value")); _free_locale(lt); } if (((l = getenv("LC_ALL")) && *l) || ((l = getenv("LC_CTYPE")) && *l) || ((l = getenv("LANG")) && *l)) { /* check standardized locales */ if (!strcmp(l, "C") || !strcmp(l, "POSIX")) return C_CODESET; /* check for encoding name fragment */ if (strstr(l, "UTF") || strstr(l, "utf")) return "UTF-8"; if ((p = strstr(l, "8859-"))) { memcpy(buf, "ISO-8859-\0\0", 12); p += 5; if (digit(*p)) { buf[9] = *p++; if (digit(*p)) buf[10] = *p++; return buf; } } if (strstr(l, "KOI8-R")) return "KOI8-R"; if (strstr(l, "KOI8-U")) return "KOI8-U"; if (strstr(l, "620")) return "TIS-620"; if (strstr(l, "2312")) return "GB2312"; if (strstr(l, "HKSCS")) return "Big5HKSCS"; /* no MIME charset */ if (strstr(l, "Big5") || strstr(l, "BIG5")) return "Big5"; if (strstr(l, "GBK")) return "GBK"; /* no MIME charset */ if (strstr(l, "18030")) return "GB18030"; /* no MIME charset */ if (strstr(l, "Shift_JIS") || strstr(l, "SJIS")) return "Shift_JIS"; /* check for conclusive modifier */ if (strstr(l, "euro")) return "ISO-8859-15"; /* check for language (and perhaps country) codes */ if (strstr(l, "zh_TW")) return "Big5"; if (strstr(l, "zh_HK")) return "Big5HKSCS"; /* no MIME charset */ if (strstr(l, "zh")) return "GB2312"; if (strstr(l, "ja")) return "EUC-JP"; if (strstr(l, "ko")) return "EUC-KR"; if (strstr(l, "ru")) return "KOI8-R"; if (strstr(l, "uk")) return "KOI8-U"; if (strstr(l, "pl") || strstr(l, "hr") || strstr(l, "hu") || strstr(l, "cs") || strstr(l, "sk") || strstr(l, "sl")) return "ISO-8859-2"; if (strstr(l, "eo") || strstr(l, "mt")) return "ISO-8859-3"; if (strstr(l, "el")) return "ISO-8859-7"; if (strstr(l, "he")) return "ISO-8859-8"; if (strstr(l, "tr")) return "ISO-8859-9"; if (strstr(l, "th")) return "TIS-620"; /* or ISO-8859-11 */ if (strstr(l, "lt")) return "ISO-8859-13"; if (strstr(l, "cy")) return "ISO-8859-14"; if (strstr(l, "ro")) return "ISO-8859-2"; /* or ISO-8859-16 */ if (strstr(l, "am") || strstr(l, "vi")) return "UTF-8"; /* Send me further rules if you like, but don't forget that we are * *only* interested in locale naming conventions on platforms * that do not already provide an nl_langinfo(CODESET) implementation. */ //return "ISO-8859-1"; /* should perhaps be "UTF-8" instead */ //return "UTF-8"; /* have set default return as "UTF-8"!!! */ } return C_CODESET; }