111
|
1 /****************************************************************************
|
|
2 * *
|
|
3 * GNAT COMPILER COMPONENTS *
|
|
4 * *
|
|
5 * L O C A L E S *
|
|
6 * *
|
|
7 * C Implementation File *
|
|
8 * *
|
145
|
9 * Copyright (C) 2010-2019, Free Software Foundation, Inc. *
|
111
|
10 * *
|
|
11 * GNAT is free software; you can redistribute it and/or modify it under *
|
|
12 * terms of the GNU General Public License as published by the Free Soft- *
|
|
13 * ware Foundation; either version 3, or (at your option) any later ver- *
|
|
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
|
|
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
|
16 * or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
17 * *
|
|
18 * As a special exception under Section 7 of GPL version 3, you are granted *
|
|
19 * additional permissions described in the GCC Runtime Library Exception, *
|
|
20 * version 3.1, as published by the Free Software Foundation. *
|
|
21 * *
|
|
22 * You should have received a copy of the GNU General Public License and *
|
|
23 * a copy of the GCC Runtime Library Exception along with this program; *
|
|
24 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
|
|
25 * <http://www.gnu.org/licenses/>. *
|
|
26 * *
|
|
27 * GNAT was originally developed by the GNAT team at New York University. *
|
|
28 * Extensive contributions were provided by Ada Core Technologies Inc. *
|
|
29 * *
|
|
30 ****************************************************************************/
|
|
31
|
|
32 /* This file provides OS-dependent support for the Ada.Locales package. */
|
|
33
|
131
|
34 #include <locale.h>
|
|
35 #include <ctype.h>
|
|
36 #include <stddef.h>
|
|
37
|
111
|
38 typedef char char4 [4];
|
|
39
|
131
|
40 /* Table containing equivalences between ISO_639_1 codes and their ISO_639_3
|
|
41 alpha-3 code plus their language name. */
|
|
42
|
|
43 static char* iso_639[] =
|
|
44 {
|
|
45 "aa", "aar", "Afar",
|
|
46 "ab", "abk", "Abkhazian",
|
|
47 "ae", "ave", "Avestan",
|
|
48 "af", "afr", "Afrikaans",
|
|
49 "ak", "aka", "Akan",
|
|
50 "am", "amh", "Amharic",
|
|
51 "an", "arg", "Aragonese",
|
|
52 "ar", "ara", "Arabic",
|
|
53 "as", "asm", "Assamese",
|
|
54 "av", "ava", "Avaric",
|
|
55 "ay", "aym", "Aymara",
|
|
56 "az", "aze", "Azerbaijani",
|
|
57
|
|
58 "ba", "bak", "Bashkir",
|
|
59 "be", "bel", "Belarusian",
|
|
60 "bg", "bul", "Bulgarian",
|
|
61 "bi", "bis", "Bislama",
|
|
62 "bm", "bam", "Bambara",
|
|
63 "bn", "ben", "Bengali",
|
|
64 "bo", "bod", "Tibetan",
|
|
65 "br", "bre", "Breton",
|
|
66 "bs", "bos", "Bosnian",
|
|
67
|
|
68 "ca", "cat", "Catalan",
|
|
69 "ce", "che", "Chechen",
|
|
70 "ch", "cha", "Chamorro",
|
|
71 "co", "cos", "Corsican",
|
|
72 "cr", "cre", "Cree",
|
|
73 "cs", "ces", "Czech",
|
|
74 "cu", "chu", "Church Slavic",
|
|
75 "cv", "chv", "Chuvash",
|
|
76 "cy", "cym", "Welsh",
|
|
77
|
|
78 "da", "dan", "Danish",
|
|
79 "de", "deu", "German",
|
|
80 "dv", "div", "Divehi",
|
|
81 "dz", "dzo", "Dzongkha",
|
|
82
|
|
83 "ee", "ewe", "Ewe",
|
|
84 "el", "ell", "Modern Greek",
|
|
85 "en", "eng", "English",
|
|
86 "eo", "epo", "Esperanto",
|
|
87 "es", "spa", "Spanish",
|
|
88 "et", "est", "Estonian",
|
|
89 "eu", "eus", "Basque",
|
|
90
|
|
91 "fa", "fas", "Persian",
|
|
92 "ff", "ful", "Fulah",
|
|
93 "fi", "fin", "Finnish",
|
|
94 "fj", "fij", "Fijian",
|
|
95 "fo", "fao", "Faroese",
|
|
96 "fr", "fra", "French",
|
|
97 "fy", "fry", "Western Frisian",
|
|
98
|
|
99 "ga", "gle", "Irish",
|
|
100 "gd", "gla", "Scottish Gaelic",
|
|
101 "gl", "glg", "Galician",
|
|
102 "gn", "grn", "Guarani",
|
|
103 "gu", "guj", "Gujarati",
|
|
104 "gv", "glv", "Manx",
|
|
105
|
|
106 "ha", "hau", "Hausa",
|
|
107 "he", "heb", "Hebrew",
|
|
108 "hi", "hin", "Hindi",
|
|
109 "ho", "hmo", "Hiri Motu",
|
|
110 "hr", "hrv", "Croatian",
|
|
111 "ht", "hat", "Haitian",
|
|
112 "hu", "hun", "Hungarian",
|
|
113 "hy", "hye", "Armenian",
|
|
114 "hz", "her", "Herero",
|
|
115
|
|
116 "ia", "ina", "Interlingua",
|
|
117 "id", "ind", "Indonesian",
|
|
118 "ie", "ile", "Interlingue",
|
|
119 "ig", "ibo", "Igbo",
|
|
120 "ii", "iii", "Sichuan Yi",
|
|
121 "ik", "ipk", "Inupiaq",
|
|
122 "io", "ido", "Ido",
|
|
123 "is", "isl", "Icelandic",
|
|
124 "it", "ita", "Italian",
|
|
125 "iu", "iku", "Inuktitut",
|
|
126
|
|
127 "ja", "jpn", "Japanese",
|
|
128 "jv", "jav", "Javanese",
|
|
129
|
|
130 "ka", "kat", "Georgian",
|
|
131 "kg", "kon", "Kongo",
|
|
132 "ki", "kik", "Kikuyu",
|
|
133 "kj", "kua", "Kuanyama",
|
|
134 "kk", "kaz", "Kazakh",
|
|
135 "kl", "kal", "Kalaallisut",
|
|
136 "km", "khm", "Central Khmer",
|
|
137 "kn", "kan", "Kannada",
|
|
138 "ko", "kor", "Korean",
|
|
139 "kr", "kau", "Kanuri",
|
|
140 "ks", "kas", "Kashmiri",
|
|
141 "ku", "kur", "Kurdish",
|
|
142 "kv", "kom", "Komi",
|
|
143 "kw", "cor", "Cornish",
|
|
144 "ky", "kir", "Kirghiz",
|
|
145
|
|
146 "la", "lat", "Latin",
|
|
147 "lb", "ltz", "Luxembourgish",
|
|
148 "lg", "lug", "Ganda",
|
|
149 "li", "lim", "Limburgan",
|
|
150 "ln", "lin", "Lingala",
|
|
151 "lo", "lao", "Lao",
|
|
152 "lt", "lit", "Lithuanian",
|
|
153 "lu", "lub", "Luba-Katanga",
|
|
154 "lv", "lav", "Latvian",
|
|
155
|
|
156 "mg", "mlg", "Malagasy",
|
|
157 "mh", "mah", "Marshallese",
|
|
158 "mi", "mri", "Maori",
|
|
159 "mk", "mkd", "Macedonian",
|
|
160 "ml", "mal", "Malayalam",
|
|
161 "mn", "mon", "Mongolian",
|
|
162 "mr", "mar", "Marathi",
|
|
163 "ms", "msa", "Malay",
|
|
164 "mt", "mlt", "Maltese",
|
|
165 "my", "mya", "Burmese",
|
|
166
|
|
167 "na", "nau", "Nauru",
|
|
168 "nb", "nob", "Norwegian Bokmal",
|
|
169 "nd", "nde", "North Ndebele",
|
|
170 "ne", "nep", "Nepali",
|
|
171 "ng", "ndo", "Ndonga",
|
|
172 "nl", "nld", "Dutch",
|
|
173 "nn", "nno", "Norwegian Nynorsk",
|
|
174 "no", "nor", "Norwegian",
|
|
175 "nr", "nbl", "South Ndebele",
|
|
176 "nv", "nav", "Navajo",
|
|
177 "ny", "nya", "Nyanja",
|
|
178
|
|
179 "oc", "oci", "Occitan",
|
|
180 "oj", "oji", "Ojibwa",
|
|
181 "om", "orm", "Oromo",
|
|
182 "or", "ori", "Oriya",
|
|
183 "os", "oss", "Ossetian",
|
|
184
|
|
185 "pa", "pan", "Panjabi",
|
|
186 "pi", "pli", "Pali",
|
|
187 "pl", "pol", "Polish",
|
|
188 "ps", "pus", "Pushto",
|
|
189 "pt", "por", "Portuguese",
|
|
190
|
|
191 "qu", "que", "Quechua",
|
|
192
|
|
193 "rm", "roh", "Romansh",
|
|
194 "rn", "run", "Rundi",
|
|
195 "ro", "ron", "Romanian",
|
|
196 "ru", "rus", "Russian",
|
|
197 "rw", "kin", "Kinyarwanda",
|
|
198
|
|
199 "sa", "san", "Sanskrit",
|
|
200 "sc", "srd", "Sardinian",
|
|
201 "sd", "snd", "Sindhi",
|
|
202 "se", "sme", "Northern Sami",
|
|
203 "sg", "sag", "Sango",
|
|
204 "sh", "hbs", "Serbo-Croatian",
|
|
205 "si", "sin", "Sinhala",
|
|
206 "sk", "slk", "Slovak",
|
|
207 "sl", "slv", "Slovenian",
|
|
208 "sm", "smo", "Samoan",
|
|
209 "sn", "sna", "Shona",
|
|
210 "so", "som", "Somali",
|
|
211 "sq", "sqi", "Albanian",
|
|
212 "sr", "srp", "Serbian",
|
|
213 "ss", "ssw", "Swati",
|
|
214 "st", "sot", "Southern Sotho",
|
|
215 "su", "sun", "Sundanese",
|
|
216 "sv", "swe", "Swedish",
|
|
217 "sw", "swa", "Swahili",
|
|
218
|
|
219 "ta", "tam", "Tamil",
|
|
220 "te", "tel", "Telugu",
|
|
221 "tg", "tgk", "Tajik",
|
|
222 "th", "tha", "Thai",
|
|
223 "ti", "tir", "Tigrinya",
|
|
224 "tk", "tuk", "Turkmen",
|
|
225 "tl", "tgl", "Tagalog",
|
|
226 "tn", "tsn", "Tswana",
|
|
227 "to", "ton", "Tonga",
|
|
228 "tr", "tur", "Turkish",
|
|
229 "ts", "tso", "Tsonga",
|
|
230 "tt", "tat", "Tatar",
|
|
231 "tw", "twi", "Twi",
|
|
232 "ty", "tah", "Tahitian",
|
|
233
|
|
234 "ug", "uig", "Uighur",
|
|
235 "uk", "ukr", "Ukrainian",
|
|
236 "ur", "urd", "Urdu",
|
|
237 "uz", "uzb", "Uzbek",
|
|
238
|
|
239 "ve", "ven", "Venda",
|
|
240 "vi", "vie", "Vietnamese",
|
|
241 "vo", "vol", "Volapuk",
|
|
242
|
|
243 "wa", "wln", "Walloon",
|
|
244 "wo", "wol", "Wolof",
|
|
245
|
|
246 "xh", "xho", "Xhosa",
|
|
247
|
|
248 "yi", "yid", "Yiddish",
|
|
249 "yo", "yor", "Yoruba",
|
|
250
|
|
251 "za", "zha", "Zhuang",
|
|
252 "zh", "zho", "Chinese",
|
|
253 "zu", "zul", "Zulu"
|
|
254 };
|
|
255
|
|
256 /* Table containing equivalences between ISO_3166 alpha-2 codes and country
|
|
257 names. This table has several entries for codes that have several valid
|
|
258 country names. */
|
|
259
|
|
260 static char* iso_3166[] =
|
|
261 {
|
|
262 "AU", "Australia",
|
|
263 "AD", "Andorra",
|
|
264 "AE", "United Arab Emirates",
|
|
265 "AF", "Afghanistan",
|
|
266 "AG", "Antigua and Barbuda",
|
|
267 "AI", "Anguilla",
|
|
268 "AL", "Albania",
|
|
269 "AM", "Armenia",
|
|
270 "AN", "Netherlands Antilles",
|
|
271 "AO", "Angola",
|
|
272 "AQ", "Antarctica",
|
|
273 "AR", "Argentina",
|
|
274 "AS", "American Samoa",
|
|
275 "AT", "Austria",
|
|
276 "AU", "Australia",
|
|
277 "AW", "Aruba",
|
|
278 "AX", "Aland Islands",
|
|
279 "AZ", "Azerbaijan",
|
|
280
|
|
281 "BA", "Bosnia and Herzegovina",
|
|
282 "BB", "Barbados",
|
|
283 "BD", "Bangladesh",
|
|
284 "BE", "Belgium",
|
|
285 "BF", "Burkina Faso",
|
|
286 "BG", "Bulgaria",
|
|
287 "BH", "Bahrain",
|
|
288 "BI", "Burundi",
|
|
289 "BJ", "Benin",
|
|
290 "BL", "Saint Barthélemy",
|
|
291 "BM", "Bermuda",
|
|
292 "BN", "Brunei Darussalam",
|
|
293 "BO", "Bolivia, Plurinational State of",
|
|
294 "BQ", "Bonaire, Sint Eustatius and Saba",
|
|
295 "BR", "Brazil",
|
|
296 "BS", "Bahamas",
|
|
297 "BT", "Bhutan",
|
|
298 "BV", "Bouvet Island",
|
|
299 "BW", "Botswana",
|
|
300 "BY", "Belarus",
|
|
301 "BZ", "Belize",
|
|
302
|
|
303 "CA", "Canada",
|
|
304 "CC", "Cocos (Keeling) Islands",
|
|
305 "CD", "Congo, Democratic Republic of the",
|
|
306 "CF", "Central African Republic",
|
|
307 "CG", "Congo",
|
|
308 "CH", "Switzerland",
|
|
309 "CI", "Côte d'Ivoire",
|
|
310 "CK", "Cook Islands",
|
|
311 "CL", "Chile",
|
|
312 "CM", "Cameroon",
|
|
313 "CN", "China",
|
|
314 "CN", "People’s Republic of China",
|
|
315 "CN", "PR China",
|
|
316 "CN", "PR-China",
|
|
317 "CO", "Colombia",
|
|
318 "CR", "Costa Rica",
|
|
319 "CS", "Czechoslovakia",
|
|
320 "CU", "Cuba",
|
|
321 "CV", "Cape Verde",
|
|
322 "CW", "Curaçao",
|
|
323 "CX", "Christmas Island",
|
|
324 "CY", "Cyprus",
|
|
325 "CZ", "Czech Republic",
|
|
326
|
|
327 "DE", "Germany",
|
|
328 "DJ", "Djibouti",
|
|
329 "DK", "Denmark",
|
|
330 "DM", "Dominica",
|
|
331 "DO", "Dominican Republic",
|
|
332 "DZ", "Algeria",
|
|
333
|
|
334 "EC", "Ecuador",
|
|
335 "EE", "Estonia",
|
|
336 "EG", "Egypt",
|
|
337 "EH", "Western Sahara",
|
|
338 "ER", "Eritrea",
|
|
339 "ES", "Spain",
|
|
340 "ET", "Ethiopia",
|
|
341
|
|
342 "FI", "Finland",
|
|
343 "FG", "Fiji",
|
|
344 "FK", "Falkland Islands (Malvinas)",
|
|
345 "FM", "Micronesia, Federated States of",
|
|
346 "FO", "Faroe Islands",
|
|
347 "FR", "France",
|
|
348
|
|
349 "GA", "Gabon",
|
|
350 "GB", "United Kingdom",
|
|
351 "GB", "United-Kingdom",
|
|
352 "GB", "England",
|
|
353 "GB", "Britain",
|
|
354 "GB", "Great Britain",
|
|
355 "GD", "Grenada",
|
|
356 "GE", "Georgia",
|
|
357 "GF", "French Guiana",
|
|
358 "GG", "Guernsey",
|
|
359 "GH", "Ghana",
|
|
360 "GI", "Gibraltar",
|
|
361 "GL", "Greenland",
|
|
362 "GM", "Gambia",
|
|
363 "GN", "Guinea",
|
|
364 "GP", "Guadeloupe",
|
|
365 "GQ", "Equatorial Guinea",
|
|
366 "GR", "Greece",
|
|
367 "GS", "South Georgia and the South Sandwich Islands",
|
|
368 "GT", "Guatemala",
|
|
369 "GU", "Guam",
|
|
370 "GW", "Guinea-Bissau",
|
|
371 "GY", "Guyana",
|
|
372
|
|
373 "HK", "Hong Kong",
|
|
374 "HK", "Hong-Kong",
|
|
375 "HM", "Heard Island and McDonald Islands",
|
|
376 "HN", "Honduras",
|
|
377 "HR", "Croatia",
|
|
378 "HT", "Haiti",
|
|
379 "HU", "Hungary",
|
|
380
|
|
381 "ID", "Indonesia",
|
|
382 "IE", "Ireland",
|
|
383 "IL", "Israel",
|
|
384 "IM", "Isle of Man",
|
|
385 "IN", "India",
|
|
386 "IO", "British Indian Ocean Territory",
|
|
387 "IQ", "Iraq",
|
|
388 "IR", "Iran",
|
|
389 "IR", "Iran, Islamic Republic of",
|
|
390 "IS", "Iceland",
|
|
391 "IT", "Italy",
|
|
392
|
|
393 "JE", "Jersey",
|
|
394 "JM", "Jamaica",
|
|
395 "JO", "Jordan",
|
|
396 "JP", "Japan",
|
|
397
|
|
398 "KE", "Kenya",
|
|
399 "KG", "Kyrgyzstan",
|
|
400 "KH", "Cambodia",
|
|
401 "KI", "Kiribati",
|
|
402 "KM", "Comoros",
|
|
403 "KN", "Saint Kitts and Nevis",
|
|
404 "KP", "Korea, Democratic People's Republic of",
|
|
405 "KR", "Korea, Republic of",
|
|
406 "KW", "Kuwait",
|
|
407 "KY", "Cayman Islands",
|
|
408 "KZ", "Kazakhstan",
|
|
409
|
|
410 "LA", "Lao People's Democratic Republic",
|
|
411 "LB", "Lebanon",
|
|
412 "LC", "Saint Lucia",
|
|
413 "LI", "Liechtenstein",
|
|
414 "LK", "Sri Lanka",
|
|
415 "LR", "Liberia",
|
|
416 "LS", "Lesotho",
|
|
417 "LT", "Lithuania",
|
|
418 "LU", "Luxembourg",
|
|
419 "LV", "Latvia",
|
|
420 "LY", "Libya",
|
|
421
|
|
422 "MA", "Morocco",
|
|
423 "MC", "Monaco",
|
|
424 "MD", "Moldova, Republic of",
|
|
425 "ME", "Montenegro",
|
|
426 "MF", "Saint Martin",
|
|
427 "MG", "Madagascar",
|
|
428 "MH", "Marshall Islands",
|
|
429 "MK", "Macedonia",
|
|
430 "ML", "Mali",
|
|
431 "MM", "Myanmar",
|
|
432 "MN", "Mongolia",
|
|
433 "MO", "Macao",
|
|
434 "MP", "Northern Mariana Islands",
|
|
435 "MQ", "Martinique",
|
|
436 "MR", "Mauritania",
|
|
437 "MS", "Montserrat",
|
|
438 "MT", "Malta",
|
|
439 "MU", "Mauritius",
|
|
440 "MV", "Maldives",
|
|
441 "MW", "Malawi",
|
|
442 "MX", "Mexico",
|
|
443 "MY", "Malaysia",
|
|
444 "MZ", "Mozambique",
|
|
445
|
|
446 "NA", "Namibia",
|
|
447 "NC", "New Caledonia",
|
|
448 "NE", "Niger",
|
|
449 "NF", "Norfolk Island",
|
|
450 "NG", "Nigeria",
|
|
451 "NI", "Nicaragua",
|
|
452 "NL", "Netherlands",
|
|
453 "NL", "Holland",
|
|
454 "NO", "Norway",
|
|
455 "NP", "Nepal",
|
|
456 "NR", "Nauru",
|
|
457 "NU", "Niue",
|
|
458 "NZ", "New Zealand",
|
|
459 "NZ", "New-Zealand",
|
|
460
|
|
461 "OM", "Oman",
|
|
462
|
|
463 "PA", "Panama",
|
|
464 "PE", "Peru",
|
|
465 "PF", "French Polynesia",
|
|
466 "PG", "Papua New Guinea",
|
|
467 "PH", "Philippines",
|
|
468 "PK", "Pakistan",
|
|
469 "PL", "Poland",
|
|
470 "PM", "Saint Pierre and Miquelon",
|
|
471 "PN", "Pitcairn",
|
|
472 "PR", "Puerto Rico",
|
|
473 "PS", "Palestine, State of",
|
|
474 "PT", "Portugal",
|
|
475 "PW", "Palau",
|
|
476 "PY", "Paraguay",
|
|
477
|
|
478 "QA", "Qatar",
|
|
479
|
|
480 "RE", "Réunion",
|
|
481 "RO", "Romania",
|
|
482 "RS", "Serbia",
|
|
483 "RU", "Russian Federation",
|
|
484 "RW", "Rwanda",
|
|
485
|
|
486 "SA", "Saudi Arabia",
|
|
487 "SB", "Solomon Islands",
|
|
488 "SC", "Seychelles",
|
|
489 "SD", "Sudan",
|
|
490 "SE", "Sweden",
|
|
491 "SG", "Singapore",
|
|
492 "SH", "Saint Helena, Ascension and Tristan da Cunha",
|
|
493 "SI", "Slovenia",
|
|
494 "SJ", "Svalbard and Jan Mayen",
|
|
495 "SK", "Slovakia",
|
|
496 "SL", "Sierra Leone",
|
|
497 "SM", "San Marino",
|
|
498 "SN", "Senegal",
|
|
499 "SO", "Somalia",
|
|
500 "SR", "Suriname",
|
|
501 "SS", "South Sudan",
|
|
502 "SV", "El Salvador",
|
|
503 "SX", "Sint Maarten (Dutch part)",
|
|
504 "SY", "Syrian Arab Republic",
|
|
505 "SZ", "Swaziland",
|
|
506
|
|
507 "TC", "Turks and Caicos Islands",
|
|
508 "TD", "Chad",
|
|
509 "TF", "French Southern Territories",
|
|
510 "TG", "Togo",
|
|
511 "TH", "Thailand",
|
|
512 "TJ", "Tajikistan",
|
|
513 "TK", "Tokelau",
|
|
514 "TL", "Timor-Leste",
|
|
515 "TM", "Turkmenistan",
|
|
516 "TN", "Tunisia",
|
|
517 "TO", "Tonga",
|
|
518 "TP", "East Timor",
|
|
519 "TR", "Turkey",
|
|
520 "TT", "Trinidad and Tobago",
|
|
521 "TV", "Tuvalu",
|
|
522 "TW", "Taiwan",
|
|
523 "TW", "Taiwan, Province of China",
|
|
524 "TZ", "Tanzania",
|
|
525 "TZ", "Tanzania, United Republic of",
|
|
526
|
|
527 "UA", "Ukraine",
|
|
528 "UG", "Uganda",
|
|
529 "UM", "United States Minor Outlying Islands",
|
|
530 "US", "United States",
|
|
531 "US", "United States of America",
|
145
|
532 "US", "United-States",
|
131
|
533 "UY", "Uruguay",
|
|
534 "UZ", "Uzbekistan",
|
|
535
|
|
536 "VA", "Holy See (Vatican City State)",
|
|
537 "VC", "Saint Vincent and the Grenadines",
|
|
538 "VE", "Venezuela",
|
|
539 "VE", "Venezuela, Bolivarian Republic of",
|
|
540 "VG", "Virgin Islands, British",
|
|
541 "VI", "Virgin Islands, U.S.",
|
|
542 "VN", "Viet Nam",
|
|
543 "VU", "Vanuatu",
|
|
544 "WF", "Wallis and Futuna",
|
|
545 "WS", "Samoa",
|
|
546
|
|
547 "YE", "Yemen",
|
|
548 "YT", "Mayotte",
|
|
549 "YU", "Yugoslavia",
|
|
550
|
|
551 "ZA", "South Africa",
|
|
552 "ZM", "Zambia",
|
|
553 "ZW", "Zimbabwe"
|
|
554 };
|
|
555
|
|
556 /* Utility function to perform case insensitive string comparison. Returns 1
|
|
557 if both strings are equal and 0 otherwise. */
|
|
558
|
|
559 static int
|
|
560 str_case_equals (const char *s1, const char *s2) {
|
|
561 while (*s1 != '\0' && *s2 != '\0' && tolower(*s1) == tolower(*s2)) {
|
|
562 s1++;
|
|
563 s2++;
|
|
564 }
|
|
565
|
|
566 return (*s1 == '\0') && (*s2 == '\0');
|
|
567 }
|
|
568
|
|
569 /* Utility function to copy length characters of a string. The target string
|
|
570 must have space to store the extra string null terminator. */
|
|
571
|
|
572 static void
|
|
573 str_copy (char *target, char *source, int length) {
|
|
574 for (; length > 0; source++, target++, length--) {
|
|
575 *target = *source;
|
|
576 }
|
|
577
|
|
578 *target = '\0';
|
|
579 }
|
|
580
|
|
581 /* Utility function to search for the last byte of the lc_all string to be
|
|
582 processed. Required because in some targets (for example, AIX), the
|
|
583 string returned by setlocale() has duplicates. */
|
|
584
|
|
585 static char*
|
|
586 str_get_last_byte (char *lc_all) {
|
|
587 char* first_space = NULL;
|
|
588 char* second_space = NULL;
|
|
589 char* last_byte = NULL;
|
|
590 char* s1 = lc_all;
|
|
591
|
|
592 /* Search for the 1st space (if any) */
|
|
593 while (*s1 != ' ' && *s1 != '\0')
|
|
594 s1++;
|
|
595
|
|
596 if (*s1 == '\0') {
|
|
597 last_byte = s1;
|
|
598
|
|
599 } else {
|
|
600 first_space = s1;
|
|
601
|
|
602 /* Skip this space and search for the 2nd one (if available) */
|
|
603 s1++;
|
|
604 while (*s1 != ' ' && *s1 != '\0')
|
|
605 s1++;
|
|
606
|
|
607 if (*s1 == '\0') {
|
|
608 last_byte = s1;
|
|
609
|
|
610 } else {
|
|
611 second_space=s1;
|
|
612
|
|
613 /* Search for the last byte of lc_all */
|
|
614 while (*s1 != '\0')
|
|
615 s1++;
|
|
616
|
|
617 last_byte = s1;
|
|
618
|
|
619 /* Check if the two strings match */
|
|
620 {
|
|
621 int len1 = first_space - lc_all;
|
|
622 int len2 = second_space - first_space - 1;
|
|
623
|
|
624 if (len1 == len2) {
|
|
625 char* p1 = lc_all;
|
|
626 char* p2 = first_space + 1;
|
|
627
|
|
628 /* Compare their contents */
|
|
629 while (*p1 == *p2 && p2 != second_space) {
|
|
630 p1++;
|
|
631 p2++;
|
|
632 }
|
|
633
|
|
634 /* if the two strings match then update the last byte */
|
|
635
|
|
636 if (p2 == second_space) {
|
|
637 last_byte = first_space;
|
|
638 }
|
|
639 }
|
|
640 }
|
|
641 }
|
|
642 }
|
|
643
|
|
644 return last_byte;
|
|
645 }
|
|
646
|
|
647 /* Utility function to search in the iso_639_1 table for an iso-639-1 code;
|
|
648 returns the corresponding iso-639-3 code or NULL if not found. */
|
|
649
|
|
650 static char*
|
|
651 iso_639_1_to_639_3(char* iso_639_1_code) {
|
|
652 int len = sizeof(iso_639)/sizeof(iso_639[0]);
|
|
653 char **p = iso_639;
|
|
654 int j;
|
|
655
|
|
656 for (j=0; j < len/3; j++) {
|
|
657 char* s1 = iso_639_1_code;
|
|
658 char* s2 = *p;
|
|
659
|
|
660 if (s1[0]==s2[0] && s1[1]==s2[1]) {
|
|
661 p++;
|
|
662 return *p;
|
|
663 }
|
|
664
|
|
665 p = p + 3;
|
|
666 }
|
|
667
|
|
668 return NULL;
|
|
669 }
|
|
670
|
|
671 /* Utility function to search in the iso_639_1 table for a language name;
|
|
672 returns the corresponding iso-639-3 code or NULL if not found. */
|
|
673
|
|
674 static char*
|
|
675 language_name_to_639_3(char* name) {
|
|
676 int len = sizeof(iso_639)/sizeof(iso_639[0]);
|
|
677 char **p = iso_639;
|
|
678 int j;
|
|
679
|
|
680 p = p + 2;
|
|
681 for (j=0; j < len/3; j++) {
|
|
682 if (str_case_equals(name, *p)) {
|
|
683 p--;
|
|
684 return *p;
|
|
685 }
|
|
686
|
|
687 p = p + 3;
|
|
688 }
|
|
689
|
|
690 return NULL;
|
|
691 }
|
|
692
|
|
693 /* Utility function to search in the iso_3166 table for a country name;
|
|
694 returns the corresponding iso-3166 code or NULL if not found. */
|
|
695
|
|
696 static char*
|
|
697 country_name_to_3166 (char* name) {
|
|
698 int len = sizeof(iso_3166)/sizeof(iso_3166[0]);
|
|
699 char **p = iso_3166;
|
|
700 int j;
|
|
701
|
|
702 p++;
|
|
703 for (j=0; j < len/2; j++) {
|
|
704 if (str_case_equals(name, *p)) {
|
|
705 p--;
|
|
706 return *p;
|
|
707 }
|
|
708
|
|
709 p = p + 2;
|
|
710 }
|
|
711
|
|
712 return NULL;
|
|
713 }
|
|
714
|
111
|
715 /*
|
|
716 c_get_language_code needs to fill in the Alpha-3 encoding of the
|
|
717 language code (3 lowercase letters). That should be "und" if the
|
|
718 language is unknown. [see Ada.Locales]
|
|
719 */
|
131
|
720 void
|
|
721 c_get_language_code (char4 p) {
|
|
722 char* Saved_Locale = setlocale(LC_ALL, NULL);
|
|
723 char iso_639_3_code[] = "und"; /* Language Unknown */
|
|
724 char* lc_all;
|
|
725 char* result;
|
|
726
|
|
727 /* Get locales set in the environment */
|
|
728
|
|
729 setlocale(LC_ALL, "");
|
|
730 lc_all = setlocale(LC_ALL, NULL);
|
|
731
|
|
732 /* The string returned by setlocale has the following format:
|
|
733
|
|
734 language[_territory][.code-set][@modifier]
|
|
735
|
|
736 where language is an ISO 639 language code, territory is an ISO 3166
|
|
737 country code, and codeset is a character set or encoding identifier
|
|
738 like ISO-8859-1 or UTF-8.
|
|
739 */
|
|
740
|
|
741 if (lc_all != NULL) {
|
|
742 char* s = lc_all;
|
|
743 int lang_length = 0;
|
|
744
|
|
745 /* Copy the language part (which may be an ISO-639-1 code, an ISO-639-3
|
|
746 code, or a language name) adding a string terminator */
|
|
747
|
|
748 while (*s != '_' && *s != '.' && *s != '@' && *s != '\0')
|
|
749 s++;
|
|
750
|
|
751 lang_length = s - lc_all;
|
|
752
|
|
753 /* Handle conversion of ISO-639-1 to ISO-639-3 */
|
|
754
|
|
755 if (lang_length == 2) {
|
|
756 char iso_639_1[3];
|
|
757 char* to_iso_639_3;
|
|
758
|
|
759 /* Duplicate the ISO-639-1 code adding the null terminator required to
|
|
760 search for the equivalent ISO-639-3 code; we cannot just append the
|
|
761 null terminator since the pointer may reference non-writable memory.
|
|
762 */
|
|
763
|
|
764 str_copy(iso_639_1, lc_all, lang_length);
|
|
765 to_iso_639_3 = iso_639_1_to_639_3(iso_639_1);
|
|
766
|
|
767 if (to_iso_639_3)
|
|
768 str_copy(iso_639_3_code, to_iso_639_3, 3);
|
|
769
|
|
770 /* Copy the ISO-639-3 code (adding a null terminator) */
|
|
771
|
|
772 } else if (lang_length == 3) {
|
|
773 str_copy(iso_639_3_code, lc_all, lang_length);
|
|
774
|
|
775 /* Handle conversion of language name to ISO-639-3 */
|
|
776
|
|
777 } else if (lang_length > 3) {
|
|
778 char name_copy[lang_length + 1];
|
|
779 char* to_iso_639_3;
|
|
780
|
|
781 /* Duplicate the ISO-639-1 code adding the null terminator required to
|
|
782 search for the equivalent ISO-639-3 code; we cannot just append the
|
|
783 null terminator since the pointer may reference non-writable memory.
|
|
784 */
|
|
785
|
|
786 str_copy(name_copy, lc_all, lang_length);
|
|
787 to_iso_639_3 = language_name_to_639_3(name_copy);
|
|
788
|
|
789 if (to_iso_639_3)
|
|
790 str_copy(iso_639_3_code, to_iso_639_3, 3);
|
|
791 }
|
|
792 }
|
|
793
|
|
794 /* Copy out the computed ISO_639_3 code */
|
|
795
|
|
796 result = iso_639_3_code;
|
|
797 for (; *result != '\0'; p++, result++)
|
|
798 *p = *result;
|
|
799
|
|
800 /* Restore the original locale settings */
|
|
801
|
|
802 setlocale(LC_ALL, Saved_Locale);
|
|
803
|
|
804 return;
|
111
|
805 }
|
|
806
|
|
807 /*
|
|
808 c_get_country_code needs to fill in the Alpha-2 encoding of the
|
|
809 country code (2 uppercase letters). That should be "ZZ" if the
|
|
810 country is unknown. [see Ada.Locales]
|
|
811 */
|
131
|
812 void
|
|
813 c_get_country_code (char4 p) {
|
|
814 char* Saved_Locale = setlocale(LC_ALL, NULL);
|
|
815 char iso_3166_code[] = "ZZ"; /* Country Unknown */
|
|
816 char* lc_all;
|
|
817 char* result;
|
|
818
|
|
819 /* Get locales set in the environment */
|
|
820
|
|
821 setlocale(LC_ALL, "");
|
|
822 lc_all = setlocale(LC_ALL, NULL);
|
|
823
|
|
824 /* The string returned by setlocale has the following format:
|
|
825
|
|
826 language[_territory][.code-set][@modifier]
|
|
827
|
|
828 where language is an ISO 639 language code, territory is an ISO 3166
|
|
829 country code, and codeset is a character set or encoding identifier
|
|
830 like ISO-8859-1 or UTF-8.
|
|
831 */
|
|
832
|
|
833 if (lc_all != NULL) {
|
|
834 char* s1 = lc_all;
|
|
835 char* s2 = NULL;
|
|
836 char* last_byte = str_get_last_byte(lc_all);
|
|
837 int country_length = 0;
|
|
838
|
|
839 /* Search for the beginning of the country code */
|
|
840
|
|
841 s1 = lc_all;
|
|
842 while (*s1 != '_' && *s1 != '.' && *s1 != '@' && s1 != last_byte)
|
|
843 s1++;
|
|
844
|
|
845 if (*s1 == '_') {
|
|
846 s1++;
|
|
847 s2 = s1;
|
|
848
|
|
849 while (*s2 != '.' && *s2 != '@' && s2 != last_byte)
|
|
850 s2++;
|
|
851
|
|
852 country_length = s2 - s1;
|
|
853
|
|
854 if (country_length == 2) {
|
|
855 str_copy(iso_3166_code, s1, country_length);
|
|
856
|
|
857 /* setlocale returned us the country name */
|
|
858
|
|
859 } else if (country_length > 3) {
|
|
860 char name_copy[country_length + 1];
|
|
861 char* to_3166;
|
|
862
|
|
863 str_copy(name_copy, s1, country_length);
|
|
864 to_3166 = country_name_to_3166(name_copy);
|
|
865
|
|
866 if (to_3166)
|
|
867 str_copy(iso_3166_code, to_3166, 2);
|
|
868 }
|
|
869 }
|
|
870 }
|
|
871
|
|
872 /* Copy out the computed ISO_3166 code */
|
|
873
|
|
874 result = iso_3166_code;
|
|
875 for (; *result != '\0'; p++, result++)
|
|
876 *p = *result;
|
|
877
|
|
878 /* Restore the original locale settings */
|
|
879
|
|
880 setlocale(LC_ALL, Saved_Locale);
|
|
881
|
|
882 return;
|
111
|
883 }
|