35# pragma diag_suppress 450
40# define _XOPEN_SOURCE 500
41# include <sys/types.h>
59# ifndef _RWSTD_NO_NL_LANGINFO
66#if __GNUG__ == 2 && __GNUC_MINOR__ == 96
83static const alias_t codeset_aliases [] = {
84 {
"ANSI_X3.4-1968", {
"ascii",
"usascii",
"us-ascii",
"us_ascii", 0 } },
85 {
"arabic8", {
"arabic-8",
"arabic_8", 0 } },
87 {
"BIG5", {
"big5",
"chinese-t", 0 } },
88 {
"BIG5-HKSCS", {
"hkbig5", 0 } },
92 {
"EUC-JP", {
"eucjp",
"eucJP",
"euc_jp",
"euc",
"ujis", 0 } },
93 {
"EUC-KR", {
"euckr",
"eucKR",
"euc_kr", 0 } },
94 {
"EUC-TW", {
"euctw",
"eucTW",
"euc_tw",
"cns-11643-1992",
96 {
"GB18030", {
"gb18030", 0 } },
98 {
"GB2312", {
"gb2312",
"hp15CN",
"chinese-s", 0 } },
99 {
"GBK", {
"gbk", 0 } },
100 {
"GEORGIAN-PS", { 0 } },
101 {
"greek8", {
"greek-8",
"greek_8", 0 } },
102 {
"hebrew8", {
"hebrew-8",
"hebrew_8", 0 } },
106 {
"ISO-88591",
"ISO_8859-1",
"ISO8859-1",
"iso88591",
"iso1", 0 } },
108 {
"ISO-88592",
"ISO_8859-2",
"ISO8859-2",
"iso88592",
"iso2", 0 } },
110 {
"ISO-88593",
"ISO_8859-3",
"ISO8859-3",
"iso88593",
"iso3", 0 } },
112 {
"ISO-88595",
"ISO_8859-5",
"ISO8859-5",
"iso88595",
"iso5", 0 } },
114 {
"ISO-88596",
"ISO_8859-6",
"ISO8859-6",
"iso88596",
"iso6", 0 } },
116 {
"ISO-88597",
"ISO_8859-7",
"ISO8859-7",
"iso88597",
"iso7",
117 "sun_eu_greek", 0 } },
119 {
"ISO-88598",
"ISO_8859-8",
"ISO8859-8",
"iso88598",
"iso8", 0 } },
121 {
"ISO-88599",
"ISO_8859-9",
"ISO8859-9",
"iso88599",
"iso9", 0 } },
123 {
"ISO-885913",
"ISO_8859-13",
"ISO8859-13",
"iso885913",
"iso13", 0 } },
125 {
"ISO-885914",
"ISO_8859-14",
"ISO8859-14",
"iso885914",
"iso14", 0 } },
127 {
"ISO-885915",
"ISO_8859-15",
"ISO8859-15",
"iso885915",
"iso15", 0 } },
129 {
"KOI8-R", {
"koi8r",
"koi8_r", 0 } },
130 {
"KOI8-T", {
"koi8t",
"koi8_t", 0 } },
131 {
"KOI8-U", {
"koi8u",
"koi8_u", 0 } },
133 {
"roman8", {
"roman-8",
"roman_8", 0 } },
134 {
"Shift_JIS", {
"shift-jis",
"sjis", 0 } },
135 {
"TIS-620", {
"tis620",
"tis620.2533", 0 } },
136 {
"UTF-8", {
"utf8",
"utf_8", 0 } },
141static const alias_t locale_aliases [] = {
142 {
"af_ZA", {
"afrikaans", 0 } },
162 {
"bg_BG", {
"bulgarian", 0 } },
163 {
"br_FR", {
"br", 0 } },
164 {
"bs_BA", {
"bs", 0 } },
166 {
"ca_ES@euro", { 0 } },
167 {
"cs_CZ", {
"czech", 0 } },
168 {
"cy_GB", {
"cy", 0 } },
169 {
"da_DK", {
"danish", 0 } },
170 {
"de_AT", {
"austrian", 0 } },
171 {
"de_AT@euro", { 0 } },
173 {
"de_BE@euro", { 0 } },
175 {
"de_DE", {
"deutsch",
"german", 0 } },
176 {
"de_DE@euro", { 0 } },
178 {
"de_LU@euro", { 0 } },
179 {
"el_GR", {
"greek", 0 } },
187 {
"en_IE@euro", { 0 } },
202 {
"es_ES", {
"spanish", 0 } },
203 {
"es_ES@euro", { 0 } },
216 {
"et_EE", {
"estonian", 0 } },
218 {
"eu_ES@euro", { 0 } },
219 {
"fa_IR", {
"fa", 0 } },
220 {
"fi_FI", {
"finnish", 0 } },
221 {
"fi_FI@euro", {
"fi", 0 } },
222 {
"fo_FO", {
"fo", 0 } },
224 {
"fr_BE@euro", { 0 } },
225 {
"fr_CA", {
"canadian", 0 } },
227 {
"fr_FR", {
"french", 0 } },
228 {
"fr_FR@euro", { 0 } },
230 {
"fr_LU@euro", { 0 } },
232 {
"ga_IE@euro", { 0 } },
234 {
"gl_ES@euro", { 0 } },
236 {
"he_IL", {
"hebrew", 0 } },
238 {
"hr_HR", {
"croatian", 0 } },
239 {
"hu_HU", {
"hungarian", 0 } },
243 {
"it_IT", {
"italian", 0 } },
244 {
"it_IT@euro", { 0 } },
246 {
"ja_JP", {
"ja",
"japanese", 0 } },
249 {
"ko_KR", {
"ko", 0 } },
251 {
"lt_LT", {
"lithuanian", 0 } },
252 {
"lv_LV", {
"latvian", 0 } },
254 {
"mk_MK", {
"macedonian", 0 } },
259 {
"nl_BE@euro", { 0 } },
260 {
"nl_NL", {
"dutch", 0 } },
261 {
"nl_NL@euro", { 0 } },
263 {
"no_NO", {
"no", 0 } },
264 {
"oc_FR", {
"occitan", 0 } },
265 {
"pl_PL", {
"polish", 0 } },
267 {
"pt_PT", {
"portuguese", 0 } },
268 {
"pt_PT@euro", { 0 } },
269 {
"ro_RO", {
"romanian", 0 } },
270 {
"ru_RU", {
"russian", 0 } },
272 {
"sk_SK", {
"slovakian",
"slovak", 0 } },
273 {
"sl_SI", {
"slovenian",
"sloven", 0 } },
274 {
"sq_AL", {
"albanian", 0 } },
275 {
"sr_YU", {
"serbian", 0 } },
276 {
"sr_YU@cyrillic", { 0 } },
278 {
"sv_FI@euro", { 0 } },
283 {
"th_TH", {
"thai", 0 } },
285 {
"tr_TR", {
"turkish", 0 } },
286 {
"uk_UA", {
"ukrainian", 0 } },
291 {
"zh_TW", {
"zh",
"chinese", 0 } },
300 unsigned int codepage;
303static const codepage_t codepages [] = {
304 {
"ANSI_X3.4-1968", 20127 },
308 {
"ISO-8859-1", 28591 },
309 {
"ISO-8859-2", 28592 },
310 {
"ISO-8859-3", 28593 },
311 {
"ISO-8859-4", 28594 },
312 {
"ISO-8859-5", 28595 },
313 {
"ISO-8859-6", 28596 },
314 {
"ISO-8859-7", 28597 },
315 {
"ISO-8859-8", 28598 },
316 {
"ISO-8859-9", 28599 },
317 {
"ISO-8859-15", 28605 },
320 {
"Shift_JIS", 932 },
332 for (std::size_t
i = 0; codepages [
i].name;
i++) {
334 return codepages[
i].codepage;
345 v.push_back (
a.name);
347 for (std::size_t
i = 0;
a.aliases [
i];
i++)
348 v.push_back (
a.aliases [
i]);
354static int ci_pre_compare (
const std::string&
s1,
const std::string&
s2)
356 std::string::const_iterator it1 =
s1.begin ();
357 std::string::const_iterator it2 =
s2.begin ();
358 for (; it1 !=
s1.end () && it2 !=
s2.end (); it1++, it2++)
359 if ( (std::tolower)(*it1, std::locale ())
360 != (std::tolower)(*it2, std::locale ()))
361 return (*it1 - *it2);
372 typedef unsigned char UChar;
374 for ( ; ; ++
s1, ++
s2) {
395 for (std::size_t
i = 0; codeset_aliases [
i].
name;
i++) {
398 store_aliases (aliases, codeset_aliases [
i]);
403 for (std::size_t
j = 0; codeset_aliases [
i].
aliases [
j];
j++) {
407 store_aliases (aliases, codeset_aliases [
i]);
413 if (aliases.empty ())
414 aliases.push_back (
name);
422 for (std::size_t
i = 0; locale_aliases [
i].
name;
i++) {
425 store_aliases (aliases, locale_aliases [
i]);
430 for (std::size_t
j = 0; locale_aliases [
i].
aliases [
j];
j++) {
434 store_aliases (aliases, locale_aliases [
i]);
440 if (aliases.empty ())
441 aliases.push_back (
name);
446 const std::string &cname,
462 for (; *locname; locname += std::strlen (locname) + 1) {
464 bool match_found =
false;
466 typedef StringVector::iterator
Iterator;
470 for (
Iterator it = la.begin (); it != la.end (); ++it) {
472 if (0 != ci_pre_compare (locname, (*it).c_str ()))
476 if (0 == std::setlocale (
LC_CTYPE, locname))
479 const char*
const cs = nl_langinfo (CODESET);
482 for (
Iterator it1 = ca.begin (); it1 != ca.end (); ++it1) {
487 libc_locales.push_back (std::string (locname));
507 for (; *locname; locname += std::strlen (locname) + 1) {
510 if (0 == std::setlocale (
LC_CTYPE, locname))
513#ifdef _RWSTD_OS_HP_UX
516 if (0 == std::strcmp (
"C.utf8", locname))
522 const char*
const cs = nl_langinfo (CODESET);
524 typedef StringVector::iterator
Iterator;
527 for (
Iterator it = ca.begin (); it != ca.end (); ++it)
533 return std::string ();
544 static char* slocname = 0;
546 static std::size_t
size = 0;
547 static std::size_t total_size = 5120;
551 slocname =
new char [16384];
555 char* locname = slocname;
558 const char*
const save_localename = std::setlocale (
LC_ALL, 0);
559 std::setlocale (
LC_ALL,
"C");
561#if __GNUG__ == 2 && __GNUC_MINOR__ == 96
564 char fname_buf [
L_tmpnam] =
"/tmp/tmpfile-XXXXXX";
565 const char *fname = fname_buf;
569 const int fd =
mkstemp (fname_buf);
572 std::perror (
"mkstemp() failed");
582 const char *fname = std::tmpnam (fname_buf);
587 std::perror (
"tmpnam() failed");
599 std::sprintf (cmd,
"LC_ALL=C /usr/bin/locale -a >%s 2>/dev/null", fname);
601 const int ret = std::system (cmd);
605 cmd, std::strerror (errno));
608 std::FILE *
f = std::fopen (fname,
"r");
614 char last_name [256];
618 while (std::fgets (cmd,
int (
sizeof cmd),
f)) {
619 cmd [std::strlen (cmd) - 1] =
'\0';
622 if ((
size += (std::strlen (cmd) + 1)) > total_size) {
624 char* newBuf =
new char[total_size];
625 std::memcpy (newBuf, slocname, total_size - 5120);
626 std::free (slocname);
628 locname = slocname +
size - std::strlen (cmd) - 1;
634 std::strcpy (locname, cmd);
635 locname += std::strlen (cmd) + 1;
642 const char *
name = std::setlocale (loc_cat, cmd);
646 if (
name && std::strcmp (last_name,
name)) {
647 std::strcpy (locname, cmd);
648 locname += std::strlen (cmd) + 1;
651 assert (std::strlen (
name) <
sizeof last_name);
652 std::strcpy (last_name,
name);
656 std::strcpy (locname, cmd);
657 locname += std::strlen (cmd) + 1;
669 std::setlocale (
LC_ALL, save_localename);
char * get_installed_locales(int loc_cat)
void get_lname_aliases(const std::string &name, StringVector &aliases)
void get_same_encoding_C_locale(const std::string &lname, const std::string &cname, StringVector &libc_locales)
void get_cname_aliases(const std::string &name, StringVector &aliases)
int ci_compare(const char *s1, const char *s2)
std::string get_C_encoding_locale(const std::string &codeset)
std::vector< std::string > StringVector
unsigned int get_codepage(const std::string &)
bool issue_diag(int type, bool, const Scanner::token_t *token, const char *fmt,...)