1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 38393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius* Copyright (C) 1997-2013, International Business Machines 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File ULOC.CPP 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 04/01/97 aliu Creation. 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 08/21/98 stephen JDK 1.2 sync 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 12/08/98 rtg New Locale implementation and C API 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 03/15/99 damiba overhaul. 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 04/06/99 stephen changed setDefault() to realloc and copy 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 06/14/99 stephen Changed calls to ures_open for new params 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 07/21/99 stephen Modified setDefault() to propagate to C++ 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 05/14/04 alan 7 years later: refactored, cleaned up, fixed bugs, 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* brought canonicalization code into line with spec 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*****************************************************************************/ 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POSIX's locale format, from putil.c: [no spaces] 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ll [ _CC ] [ . MM ] [ @ VV] 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru l = lang, C = ctry, M = charmap, V = variant 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uloc.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ulocimp.h" 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_cmn.h" 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "locmap.h" 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uarrsort.h" 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uenumimp.h" 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h" 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> /* for sprintf */ 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### Declarations **************************************************/ 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Locale stuff from locid.cpp */ 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void locale_set_default(const char *id); 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC const char *locale_get_default(void); 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC int32_t 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulocale_getKeywords(const char *localeID, 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *keywords, int32_t keywordCapacity, 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *values, int32_t valuesCapacity, int32_t *valLen, 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool valuesToo, 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status); 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### Data tables **************************************************/ 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Table of language codes, both 2- and 3-letter, with preference 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * given to 2-letter codes where possible. Includes 3-letter codes 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that lack a 2-letter equivalent. 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This list must be in sorted order. This list is returned directly 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to the user by some API. 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This list must be kept in sync with LANGUAGES_3, with corresponding 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * entries matched. 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This table should be terminated with a NULL entry, followed by a 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * second list, and another NULL entry. The first list is visible to 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * user code when this array is returned by API. The second list 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * contains codes we support, but do not expose through user API. 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Notes 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Tables updated per http://lcweb.loc.gov/standards/iso639-2/ to 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * include the revisions up to 2001/7/27 *CWB* 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The 3 character codes are the terminology codes like RFC 3066. This 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is compatible with prior ICU codes 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * "in" "iw" "ji" "jw" & "sh" have been withdrawn but are still in the 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * table but now at the end of the table because 3 character codes are 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * duplicates. This avoids bad searches going from 3 to 2 character 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * codes. 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The range qaa-qtz is reserved for local use 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* Generated using org.unicode.cldr.icu.GenerateISO639LanguageTables */ 9659d709d503bab6e2b61931737e662dd293b40578ccornelius/* ISO639 table version is 20130531 */ 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const LANGUAGES[] = { 988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "aa", "ab", "ace", "ach", "ada", "ady", "ae", "af", 998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "afa", "afh", "agq", "ain", "ak", "akk", "ale", "alg", 1008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "alt", "am", "an", "ang", "anp", "apa", "ar", "arc", 1018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "arn", "arp", "art", "arw", "as", "asa", "ast", "ath", 1028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "aus", "av", "awa", "ay", "az", 1038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ba", "bad", "bai", "bal", "ban", "bas", "bat", "bax", 1048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "bbj", "be", "bej", "bem", "ber", "bez", "bfd", "bg", 1058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "bh", "bho", "bi", "bik", "bin", "bkm", "bla", "bm", 1068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "bn", "bnt", "bo", "br", "bra", "brx", "bs", "bss", 1078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "btk", "bua", "bug", "bum", "byn", "byv", 1088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ca", "cad", "cai", "car", "cau", "cay", "cch", "ce", 1098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ceb", "cel", "cgg", "ch", "chb", "chg", "chk", "chm", 1108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "chn", "cho", "chp", "chr", "chy", "ckb", "cmc", "co", 1118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "cop", "cpe", "cpf", "cpp", "cr", "crh", "crp", "cs", 1128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "csb", "cu", "cus", "cv", "cy", 1138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "da", "dak", "dar", "dav", "day", "de", "del", "den", 1148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "dgr", "din", "dje", "doi", "dra", "dsb", "dua", "dum", 1158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "dv", "dyo", "dyu", "dz", "dzg", 1168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ebu", "ee", "efi", "egy", "eka", "el", "elx", "en", 1178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "enm", "eo", "es", "et", "eu", "ewo", 1188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "fa", "fan", "fat", "ff", "fi", "fil", "fiu", "fj", 1198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "fo", "fon", "fr", "frm", "fro", "frr", "frs", "fur", 1208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "fy", 1218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ga", "gaa", "gay", "gba", "gd", "gem", "gez", "gil", 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "gl", "gmh", "gn", "goh", "gon", "gor", "got", "grb", 1238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "grc", "gsw", "gu", "guz", "gv", "gwi", 1248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ha", "hai", "haw", "he", "hi", "hil", "him", "hit", 1258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "hmn", "ho", "hr", "hsb", "ht", "hu", "hup", "hy", 1268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "hz", 1278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ia", "iba", "ibb", "id", "ie", "ig", "ii", "ijo", 1288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ik", "ilo", "inc", "ine", "inh", "io", "ira", "iro", 1298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "is", "it", "iu", 1308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ja", "jbo", "jgo", "jmc", "jpr", "jrb", "jv", 1318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ka", "kaa", "kab", "kac", "kaj", "kam", "kar", "kaw", 1328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "kbd", "kbl", "kcg", "kde", "kea", "kfo", "kg", "kha", 1338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "khi", "kho", "khq", "ki", "kj", "kk", "kkj", "kl", 1348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "kln", "km", "kmb", "kn", "ko", "kok", "kos", "kpe", 1358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "kr", "krc", "krl", "kro", "kru", "ks", "ksb", "ksf", 1368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ksh", "ku", "kum", "kut", "kv", "kw", "ky", 1378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "la", "lad", "lag", "lah", "lam", "lb", "lez", "lg", 1388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "li", "lkt", "ln", "lo", "lol", "loz", "lt", "lu", 1398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "lua", "lui", "lun", "luo", "lus", "luy", "lv", 1408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mad", "maf", "mag", "mai", "mak", "man", "map", "mas", 1418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mde", "mdf", "mdr", "men", "mer", "mfe", "mg", "mga", 1428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mgh", "mgo", "mh", "mi", "mic", "min", "mis", "mk", 1438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mkh", "ml", "mn", "mnc", "mni", "mno", "mo", "moh", 1448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mos", "mr", "ms", "mt", "mua", "mul", "mun", "mus", 1458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mwl", "mwr", "my", "mye", "myn", "myv", 1468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "na", "nah", "nai", "nap", "naq", "nb", "nd", "nds", 1478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ne", "new", "ng", "nia", "nic", "niu", "nl", "nmg", 1488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "nn", "nnh", "no", "nog", "non", "nqo", "nr", "nso", 1498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "nub", "nus", "nv", "nwc", "ny", "nym", "nyn", "nyo", 1508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "nzi", 1518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "oc", "oj", "om", "or", "os", "osa", "ota", "oto", 1528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "pa", "paa", "pag", "pal", "pam", "pap", "pau", "peo", 1538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "phi", "phn", "pi", "pl", "pon", "pra", "pro", "ps", 1548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "pt", 1558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "qu", 1568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "raj", "rap", "rar", "rm", "rn", "ro", "roa", "rof", 1578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "rom", "ru", "rup", "rw", "rwk", 1588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "sa", "sad", "sah", "sai", "sal", "sam", "saq", "sas", 1598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "sat", "sba", "sbp", "sc", "scn", "sco", "sd", "se", 1608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "see", "seh", "sel", "sem", "ses", "sg", "sga", "sgn", 1618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "shi", "shn", "shu", "si", "sid", "sio", "sit", 1628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "sk", "sl", "sla", "sm", "sma", "smi", "smj", "smn", 1638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "sms", "sn", "snk", "so", "sog", "son", "sq", "sr", 1648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "srn", "srr", "ss", "ssa", "ssy", "st", "su", "suk", 1658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "sus", "sux", "sv", "sw", "swb", "swc", "syc", "syr", 1668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ta", "tai", "te", "tem", "teo", "ter", "tet", "tg", 1678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "th", "ti", "tig", "tiv", "tk", "tkl", "tl", "tlh", 1688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "tli", "tmh", "tn", "to", "tog", "tpi", "tr", "trv", 1698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ts", "tsi", "tt", "tum", "tup", "tut", "tvl", "tw", 1708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "twq", "ty", "tyv", "tzm", 1718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "udm", "ug", "uga", "uk", "umb", "und", "ur", "uz", 1728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "vai", "ve", "vi", "vo", "vot", "vun", 1738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "wa", "wae", "wak", "wal", "war", "was", "wen", "wo", 1748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "xal", "xh", "xog", 1758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "yao", "yap", "yav", "ybb", "yi", "yo", "ypk", "yue", 17659d709d503bab6e2b61931737e662dd293b40578ccornelius "za", "zap", "zbl", "zen", "zgh", "zh", "znd", "zu", 17759d709d503bab6e2b61931737e662dd293b40578ccornelius "zun", "zxx", "zza", 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL, 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "in", "iw", "ji", "jw", "sh", /* obsolete language codes */ 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* const DEPRECATED_LANGUAGES[]={ 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "in", "iw", "ji", "jw", NULL, NULL 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* const REPLACEMENT_LANGUAGES[]={ 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "id", "he", "yi", "jv", NULL, NULL 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Table of 3-letter language codes. 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is a lookup table used to convert 3-letter language codes to 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * their 2-letter equivalent, where possible. It must be kept in sync 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * with LANGUAGES. For all valid i, LANGUAGES[i] must refer to the 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * same language as LANGUAGES_3[i]. The commented-out lines are 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * copied from LANGUAGES to make eyeballing this baby easier. 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Where a 3-letter language code has no 2-letter equivalent, the 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 3-letter code occupies both LANGUAGES[i] and LANGUAGES_3[i]. 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This table should be terminated with a NULL entry, followed by a 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * second list, and another NULL entry. The two lists correspond to 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the two lists in LANGUAGES. 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* Generated using org.unicode.cldr.icu.GenerateISO639LanguageTables */ 20759d709d503bab6e2b61931737e662dd293b40578ccornelius/* ISO639 table version is 20130531 */ 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const LANGUAGES_3[] = { 2098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "aar", "abk", "ace", "ach", "ada", "ady", "ave", "afr", 2108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "afa", "afh", "agq", "ain", "aka", "akk", "ale", "alg", 2118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "alt", "amh", "arg", "ang", "anp", "apa", "ara", "arc", 2128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "arn", "arp", "art", "arw", "asm", "asa", "ast", "ath", 2138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "aus", "ava", "awa", "aym", "aze", 2148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "bak", "bad", "bai", "bal", "ban", "bas", "bat", "bax", 2158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "bbj", "bel", "bej", "bem", "ber", "bez", "bfd", "bul", 2168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "bih", "bho", "bis", "bik", "bin", "bkm", "bla", "bam", 2178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ben", "bnt", "bod", "bre", "bra", "brx", "bos", "bss", 2188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "btk", "bua", "bug", "bum", "byn", "byv", 2198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "cat", "cad", "cai", "car", "cau", "cay", "cch", "che", 2208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ceb", "cel", "cgg", "cha", "chb", "chg", "chk", "chm", 2218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "chn", "cho", "chp", "chr", "chy", "ckb", "cmc", "cos", 2228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "cop", "cpe", "cpf", "cpp", "cre", "crh", "crp", "ces", 2238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "csb", "chu", "cus", "chv", "cym", 2248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "dan", "dak", "dar", "dav", "day", "deu", "del", "den", 2258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "dgr", "din", "dje", "doi", "dra", "dsb", "dua", "dum", 2268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "div", "dyo", "dyu", "dzo", "dzg", 2278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ebu", "ewe", "efi", "egy", "eka", "ell", "elx", "eng", 2288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "enm", "epo", "spa", "est", "eus", "ewo", 2298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "fas", "fan", "fat", "ful", "fin", "fil", "fiu", "fij", 2308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "fao", "fon", "fra", "frm", "fro", "frr", "frs", "fur", 2318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "fry", 2328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "gle", "gaa", "gay", "gba", "gla", "gem", "gez", "gil", 2338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "glg", "gmh", "grn", "goh", "gon", "gor", "got", "grb", 2348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "grc", "gsw", "guj", "guz", "glv", "gwi", 2358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "hau", "hai", "haw", "heb", "hin", "hil", "him", "hit", 2368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "hmn", "hmo", "hrv", "hsb", "hat", "hun", "hup", "hye", 2378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "her", 2388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ina", "iba", "ibb", "ind", "ile", "ibo", "iii", "ijo", 2398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ipk", "ilo", "inc", "ine", "inh", "ido", "ira", "iro", 2408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "isl", "ita", "iku", 2418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "jpn", "jbo", "jgo", "jmc", "jpr", "jrb", "jav", 2428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "kat", "kaa", "kab", "kac", "kaj", "kam", "kar", "kaw", 2438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "kbd", "kbl", "kcg", "kde", "kea", "kfo", "kon", "kha", 2448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "khi", "kho", "khq", "kik", "kua", "kaz", "kkj", "kal", 2458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "kln", "khm", "kmb", "kan", "kor", "kok", "kos", "kpe", 2468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "kau", "krc", "krl", "kro", "kru", "kas", "ksb", "ksf", 2478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ksh", "kur", "kum", "kut", "kom", "cor", "kir", 2488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "lat", "lad", "lag", "lah", "lam", "ltz", "lez", "lug", 2498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "lim", "lkt", "lin", "lao", "lol", "loz", "lit", "lub", 2508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "lua", "lui", "lun", "luo", "lus", "luy", "lav", 2518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mad", "maf", "mag", "mai", "mak", "man", "map", "mas", 2528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mde", "mdf", "mdr", "men", "mer", "mfe", "mlg", "mga", 2538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mgh", "mgo", "mah", "mri", "mic", "min", "mis", "mkd", 2548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mkh", "mal", "mon", "mnc", "mni", "mno", "mol", "moh", 2558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mos", "mar", "msa", "mlt", "mua", "mul", "mun", "mus", 2568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "mwl", "mwr", "mya", "mye", "myn", "myv", 2578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "nau", "nah", "nai", "nap", "naq", "nob", "nde", "nds", 2588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "nep", "new", "ndo", "nia", "nic", "niu", "nld", "nmg", 2598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "nno", "nnh", "nor", "nog", "non", "nqo", "nbl", "nso", 2608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "nub", "nus", "nav", "nwc", "nya", "nym", "nyn", "nyo", 2618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "nzi", 2628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "oci", "oji", "orm", "ori", "oss", "osa", "ota", "oto", 2638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "pan", "paa", "pag", "pal", "pam", "pap", "pau", "peo", 2648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "phi", "phn", "pli", "pol", "pon", "pra", "pro", "pus", 2658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "por", 2668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "que", 2678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "raj", "rap", "rar", "roh", "run", "ron", "roa", "rof", 2688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "rom", "rus", "rup", "kin", "rwk", 2698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "san", "sad", "sah", "sai", "sal", "sam", "saq", "sas", 2708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "sat", "sba", "sbp", "srd", "scn", "sco", "snd", "sme", 2718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "see", "seh", "sel", "sem", "ses", "sag", "sga", "sgn", 2728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "shi", "shn", "shu", "sin", "sid", "sio", "sit", 2738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "slk", "slv", "sla", "smo", "sma", "smi", "smj", "smn", 2748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "sms", "sna", "snk", "som", "sog", "son", "sqi", "srp", 2758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "srn", "srr", "ssw", "ssa", "ssy", "sot", "sun", "suk", 2768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "sus", "sux", "swe", "swa", "swb", "swc", "syc", "syr", 2778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "tam", "tai", "tel", "tem", "teo", "ter", "tet", "tgk", 2788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "tha", "tir", "tig", "tiv", "tuk", "tkl", "tgl", "tlh", 2798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "tli", "tmh", "tsn", "ton", "tog", "tpi", "tur", "trv", 2808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "tso", "tsi", "tat", "tum", "tup", "tut", "tvl", "twi", 2818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "twq", "tah", "tyv", "tzm", 2828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "udm", "uig", "uga", "ukr", "umb", "und", "urd", "uzb", 2838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "vai", "ven", "vie", "vol", "vot", "vun", 2848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "wln", "wae", "wak", "wal", "war", "was", "wen", "wol", 2858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "xal", "xho", "xog", 2868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "yao", "yap", "yav", "ybb", "yid", "yor", "ypk", "yue", 28759d709d503bab6e2b61931737e662dd293b40578ccornelius "zha", "zap", "zbl", "zen", "zgh", "zho", "znd", "zul", 28859d709d503bab6e2b61931737e662dd293b40578ccornelius "zun", "zxx", "zza", 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL, 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "in", "iw", "ji", "jw", "sh", */ 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ind", "heb", "yid", "jaw", "srp", 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Table of 2-letter country codes. 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This list must be in sorted order. This list is returned directly 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to the user by some API. 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This list must be kept in sync with COUNTRIES_3, with corresponding 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * entries matched. 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This table should be terminated with a NULL entry, followed by a 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * second list, and another NULL entry. The first list is visible to 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * user code when this array is returned by API. The second list 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * contains codes we support, but do not expose through user API. 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Notes: 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * ZR(ZAR) is now CD(COD) and FX(FXX) is PS(PSE) as per 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * http://www.evertype.com/standards/iso3166/iso3166-1-en.html added 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * new codes keeping the old ones for compatibility updated to include 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1999/12/03 revisions *CWB* 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * RO(ROM) is now RO(ROU) according to 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * http://www.iso.org/iso/en/prods-services/iso3166ma/03updates-on-iso-3166/nlv3e-rou.html 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const COUNTRIES[] = { 3208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "AD", "AE", "AF", "AG", "AI", "AL", "AM", 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", 3238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", 3268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", 3448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", 3458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "WS", "YE", "YT", "ZA", "ZM", "ZW", 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL, 3518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "AN", "BU", "CS", "FX", "RO", "SU", "TP", "YD", "YU", "ZR", /* obsolete country codes */ 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const char* const DEPRECATED_COUNTRIES[] = { 3568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "AN", "BU", "CS", "DD", "DY", "FX", "HV", "NH", "RH", "SU", "TP", "UK", "VD", "YD", "YU", "ZR", NULL, NULL /* deprecated country list */ 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* const REPLACEMENT_COUNTRIES[] = { 3598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "AN", "BU", "CS", "DD", "DY", "FX", "HV", "NH", "RH", "SU", "TP", "UK", "VD", "YD", "YU", "ZR" */ 3608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "CW", "MM", "RS", "DE", "BJ", "FR", "BF", "VU", "ZW", "RU", "TL", "GB", "VN", "YE", "RS", "CD", NULL, NULL /* replacement country codes */ 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Table of 3-letter country codes. 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is a lookup table used to convert 3-letter country codes to 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * their 2-letter equivalent. It must be kept in sync with COUNTRIES. 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * For all valid i, COUNTRIES[i] must refer to the same country as 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * COUNTRIES_3[i]. The commented-out lines are copied from COUNTRIES 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to make eyeballing this baby easier. 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This table should be terminated with a NULL entry, followed by a 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * second list, and another NULL entry. The two lists correspond to 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the two lists in COUNTRIES. 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const COUNTRIES_3[] = { 3778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "AD", "AE", "AF", "AG", "AI", "AL", "AM", */ 3788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", */ 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "ALA", "AZE", 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", */ 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "BIH", "BRB", "BGD", "BEL", "BFA", "BGR", "BHR", "BDI", 3838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", */ 3848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "BEN", "BLM", "BMU", "BRN", "BOL", "BES", "BRA", "BHS", "BTN", "BVT", 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", */ 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG", 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", */ 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "CHE", "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI", 3898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", */ 3908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "CUB", "CPV", "CUW", "CXR", "CYP", "CZE", "DEU", "DJI", "DNK", 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", */ 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH", "ERI", 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", */ 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA", 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", */ 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GAB", "GBR", "GRD", "GEO", "GUF", "GGY", "GHA", "GIB", "GRL", 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", */ 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GMB", "GIN", "GLP", "GNQ", "GRC", "SGS", "GTM", "GUM", 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", */ 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI", "HUN", 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS" */ 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "IDN", "IRL", "ISR", "IMN", "IND", "IOT", "IRQ", "IRN", "ISL", 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", */ 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ITA", "JEY", "JAM", "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR", 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", */ 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "COM", "KNA", "PRK", "KOR", "KWT", "CYM", "KAZ", "LAO", 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", */ 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX", 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", */ 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "LVA", "LBY", "MAR", "MCO", "MDA", "MNE", "MAF", "MDG", "MHL", "MKD", 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", */ 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "MLI", "MMR", "MNG", "MAC", "MNP", "MTQ", "MRT", "MSR", 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", */ 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "MLT", "MUS", "MDV", "MWI", "MEX", "MYS", "MOZ", "NAM", 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", */ 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL", 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", */ 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "NRU", "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG", 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", */ 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "PHL", "PAK", "POL", "SPM", "PCN", "PRI", "PSE", "PRT", 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", */ 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "PLW", "PRY", "QAT", "REU", "ROU", "SRB", "RUS", "RWA", "SAU", 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", */ 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM", 4258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", */ 4268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "SVK", "SLE", "SMR", "SEN", "SOM", "SUR", "SSD", "STP", "SLV", 4278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", */ 4288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "SXM", "SYR", "SWZ", "TCA", "TCD", "ATF", "TGO", "THA", "TJK", 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", */ 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "TKL", "TLS", "TKM", "TUN", "TON", "TUR", "TTO", "TUV", 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", */ 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB", 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", */ 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "VAT", "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", "WLF", 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "WS", "YE", "YT", "ZA", "ZM", "ZW", */ 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "WSM", "YEM", "MYT", "ZAF", "ZMB", "ZWE", 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL, 4388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "AN", "BU", "CS", "FX", "RO", "SU", "TP", "YD", "YU", "ZR" */ 4398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ANT", "BUR", "SCG", "FXX", "ROM", "SUN", "TMP", "YMD", "YUG", "ZAR", 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct CanonicalizationMap { 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *id; /* input ID */ 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *canonicalID; /* canonicalized output ID */ 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *keyword; /* keyword, or NULL if none */ 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *value; /* keyword value, or NULL if kw==NULL */ 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} CanonicalizationMap; 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * A map to canonicalize locale IDs. This handles a variety of 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * different semantic kinds of transformations. 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const CanonicalizationMap CANONICALIZE_MAP[] = { 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "", "en_US_POSIX", NULL, NULL }, /* .NET name */ 45627f654740f2a26ad62a5c155af9199af9e69b889claireho { "c", "en_US_POSIX", NULL, NULL }, /* POSIX name */ 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "posix", "en_US_POSIX", NULL, NULL }, /* POSIX name (alias of C) */ 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "art_LOJBAN", "jbo", NULL, NULL }, /* registered name */ 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "az_AZ_CYRL", "az_Cyrl_AZ", NULL, NULL }, /* .NET name */ 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "az_AZ_LATN", "az_Latn_AZ", NULL, NULL }, /* .NET name */ 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "ca_ES_PREEURO", "ca_ES", "currency", "ESP" }, 462c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "de__PHONEBOOK", "de", "collation", "phonebook" }, /* Old ICU name */ 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "de_AT_PREEURO", "de_AT", "currency", "ATS" }, 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "de_DE_PREEURO", "de_DE", "currency", "DEM" }, 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "de_LU_PREEURO", "de_LU", "currency", "LUF" }, 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "el_GR_PREEURO", "el_GR", "currency", "GRD" }, 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "en_BE_PREEURO", "en_BE", "currency", "BEF" }, 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "en_IE_PREEURO", "en_IE", "currency", "IEP" }, 469c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "es__TRADITIONAL", "es", "collation", "traditional" }, /* Old ICU name */ 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "es_ES_PREEURO", "es_ES", "currency", "ESP" }, 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "eu_ES_PREEURO", "eu_ES", "currency", "ESP" }, 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "fi_FI_PREEURO", "fi_FI", "currency", "FIM" }, 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "fr_BE_PREEURO", "fr_BE", "currency", "BEF" }, 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "fr_FR_PREEURO", "fr_FR", "currency", "FRF" }, 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "fr_LU_PREEURO", "fr_LU", "currency", "LUF" }, 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "ga_IE_PREEURO", "ga_IE", "currency", "IEP" }, 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "gl_ES_PREEURO", "gl_ES", "currency", "ESP" }, 478c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "hi__DIRECT", "hi", "collation", "direct" }, /* Old ICU name */ 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "it_IT_PREEURO", "it_IT", "currency", "ITL" }, 480c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "ja_JP_TRADITIONAL", "ja_JP", "calendar", "japanese" }, /* Old ICU name */ 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "nb_NO_NY", "nn_NO", NULL, NULL }, /* "markus said this was ok" :-) */ 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "nl_BE_PREEURO", "nl_BE", "currency", "BEF" }, 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "nl_NL_PREEURO", "nl_NL", "currency", "NLG" }, 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "pt_PT_PREEURO", "pt_PT", "currency", "PTE" }, 485c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "sr_SP_CYRL", "sr_Cyrl_RS", NULL, NULL }, /* .NET name */ 486c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "sr_SP_LATN", "sr_Latn_RS", NULL, NULL }, /* .NET name */ 487c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "sr_YU_CYRILLIC", "sr_Cyrl_RS", NULL, NULL }, /* Linux name */ 488c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "th_TH_TRADITIONAL", "th_TH", "calendar", "buddhist" }, /* Old ICU name */ 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "uz_UZ_CYRILLIC", "uz_Cyrl_UZ", NULL, NULL }, /* Linux name */ 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "uz_UZ_CYRL", "uz_Cyrl_UZ", NULL, NULL }, /* .NET name */ 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "uz_UZ_LATN", "uz_Latn_UZ", NULL, NULL }, /* .NET name */ 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "zh_CHS", "zh_Hans", NULL, NULL }, /* .NET name */ 493c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "zh_CHT", "zh_Hant", NULL, NULL }, /* .NET name */ 494103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_GAN", "gan", NULL, NULL }, /* registered name */ 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "zh_GUOYU", "zh", NULL, NULL }, /* registered name */ 496103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_HAKKA", "hak", NULL, NULL }, /* registered name */ 497103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_MIN_NAN", "nan", NULL, NULL }, /* registered name */ 498103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_WUU", "wuu", NULL, NULL }, /* registered name */ 499103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_XIANG", "hsn", NULL, NULL }, /* registered name */ 500103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_YUE", "yue", NULL, NULL }, /* registered name */ 501c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}; 502c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 503c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querutypedef struct VariantMap { 504c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char *variant; /* input ID */ 505c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char *keyword; /* keyword, or NULL if none */ 506c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char *value; /* keyword value, or NULL if kw==NULL */ 507c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} VariantMap; 508c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 509c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const VariantMap VARIANT_MAP[] = { 510c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "EURO", "currency", "EUR" }, 511c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "PINYIN", "collation", "pinyin" }, /* Solaris variant */ 512c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "STROKE", "collation", "stroke" } /* Solaris variant */ 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 51527f654740f2a26ad62a5c155af9199af9e69b889claireho/* ### BCP47 Conversion *******************************************/ 51627f654740f2a26ad62a5c155af9199af9e69b889claireho/* Test if the locale id has BCP47 u extension and does not have '@' */ 51727f654740f2a26ad62a5c155af9199af9e69b889claireho#define _hasBCP47Extension(id) (id && uprv_strstr(id, "@") == NULL && getShortestSubtagLength(localeID) == 1) 51827f654740f2a26ad62a5c155af9199af9e69b889claireho/* Converts the BCP47 id to Unicode id. Does nothing to id if conversion fails */ 51927f654740f2a26ad62a5c155af9199af9e69b889claireho#define _ConvertBCP47(finalID, id, buffer, length,err) \ 52027f654740f2a26ad62a5c155af9199af9e69b889claireho if (uloc_forLanguageTag(id, buffer, length, NULL, err) <= 0 || U_FAILURE(*err)) { \ 52127f654740f2a26ad62a5c155af9199af9e69b889claireho finalID=id; \ 52227f654740f2a26ad62a5c155af9199af9e69b889claireho } else { \ 52327f654740f2a26ad62a5c155af9199af9e69b889claireho finalID=buffer; \ 52427f654740f2a26ad62a5c155af9199af9e69b889claireho } 52527f654740f2a26ad62a5c155af9199af9e69b889claireho/* Gets the size of the shortest subtag in the given localeID. */ 52627f654740f2a26ad62a5c155af9199af9e69b889clairehostatic int32_t getShortestSubtagLength(const char *localeID) { 52727f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t localeIDLength = uprv_strlen(localeID); 52827f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t length = localeIDLength; 52927f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t tmpLength = 0; 53027f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t i; 53127f654740f2a26ad62a5c155af9199af9e69b889claireho UBool reset = TRUE; 53227f654740f2a26ad62a5c155af9199af9e69b889claireho 53327f654740f2a26ad62a5c155af9199af9e69b889claireho for (i = 0; i < localeIDLength; i++) { 53427f654740f2a26ad62a5c155af9199af9e69b889claireho if (localeID[i] != '_' && localeID[i] != '-') { 53527f654740f2a26ad62a5c155af9199af9e69b889claireho if (reset) { 53627f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLength = 0; 53727f654740f2a26ad62a5c155af9199af9e69b889claireho reset = FALSE; 53827f654740f2a26ad62a5c155af9199af9e69b889claireho } 53927f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLength++; 54027f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 54127f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpLength != 0 && tmpLength < length) { 54227f654740f2a26ad62a5c155af9199af9e69b889claireho length = tmpLength; 54327f654740f2a26ad62a5c155af9199af9e69b889claireho } 54427f654740f2a26ad62a5c155af9199af9e69b889claireho reset = TRUE; 54527f654740f2a26ad62a5c155af9199af9e69b889claireho } 54627f654740f2a26ad62a5c155af9199af9e69b889claireho } 54727f654740f2a26ad62a5c155af9199af9e69b889claireho 54827f654740f2a26ad62a5c155af9199af9e69b889claireho return length; 54927f654740f2a26ad62a5c155af9199af9e69b889claireho} 55027f654740f2a26ad62a5c155af9199af9e69b889claireho 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### Keywords **************************************************/ 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ULOC_KEYWORD_BUFFER_LEN 25 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ULOC_MAX_NO_KEYWORDS 25 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55627f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI const char * U_EXPORT2 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulocale_getKeywordsStart(const char *localeID) { 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *result = NULL; 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((result = uprv_strchr(localeID, '@')) != NULL) { 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (U_CHARSET_FAMILY == U_EBCDIC_FAMILY) 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We do this because the @ sign is variant, and the @ sign used on one 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru EBCDIC machine won't be compiled the same way on other EBCDIC based 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru machines. */ 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static const uint8_t ebcdicSigns[] = { 0x7C, 0x44, 0x66, 0x80, 0xAC, 0xAE, 0xAF, 0xB5, 0xEC, 0xEF, 0x00 }; 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *charToFind = ebcdicSigns; 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*charToFind) { 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((result = uprv_strchr(localeID, *charToFind)) != NULL) { 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charToFind++; 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param buf buffer of size [ULOC_KEYWORD_BUFFER_LEN] 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param keywordName incoming name to be canonicalized 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param status return status (keyword too long) 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return length of the keyword name 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t locale_canonKeywordName(char *buf, const char *keywordName, UErrorCode *status) 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordNameLen = (int32_t)uprv_strlen(keywordName); 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordNameLen >= ULOC_KEYWORD_BUFFER_LEN) { 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keyword name too long for internal buffer */ 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* normalize the keyword name */ 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0; i < keywordNameLen; i++) { 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf[i] = uprv_tolower(keywordName[i]); 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf[i] = 0; 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return keywordNameLen; 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct { 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keyword[ULOC_KEYWORD_BUFFER_LEN]; 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordLen; 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *valueStart; 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t valueLen; 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} KeywordStruct; 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 614103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliuscompareKeywordStructs(const void * /*context*/, const void *left, const void *right) { 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* leftString = ((const KeywordStruct *)left)->keyword; 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* rightString = ((const KeywordStruct *)right)->keyword; 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_strcmp(leftString, rightString); 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Both addKeyword and addValue must already be in canonical form. 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Either both addKeyword and addValue are NULL, or neither is NULL. 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If they are not NULL they must be zero terminated. 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If addKeyword is not NULL is must have length small enough to fit in KeywordStruct.keyword. 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_getKeywords(const char *localeID, 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *keywords, int32_t keywordCapacity, 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *values, int32_t valuesCapacity, int32_t *valLen, 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool valuesToo, 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* addKeyword, 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* addValue, 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru KeywordStruct keywordList[ULOC_MAX_NO_KEYWORDS]; 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t maxKeywords = ULOC_MAX_NO_KEYWORDS; 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t numKeywords = 0; 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* pos = localeID; 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* equalSign = NULL; 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* semicolon = NULL; 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0, j, n; 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordsLen = 0; 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t valuesLen = 0; 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(prev == '@') { /* start of keyword definition */ 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we will grab pairs, trim spaces, lowercase keywords, sort and return */ 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool duplicate = FALSE; 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip leading spaces */ 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*pos == ' ') { 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pos++; 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!*pos) { /* handle trailing "; " */ 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(numKeywords == maxKeywords) { 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru equalSign = uprv_strchr(pos, '='); 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru semicolon = uprv_strchr(pos, ';'); 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* lack of '=' [foo@currency] is illegal */ 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* ';' before '=' [foo@currency;collation=pinyin] is illegal */ 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!equalSign || (semicolon && semicolon<equalSign)) { 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* need to normalize both keyword and keyword name */ 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(equalSign - pos >= ULOC_KEYWORD_BUFFER_LEN) { 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keyword name too long for internal buffer */ 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0, n = 0; i < equalSign - pos; ++i) { 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pos[i] != ' ') { 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].keyword[n++] = uprv_tolower(pos[i]); 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 68159d709d503bab6e2b61931737e662dd293b40578ccornelius 68259d709d503bab6e2b61931737e662dd293b40578ccornelius /* zero-length keyword is an error. */ 68359d709d503bab6e2b61931737e662dd293b40578ccornelius if (n == 0) { 68459d709d503bab6e2b61931737e662dd293b40578ccornelius *status = U_INVALID_FORMAT_ERROR; 68559d709d503bab6e2b61931737e662dd293b40578ccornelius return 0; 68659d709d503bab6e2b61931737e662dd293b40578ccornelius } 68759d709d503bab6e2b61931737e662dd293b40578ccornelius 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].keyword[n] = 0; 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].keywordLen = n; 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* now grab the value part. First we skip the '=' */ 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru equalSign++; 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* then we leading spaces */ 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*equalSign == ' ') { 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru equalSign++; 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 69659d709d503bab6e2b61931737e662dd293b40578ccornelius 69759d709d503bab6e2b61931737e662dd293b40578ccornelius /* Premature end or zero-length value */ 69859d709d503bab6e2b61931737e662dd293b40578ccornelius if (!equalSign || equalSign == semicolon) { 69959d709d503bab6e2b61931737e662dd293b40578ccornelius *status = U_INVALID_FORMAT_ERROR; 70059d709d503bab6e2b61931737e662dd293b40578ccornelius return 0; 70159d709d503bab6e2b61931737e662dd293b40578ccornelius } 70259d709d503bab6e2b61931737e662dd293b40578ccornelius 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueStart = equalSign; 70459d709d503bab6e2b61931737e662dd293b40578ccornelius 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pos = semicolon; 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = 0; 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pos) { 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*(pos - i - 1) == ' ') { 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i++; 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueLen = (int32_t)(pos - equalSign - i); 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pos++; 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = (int32_t)uprv_strlen(equalSign); 715816c50fb47edc483a0516072584640b520045214claireho while(i && equalSign[i-1] == ' ') { 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i--; 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueLen = i; 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If this is a duplicate keyword, then ignore it */ 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j=0; j<numKeywords; ++j) { 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(keywordList[j].keyword, keywordList[numKeywords].keyword) == 0) { 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru duplicate = TRUE; 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!duplicate) { 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++numKeywords; 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(pos); 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Handle addKeyword/addValue. */ 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (addKeyword != NULL) { 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool duplicate = FALSE; 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ASSERT(addValue != NULL); 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Search for duplicate; if found, do nothing. Explicit keyword 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru overrides addKeyword. */ 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j=0; j<numKeywords; ++j) { 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(keywordList[j].keyword, addKeyword) == 0) { 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru duplicate = TRUE; 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!duplicate) { 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (numKeywords == maxKeywords) { 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(keywordList[numKeywords].keyword, addKeyword); 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].keywordLen = (int32_t)uprv_strlen(addKeyword); 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueStart = addValue; 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueLen = (int32_t)uprv_strlen(addValue); 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++numKeywords; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ASSERT(addValue == NULL); 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* now we have a list of keywords */ 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we need to sort it */ 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_sortArray(keywordList, numKeywords, sizeof(KeywordStruct), compareKeywordStructs, NULL, FALSE, status); 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Now construct the keyword part */ 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0; i < numKeywords; i++) { 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordsLen + keywordList[i].keywordLen + 1< keywordCapacity) { 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(keywords+keywordsLen, keywordList[i].keyword); 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(valuesToo) { 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywords[keywordsLen + keywordList[i].keywordLen] = '='; 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywords[keywordsLen + keywordList[i].keywordLen] = 0; 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordsLen += keywordList[i].keywordLen + 1; 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(valuesToo) { 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordsLen + keywordList[i].valueLen < keywordCapacity) { 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(keywords+keywordsLen, keywordList[i].valueStart, keywordList[i].valueLen); 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordsLen += keywordList[i].valueLen; 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i < numKeywords - 1) { 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordsLen < keywordCapacity) { 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywords[keywordsLen] = ';'; 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordsLen++; 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(values) { 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(valuesLen + keywordList[i].valueLen + 1< valuesCapacity) { 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(values+valuesLen, keywordList[i].valueStart); 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru values[valuesLen + keywordList[i].valueLen] = 0; 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru valuesLen += keywordList[i].valueLen + 1; 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(values) { 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru values[valuesLen] = 0; 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(valLen) { 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *valLen = valuesLen; 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(keywords, keywordCapacity, keywordsLen, status); 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC int32_t 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulocale_getKeywords(const char *localeID, 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *keywords, int32_t keywordCapacity, 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *values, int32_t valuesCapacity, int32_t *valLen, 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool valuesToo, 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) { 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _getKeywords(localeID, prev, keywords, keywordCapacity, 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru values, valuesCapacity, valLen, valuesToo, 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, NULL, status); 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getKeywordValue(const char* localeID, 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* keywordName, 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* buffer, int32_t bufferCapacity, 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status) 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 82527f654740f2a26ad62a5c155af9199af9e69b889claireho const char* startSearchHere = NULL; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* nextSeparator = NULL; 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN]; 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char localeKeywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN]; 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result = 0; 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status && U_SUCCESS(*status) && localeID) { 83327f654740f2a26ad62a5c155af9199af9e69b889claireho char tempBuffer[ULOC_FULLNAME_CAPACITY]; 83427f654740f2a26ad62a5c155af9199af9e69b889claireho const char* tmpLocaleID; 83527f654740f2a26ad62a5c155af9199af9e69b889claireho 83627f654740f2a26ad62a5c155af9199af9e69b889claireho if (_hasBCP47Extension(localeID)) { 83727f654740f2a26ad62a5c155af9199af9e69b889claireho _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), status); 83827f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 83927f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID=localeID; 84027f654740f2a26ad62a5c155af9199af9e69b889claireho } 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 84227f654740f2a26ad62a5c155af9199af9e69b889claireho startSearchHere = uprv_strchr(tmpLocaleID, '@'); /* TODO: REVISIT: shouldn't this be locale_getKeywordsStart ? */ 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(startSearchHere == NULL) { 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no keywords, return at once */ 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru locale_canonKeywordName(keywordNameBuffer, keywordName, status); 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* find the first keyword */ 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(startSearchHere) { 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere++; 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip leading spaces (allowed?) */ 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*startSearchHere == ' ') { 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere++; 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextSeparator = uprv_strchr(startSearchHere, '='); 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* need to normalize both keyword and keyword name */ 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!nextSeparator) { 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(nextSeparator - startSearchHere >= ULOC_KEYWORD_BUFFER_LEN) { 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keyword name too long for internal buffer */ 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0; i < nextSeparator - startSearchHere; i++) { 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeKeywordNameBuffer[i] = uprv_tolower(startSearchHere[i]); 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* trim trailing spaces */ 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(startSearchHere[i-1] == ' ') { 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i--; 876103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(i>=0); 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeKeywordNameBuffer[i] = 0; 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere = uprv_strchr(nextSeparator, ';'); 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uprv_strcmp(keywordNameBuffer, localeKeywordNameBuffer) == 0) { 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextSeparator++; 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*nextSeparator == ' ') { 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextSeparator++; 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we actually found the keyword. Copy the value */ 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(startSearchHere && startSearchHere - nextSeparator < bufferCapacity) { 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*(startSearchHere-1) == ' ') { 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere--; 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(buffer, nextSeparator, startSearchHere - nextSeparator); 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = u_terminateChars(buffer, bufferCapacity, (int32_t)(startSearchHere - nextSeparator), status); 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!startSearchHere && (int32_t)uprv_strlen(nextSeparator) < bufferCapacity) { /* last item in string */ 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = (int32_t)uprv_strlen(nextSeparator); 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(nextSeparator[i - 1] == ' ') { 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i--; 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(buffer, nextSeparator, i); 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = u_terminateChars(buffer, bufferCapacity, i, status); 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* give a bigger buffer, please */ 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_BUFFER_OVERFLOW_ERROR; 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(startSearchHere) { 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = (int32_t)(startSearchHere - nextSeparator); 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = (int32_t)uprv_strlen(nextSeparator); 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_setKeywordValue(const char* keywordName, 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* keywordValue, 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* buffer, int32_t bufferCapacity, 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status) 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* TODO: sorting. removal. */ 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordNameLen; 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordValueLen; 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t bufLen; 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t needLen = 0; 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t foundValueLen; 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordAtEnd = 0; /* is the keyword at the end of the string? */ 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN]; 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char localeKeywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN]; 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rc; 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* nextSeparator = NULL; 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* nextEqualsign = NULL; 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* startSearchHere = NULL; 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* keywordStart = NULL; 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *insertHere = NULL; 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bufferCapacity>1) { 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bufLen = (int32_t)uprv_strlen(buffer); 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bufferCapacity<bufLen) { 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* The capacity is less than the length?! Is this NULL terminated? */ 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordValue && !*keywordValue) { 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordValue = NULL; 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordValue) { 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordValueLen = (int32_t)uprv_strlen(keywordValue); 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordValueLen = 0; 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordNameLen = locale_canonKeywordName(keywordNameBuffer, keywordName, status); 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere = (char*)locale_getKeywordsStart(buffer); 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(startSearchHere == NULL || (startSearchHere[1]==0)) { 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!keywordValue) { /* no keywords = nothing to remove */ 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufLen; 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needLen = bufLen+1+keywordNameLen+1+keywordValueLen; 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(startSearchHere) { /* had a single @ */ 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needLen--; /* already had the @ */ 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* startSearchHere points at the @ */ 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere=buffer+bufLen; 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(needLen >= bufferCapacity) { 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_BUFFER_OVERFLOW_ERROR; 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return needLen; /* no change */ 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *startSearchHere = '@'; 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere++; 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(startSearchHere, keywordNameBuffer); 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere += keywordNameLen; 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *startSearchHere = '='; 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere++; 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(startSearchHere, keywordValue); 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere+=keywordValueLen; 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return needLen; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* end shortcut - no @ */ 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart = startSearchHere; 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* search for keyword */ 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(keywordStart) { 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart++; 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip leading spaces (allowed?) */ 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*keywordStart == ' ') { 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart++; 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextEqualsign = uprv_strchr(keywordStart, '='); 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* need to normalize both keyword and keyword name */ 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!nextEqualsign) { 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(nextEqualsign - keywordStart >= ULOC_KEYWORD_BUFFER_LEN) { 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keyword name too long for internal buffer */ 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0; i < nextEqualsign - keywordStart; i++) { 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeKeywordNameBuffer[i] = uprv_tolower(keywordStart[i]); 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* trim trailing spaces */ 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(keywordStart[i-1] == ' ') { 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i--; 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 101854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_ASSERT(i>=0 && i<ULOC_KEYWORD_BUFFER_LEN); 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeKeywordNameBuffer[i] = 0; 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextSeparator = uprv_strchr(nextEqualsign, ';'); 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = uprv_strcmp(keywordNameBuffer, localeKeywordNameBuffer); 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(rc == 0) { 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextEqualsign++; 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*nextEqualsign == ' ') { 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextEqualsign++; 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we actually found the keyword. Change the value */ 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nextSeparator) { 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordAtEnd = 0; 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru foundValueLen = (int32_t)(nextSeparator - nextEqualsign); 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordAtEnd = 1; 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru foundValueLen = (int32_t)uprv_strlen(nextEqualsign); 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordValue) { /* adding a value - not removing */ 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(foundValueLen == keywordValueLen) { 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(nextEqualsign, keywordValue, keywordValueLen); 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufLen; /* no change in size */ 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(foundValueLen > keywordValueLen) { 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t delta = foundValueLen - keywordValueLen; 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(nextSeparator) { /* RH side */ 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(nextSeparator - delta, nextSeparator, bufLen-(nextSeparator-buffer)); 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(nextEqualsign, keywordValue, keywordValueLen); 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bufLen -= delta; 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[bufLen]=0; 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufLen; 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { /* FVL < KVL */ 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t delta = keywordValueLen - foundValueLen; 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((bufLen+delta) >= bufferCapacity) { 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_BUFFER_OVERFLOW_ERROR; 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufLen+delta; 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(nextSeparator) { /* RH side */ 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(nextSeparator+delta,nextSeparator, bufLen-(nextSeparator-buffer)); 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(nextEqualsign, keywordValue, keywordValueLen); 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bufLen += delta; 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[bufLen]=0; 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufLen; 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { /* removing a keyword */ 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordAtEnd) { 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* zero out the ';' or '@' just before startSearchhere */ 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart[-1] = 0; 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)((keywordStart-buffer)-1); /* (string length without keyword) minus separator */ 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(keywordStart, nextSeparator+1, bufLen-((nextSeparator+1)-buffer)); 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart[bufLen-((nextSeparator+1)-buffer)]=0; 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)(bufLen-((nextSeparator+1)-keywordStart)); 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(rc<0){ /* end match keyword */ 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* could insert at this location. */ 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertHere = keywordStart; 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart = nextSeparator; 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* end loop searching */ 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!keywordValue) { 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufLen; /* removal of non-extant keyword - no change */ 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we know there is at least one keyword. */ 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needLen = bufLen+1+keywordNameLen+1+keywordValueLen; 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(needLen >= bufferCapacity) { 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_BUFFER_OVERFLOW_ERROR; 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return needLen; /* no change */ 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertHere) { 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(insertHere+(1+keywordNameLen+1+keywordValueLen), insertHere, bufLen-(insertHere-buffer)); 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart = insertHere; 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart = buffer+bufLen; 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *keywordStart = ';'; 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart++; 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(keywordStart, keywordNameBuffer, keywordNameLen); 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart += keywordNameLen; 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *keywordStart = '='; 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart++; 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(keywordStart, keywordValue, keywordValueLen); /* terminates. */ 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart+=keywordValueLen; 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertHere) { 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *keywordStart = ';'; 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart++; 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[needLen]=0; 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return needLen; 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### ID parsing implementation **************************************************/ 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _isPrefixLetter(a) ((a=='x')||(a=='X')||(a=='i')||(a=='I')) 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*returns TRUE if one of the special prefixes is here (s=string) 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 'x-' or 'i-' */ 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _isIDPrefix(s) (_isPrefixLetter(s[0])&&_isIDSeparator(s[1])) 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Dot terminates it because of POSIX form where dot precedes the codepage 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * except for variant 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _isTerminator(a) ((a==0)||(a=='.')||(a=='@')) 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char* _strnchr(const char* str, int32_t len, char c) { 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ASSERT(str != 0 && len >= 0); 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (len-- != 0) { 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char d = *str; 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (d == c) { 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (char*) str; 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (d == 0) { 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++str; 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Lookup 'key' in the array 'list'. The array 'list' should contain 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * a NULL entry, followed by more entries, and a second NULL entry. 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The 'list' param should be LANGUAGES, LANGUAGES_3, COUNTRIES, or 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * COUNTRIES_3. 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int16_t _findIndex(const char* const* list, const char* key) 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* const* anchor = list; 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t pass = 0; 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Make two passes through two NULL-terminated arrays at 'list' */ 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (pass++ < 2) { 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (*list) { 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(key, *list) == 0) { 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int16_t)(list - anchor); 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru list++; 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++list; /* skip final NULL *CWB*/ 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* count the length of src while copying it to dest; return strlen(src) */ 1167103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline int32_t 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_copyCount(char *dest, int32_t destCapacity, const char *src) { 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *anchor; 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru anchor=src; 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((c=*src)==0) { 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)(src-anchor); 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(destCapacity<=0) { 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)((src-anchor)+uprv_strlen(src)); 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++src; 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *dest++=c; 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --destCapacity; 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 118650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC const char* 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getCurrentCountryID(const char* oldID){ 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset = _findIndex(DEPRECATED_COUNTRIES, oldID); 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset >= 0) { 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return REPLACEMENT_COUNTRIES[offset]; 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return oldID; 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 119450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC const char* 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getCurrentLanguageID(const char* oldID){ 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset = _findIndex(DEPRECATED_LANGUAGES, oldID); 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset >= 0) { 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return REPLACEMENT_LANGUAGES[offset]; 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return oldID; 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the internal functions _getLanguage(), _getCountry(), _getVariant() 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * avoid duplicating code to handle the earlier locale ID pieces 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * in the functions for the later ones by 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * setting the *pEnd pointer to where they stopped parsing 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TODO try to use this in Locale 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 121050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC int32_t 121150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoulocimp_getLanguage(const char *localeID, 121250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *language, int32_t languageCapacity, 121350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char **pEnd) { 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset; 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char lang[4]={ 0, 0, 0, 0 }; /* temporary buffer to hold language code for searching */ 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if it starts with i- or x- then copy that prefix */ 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDPrefix(localeID)) { 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<languageCapacity) { 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru language[i]=(char)uprv_tolower(*localeID); 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<languageCapacity) { 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru language[i+1]='-'; 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i+=2; 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID+=2; 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the language as far as possible and count its length */ 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(!_isTerminator(*localeID) && !_isIDSeparator(*localeID)) { 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<languageCapacity) { 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru language[i]=(char)uprv_tolower(*localeID); 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<3) { 1236103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(i>=0); 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lang[i]=(char)uprv_tolower(*localeID); 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i++; 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID++; 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i==3) { 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* convert 3 character code to 2 character code if possible *CWB*/ 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset=_findIndex(LANGUAGES_3, lang); 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(offset>=0) { 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=_copyCount(language, languageCapacity, LANGUAGES[offset]); 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pEnd!=NULL) { 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pEnd=localeID; 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return i; 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC int32_t 125850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoulocimp_getScript(const char *localeID, 125950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *script, int32_t scriptCapacity, 126050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char **pEnd) 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t idLen = 0; 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pEnd != NULL) { 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pEnd = localeID; 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the second item as far as possible and count its length */ 1269103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius while(!_isTerminator(localeID[idLen]) && !_isIDSeparator(localeID[idLen]) 1270103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius && uprv_isASCIILetter(localeID[idLen])) { 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idLen++; 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If it's exactly 4 characters long, then it's a script and not a country. */ 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (idLen == 4) { 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pEnd != NULL) { 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pEnd = localeID+idLen; 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(idLen > scriptCapacity) { 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idLen = scriptCapacity; 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (idLen >= 1) { 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru script[0]=(char)uprv_toupper(*(localeID++)); 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 1; i < idLen; i++) { 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru script[i]=(char)uprv_tolower(*(localeID++)); 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idLen = 0; 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return idLen; 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC int32_t 129750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoulocimp_getCountry(const char *localeID, 129850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *country, int32_t countryCapacity, 129950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char **pEnd) 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 130150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t idLen=0; 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cnty[ULOC_COUNTRY_CAPACITY]={ 0, 0, 0, 0 }; 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset; 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the country as far as possible and count its length */ 130650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(!_isTerminator(localeID[idLen]) && !_isIDSeparator(localeID[idLen])) { 130750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(idLen<(ULOC_COUNTRY_CAPACITY-1)) { /*CWB*/ 130850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho cnty[idLen]=(char)uprv_toupper(localeID[idLen]); 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 131050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho idLen++; 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 131350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* the country should be either length 2 or 3 */ 131450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (idLen == 2 || idLen == 3) { 131550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool gotCountry = FALSE; 131650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* convert 3 character code to 2 character code if possible *CWB*/ 131750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(idLen==3) { 131850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho offset=_findIndex(COUNTRIES_3, cnty); 131950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(offset>=0) { 132050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho idLen=_copyCount(country, countryCapacity, COUNTRIES[offset]); 132150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho gotCountry = TRUE; 132250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 132350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 132450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (!gotCountry) { 132550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t i = 0; 132650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0; i < idLen; i++) { 132750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (i < countryCapacity) { 132850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho country[i]=(char)uprv_toupper(localeID[i]); 132950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 133050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 133250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho localeID+=idLen; 133350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 133450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho idLen = 0; 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pEnd!=NULL) { 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pEnd=localeID; 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 134050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 134150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return idLen; 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param needSeparator if true, then add leading '_' if any variants 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * are added to 'variant' 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_getVariantEx(const char *localeID, 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *variant, int32_t variantCapacity, 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool needSeparator) { 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get one or more variant tags and separate them with '_' */ 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDSeparator(prev)) { 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get a variant string after a '-' or '_' */ 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(!_isTerminator(*localeID)) { 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (needSeparator) { 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i<variantCapacity) { 1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i] = '_'; 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needSeparator = FALSE; 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<variantCapacity) { 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i]=(char)uprv_toupper(*localeID); 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(variant[i]=='-') { 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i]='_'; 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i++; 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID++; 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there is no variant tag after a '-' or '_' then look for '@' */ 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i==0) { 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(prev=='@') { 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keep localeID */ 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if((localeID=locale_getKeywordsStart(localeID))!=NULL) { 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++localeID; /* point after the '@' */ 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(!_isTerminator(*localeID)) { 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (needSeparator) { 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i<variantCapacity) { 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i] = '_'; 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needSeparator = FALSE; 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<variantCapacity) { 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i]=(char)uprv_toupper(*localeID); 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(variant[i]=='-' || variant[i]==',') { 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i]='_'; 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i++; 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID++; 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return i; 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_getVariant(const char *localeID, 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *variant, int32_t variantCapacity) { 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _getVariantEx(localeID, prev, variant, variantCapacity, FALSE); 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Delete ALL instances of a variant from the given list of one or 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * more variants. Example: "FOO_EURO_BAR_EURO" => "FOO_BAR". 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param variants the source string of one or more variants, 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * separated by '_'. This will be MODIFIED IN PLACE. Not zero 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * terminated; if it is, trailing zero will NOT be maintained. 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param variantsLen length of variants 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param toDelete variant to delete, without separators, e.g. "EURO" 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * or "PREEURO"; not zero terminated 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param toDeleteLen length of toDelete 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return number of characters deleted from variants 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_deleteVariant(char* variants, int32_t variantsLen, 1429c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char* toDelete, int32_t toDeleteLen) 1430c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t delta = 0; /* number of chars deleted */ 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) { 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool flag = FALSE; 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variantsLen < toDeleteLen) { 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return delta; 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strncmp(variants, toDelete, toDeleteLen) == 0 && 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (variantsLen == toDeleteLen || 1439c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru (flag=(variants[toDeleteLen] == '_')))) 1440c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t d = toDeleteLen + (flag?1:0); 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variantsLen -= d; 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delta += d; 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variantsLen > 0) { 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(variants, variants+d, variantsLen); 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* p = _strnchr(variants, variantsLen, '_'); 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p == NULL) { 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return delta; 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variantsLen -= (int32_t)(p - variants); 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variants = p; 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Keyword enumeration */ 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct UKeywordsContext { 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* keywords; 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* current; 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} UKeywordsContext; 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_kw_closeKeywords(UEnumeration *enumerator) { 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(((UKeywordsContext *)enumerator->context)->keywords); 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(enumerator->context); 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(enumerator); 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 1474103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuloc_kw_countKeywords(UEnumeration *en, UErrorCode * /*status*/) { 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *kw = ((UKeywordsContext *)en->context)->keywords; 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result = 0; 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*kw) { 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result++; 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru kw += uprv_strlen(kw)+1; 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* U_CALLCONV 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_kw_nextKeyword(UEnumeration* en, 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t* resultLength, 1487103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode* /*status*/) { 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* result = ((UKeywordsContext *)en->context)->current; 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len = 0; 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*result) { 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (int32_t)uprv_strlen(((UKeywordsContext *)en->context)->current); 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UKeywordsContext *)en->context)->current += len+1; 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = NULL; 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (resultLength) { 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *resultLength = len; 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_kw_resetKeywords(UEnumeration* en, 1504103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode* /*status*/) { 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UKeywordsContext *)en->context)->current = ((UKeywordsContext *)en->context)->keywords; 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UEnumeration gKeywordsEnum = { 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_kw_closeKeywords, 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_kw_countKeywords, 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uenum_unextDefault, 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_kw_nextKeyword, 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_kw_resetKeywords 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UEnumeration* U_EXPORT2 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_openKeywordList(const char *keywordList, int32_t keywordListSize, UErrorCode* status) 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1521c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UKeywordsContext *myContext = NULL; 1522c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UEnumeration *result = NULL; 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1524c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(U_FAILURE(*status)) { 1525c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 1526c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1527c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); 1528c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* Null pointer test */ 1529c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (result == NULL) { 1530c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1531c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 1532c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1533c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(result, &gKeywordsEnum, sizeof(UEnumeration)); 153454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius myContext = static_cast<UKeywordsContext *>(uprv_malloc(sizeof(UKeywordsContext))); 1535c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (myContext == NULL) { 1536c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1537c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free(result); 1538c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 1539c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1540c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru myContext->keywords = (char *)uprv_malloc(keywordListSize+1); 1541c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(myContext->keywords, keywordList, keywordListSize); 1542c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru myContext->keywords[keywordListSize] = 0; 1543c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru myContext->current = myContext->keywords; 1544c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->context = myContext; 1545c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return result; 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UEnumeration* U_EXPORT2 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_openKeywords(const char* localeID, 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status) 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keywords[256]; 1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordsCapacity = 256; 155527f654740f2a26ad62a5c155af9199af9e69b889claireho char tempBuffer[ULOC_FULLNAME_CAPACITY]; 155627f654740f2a26ad62a5c155af9199af9e69b889claireho const char* tmpLocaleID; 155727f654740f2a26ad62a5c155af9199af9e69b889claireho 1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status==NULL || U_FAILURE(*status)) { 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 156227f654740f2a26ad62a5c155af9199af9e69b889claireho if (_hasBCP47Extension(localeID)) { 156327f654740f2a26ad62a5c155af9199af9e69b889claireho _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), status); 156427f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 156527f654740f2a26ad62a5c155af9199af9e69b889claireho if (localeID==NULL) { 156627f654740f2a26ad62a5c155af9199af9e69b889claireho localeID=uloc_getDefault(); 156727f654740f2a26ad62a5c155af9199af9e69b889claireho } 156827f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID=localeID; 1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the language */ 157227f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getLanguage(tmpLocaleID, NULL, 0, &tmpLocaleID); 157327f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *scriptID; 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the script if available */ 157627f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getScript(tmpLocaleID+1, NULL, 0, &scriptID); 157727f654740f2a26ad62a5c155af9199af9e69b889claireho if(scriptID != tmpLocaleID+1) { 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Found optional script */ 157927f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = scriptID; 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the Country */ 158227f654740f2a26ad62a5c155af9199af9e69b889claireho if (_isIDSeparator(*tmpLocaleID)) { 158327f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getCountry(tmpLocaleID+1, NULL, 0, &tmpLocaleID); 158427f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 158527f654740f2a26ad62a5c155af9199af9e69b889claireho _getVariant(tmpLocaleID+1, *tmpLocaleID, NULL, 0); 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keywords are located after '@' */ 159127f654740f2a26ad62a5c155af9199af9e69b889claireho if((tmpLocaleID = locale_getKeywordsStart(tmpLocaleID)) != NULL) { 159227f654740f2a26ad62a5c155af9199af9e69b889claireho i=locale_getKeywords(tmpLocaleID+1, '@', keywords, keywordsCapacity, NULL, 0, NULL, FALSE, status); 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i) { 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uloc_openKeywordList(keywords, i, status); 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* bit-flags for 'options' parameter of _canonicalize */ 1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _ULOC_STRIP_KEYWORDS 0x2 1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _ULOC_CANONICALIZE 0x1 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define OPTION_SET(options, mask) ((options & mask) != 0) 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char i_default[] = {'i', '-', 'd', 'e', 'f', 'a', 'u', 'l', 't'}; 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define I_DEFAULT_LENGTH (sizeof i_default / sizeof i_default[0]) 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Canonicalize the given localeID, to level 1 or to level 2, 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * depending on the options. To specify level 1, pass in options=0. 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * To specify level 2, pass in options=_ULOC_CANONICALIZE. 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is the code underlying uloc_getName and uloc_canonicalize. 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_canonicalize(const char* localeID, 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* result, 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t resultCapacity, 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t options, 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) { 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t j, len, fieldCount=0, scriptSize=0, variantSize=0, nameCapacity; 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char localeBuffer[ULOC_FULLNAME_CAPACITY]; 162727f654740f2a26ad62a5c155af9199af9e69b889claireho char tempBuffer[ULOC_FULLNAME_CAPACITY]; 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* origLocaleID; 162927f654740f2a26ad62a5c155af9199af9e69b889claireho const char* tmpLocaleID; 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* keywordAssign = NULL; 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* separatorIndicator = NULL; 1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* addKeyword = NULL; 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* addValue = NULL; 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* name; 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* variant = NULL; /* pointer into name, or NULL */ 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*err)) { 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 164127f654740f2a26ad62a5c155af9199af9e69b889claireho if (_hasBCP47Extension(localeID)) { 164227f654740f2a26ad62a5c155af9199af9e69b889claireho _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), err); 164327f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 164427f654740f2a26ad62a5c155af9199af9e69b889claireho if (localeID==NULL) { 164527f654740f2a26ad62a5c155af9199af9e69b889claireho localeID=uloc_getDefault(); 164627f654740f2a26ad62a5c155af9199af9e69b889claireho } 164727f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID=localeID; 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 164927f654740f2a26ad62a5c155af9199af9e69b889claireho 165027f654740f2a26ad62a5c155af9199af9e69b889claireho origLocaleID=tmpLocaleID; 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if we are doing a full canonicalization, then put results in 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeBuffer, if necessary; otherwise send them to result. */ 165450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (/*OPTION_SET(options, _ULOC_CANONICALIZE) &&*/ 1655103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius (result == NULL || resultCapacity < (int32_t)sizeof(localeBuffer))) { 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = localeBuffer; 1657103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius nameCapacity = (int32_t)sizeof(localeBuffer); 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = result; 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nameCapacity = resultCapacity; 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get all pieces, one after another, and separate with '_' */ 166427f654740f2a26ad62a5c155af9199af9e69b889claireho len=ulocimp_getLanguage(tmpLocaleID, name, nameCapacity, &tmpLocaleID); 1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len == I_DEFAULT_LENGTH && uprv_strncmp(origLocaleID, i_default, len) == 0) { 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *d = uloc_getDefault(); 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho len = (int32_t)uprv_strlen(d); 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (name != NULL) { 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(name, d, len); 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 167427f654740f2a26ad62a5c155af9199af9e69b889claireho } else if(_isIDSeparator(*tmpLocaleID)) { 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *scriptID; 1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fieldCount; 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len<nameCapacity) { 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len]='_'; 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1683103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius scriptSize=ulocimp_getScript(tmpLocaleID+1, 1684103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius (len<nameCapacity ? name+len : NULL), nameCapacity-len, &scriptID); 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(scriptSize > 0) { 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Found optional script */ 168727f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = scriptID; 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fieldCount; 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len+=scriptSize; 169027f654740f2a26ad62a5c155af9199af9e69b889claireho if (_isIDSeparator(*tmpLocaleID)) { 1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If there is something else, then we add the _ */ 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len<nameCapacity) { 1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len]='_'; 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 169927f654740f2a26ad62a5c155af9199af9e69b889claireho if (_isIDSeparator(*tmpLocaleID)) { 170050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *cntryID; 1701103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t cntrySize = ulocimp_getCountry(tmpLocaleID+1, 1702103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius (len<nameCapacity ? name+len : NULL), nameCapacity-len, &cntryID); 170350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (cntrySize > 0) { 170450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Found optional country */ 170527f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = cntryID; 170650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho len+=cntrySize; 170750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 170827f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 170954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius /* If there is something else, then we add the _ if we found country before. */ 171054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (cntrySize >= 0 && ! _isIDSeparator(*(tmpLocaleID+1)) ) { 171150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++fieldCount; 171250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(len<nameCapacity) { 171350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho name[len]='_'; 171450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 171550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++len; 1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 171750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1718103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius variantSize = _getVariant(tmpLocaleID+1, *tmpLocaleID, 1719103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius (len<nameCapacity ? name+len : NULL), nameCapacity-len); 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variantSize > 0) { 1721103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius variant = len<nameCapacity ? name+len : NULL; 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += variantSize; 172327f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID += variantSize + 1; /* skip '_' and variant */ 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Copy POSIX-style charset specifier, if any [mr.utf8] */ 173027f654740f2a26ad62a5c155af9199af9e69b889claireho if (!OPTION_SET(options, _ULOC_CANONICALIZE) && *tmpLocaleID == '.') { 1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool done = FALSE; 1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 173327f654740f2a26ad62a5c155af9199af9e69b889claireho char c = *tmpLocaleID; 1734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (c) { 1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: 1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case '@': 1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru done = TRUE; 1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len<nameCapacity) { 1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len] = c; 1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 174427f654740f2a26ad62a5c155af9199af9e69b889claireho ++tmpLocaleID; 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while (!done); 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Scan ahead to next '@' and determine if it is followed by '=' and/or ';' 175127f654740f2a26ad62a5c155af9199af9e69b889claireho After this, tmpLocaleID either points to '@' or is NULL */ 175227f654740f2a26ad62a5c155af9199af9e69b889claireho if ((tmpLocaleID=locale_getKeywordsStart(tmpLocaleID))!=NULL) { 175327f654740f2a26ad62a5c155af9199af9e69b889claireho keywordAssign = uprv_strchr(tmpLocaleID, '='); 175427f654740f2a26ad62a5c155af9199af9e69b889claireho separatorIndicator = uprv_strchr(tmpLocaleID, ';'); 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Copy POSIX-style variant, if any [mr@FOO] */ 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!OPTION_SET(options, _ULOC_CANONICALIZE) && 175927f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID != NULL && keywordAssign == NULL) { 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) { 176127f654740f2a26ad62a5c155af9199af9e69b889claireho char c = *tmpLocaleID; 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (c == 0) { 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len<nameCapacity) { 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len] = c; 1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 176927f654740f2a26ad62a5c155af9199af9e69b889claireho ++tmpLocaleID; 1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (OPTION_SET(options, _ULOC_CANONICALIZE)) { 1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Handle @FOO variant if @ is present and not followed by = */ 177527f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpLocaleID!=NULL && keywordAssign==NULL) { 1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t posixVariantSize; 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Add missing '_' if needed */ 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fieldCount < 2 || (fieldCount < 3 && scriptSize > 0)) { 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len<nameCapacity) { 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len]='_'; 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fieldCount; 1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(fieldCount<2); 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 178727f654740f2a26ad62a5c155af9199af9e69b889claireho posixVariantSize = _getVariantEx(tmpLocaleID+1, '@', name+len, nameCapacity-len, 1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (UBool)(variantSize > 0)); 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (posixVariantSize > 0) { 1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variant == NULL) { 1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant = name+len; 1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += posixVariantSize; 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variantSize += posixVariantSize; 1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1798c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* Handle generic variants first */ 1799c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (variant) { 1800c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru for (j=0; j<(int32_t)(sizeof(VARIANT_MAP)/sizeof(VARIANT_MAP[0])); j++) { 1801c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char* variantToCompare = VARIANT_MAP[j].variant; 1802c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t n = (int32_t)uprv_strlen(variantToCompare); 1803c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t variantLen = _deleteVariant(variant, uprv_min(variantSize, (nameCapacity-len)), variantToCompare, n); 1804c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru len -= variantLen; 1805c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (variantLen > 0) { 1806ab19ce4e2e94e2c9e847a6ae07773a48e4d40713claireho if (len > 0 && name[len-1] == '_') { /* delete trailing '_' */ 1807c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru --len; 1808c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1809c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru addKeyword = VARIANT_MAP[j].keyword; 1810c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru addValue = VARIANT_MAP[j].value; 1811c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 1812c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1813c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1814ab19ce4e2e94e2c9e847a6ae07773a48e4d40713claireho if (len > 0 && len <= nameCapacity && name[len-1] == '_') { /* delete trailing '_' */ 1815c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru --len; 1816c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Look up the ID in the canonicalization map */ 1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j=0; j<(int32_t)(sizeof(CANONICALIZE_MAP)/sizeof(CANONICALIZE_MAP[0])); j++) { 1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* id = CANONICALIZE_MAP[j].id; 1822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t n = (int32_t)uprv_strlen(id); 1823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len == n && uprv_strncmp(name, id, n) == 0) { 182427f654740f2a26ad62a5c155af9199af9e69b889claireho if (n == 0 && tmpLocaleID != NULL) { 1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* Don't remap "" if keywords present */ 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = _copyCount(name, nameCapacity, CANONICALIZE_MAP[j].canonicalID); 1828c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (CANONICALIZE_MAP[j].keyword) { 1829c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru addKeyword = CANONICALIZE_MAP[j].keyword; 1830c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru addValue = CANONICALIZE_MAP[j].value; 1831c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!OPTION_SET(options, _ULOC_STRIP_KEYWORDS)) { 183827f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpLocaleID!=NULL && keywordAssign!=NULL && 1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (!separatorIndicator || separatorIndicator > keywordAssign)) { 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len<nameCapacity) { 1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len]='@'; 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fieldCount; 1845103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius len += _getKeywords(tmpLocaleID+1, '@', (len<nameCapacity ? name+len : NULL), nameCapacity-len, 1846103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius NULL, 0, NULL, TRUE, addKeyword, addValue, err); 1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (addKeyword != NULL) { 184854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_ASSERT(addValue != NULL && len < nameCapacity); 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* inelegant but works -- later make _getKeywords do this? */ 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += _copyCount(name+len, nameCapacity-len, "@"); 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += _copyCount(name+len, nameCapacity-len, addKeyword); 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += _copyCount(name+len, nameCapacity-len, "="); 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += _copyCount(name+len, nameCapacity-len, addValue); 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*err) && result != NULL && name == localeBuffer) { 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(result, localeBuffer, (len > resultCapacity) ? resultCapacity : len); 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(result, resultCapacity, len, err); 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### ID parsing API **************************************************/ 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getParent(const char* localeID, 1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* parent, 1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t parentCapacity, 1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *lastUnderscore; 1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*err)) 1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (localeID == NULL) 1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID = uloc_getDefault(); 1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lastUnderscore=uprv_strrchr(localeID, '_'); 1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(lastUnderscore!=NULL) { 1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=(int32_t)(lastUnderscore-localeID); 1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=0; 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i>0 && parent != localeID) { 1889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(parent, localeID, uprv_min(i, parentCapacity)); 1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(parent, parentCapacity, i, err); 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getLanguage(const char* localeID, 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* language, 1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t languageCapacity, 1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* uloc_getLanguage will return a 2 character iso-639 code if one exists. *CWB*/ 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (err==NULL || U_FAILURE(*err)) { 1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(localeID==NULL) { 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID=uloc_getDefault(); 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 191150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i=ulocimp_getLanguage(localeID, language, languageCapacity, NULL); 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(language, languageCapacity, i, err); 1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getScript(const char* localeID, 1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* script, 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t scriptCapacity, 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(localeID==NULL) { 1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID=uloc_getDefault(); 1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip the language */ 193250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ulocimp_getLanguage(localeID, NULL, 0, &localeID); 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDSeparator(*localeID)) { 193450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i=ulocimp_getScript(localeID+1, script, scriptCapacity, NULL); 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(script, scriptCapacity, i, err); 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getCountry(const char* localeID, 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* country, 1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t countryCapacity, 1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(localeID==NULL) { 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID=uloc_getDefault(); 1953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the language */ 195650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ulocimp_getLanguage(localeID, NULL, 0, &localeID); 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDSeparator(*localeID)) { 1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *scriptID; 1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the script if available */ 196050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ulocimp_getScript(localeID+1, NULL, 0, &scriptID); 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(scriptID != localeID+1) { 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Found optional script */ 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID = scriptID; 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDSeparator(*localeID)) { 196650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i=ulocimp_getCountry(localeID+1, country, countryCapacity, NULL); 1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(country, countryCapacity, i, err); 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getVariant(const char* localeID, 1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* variant, 1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t variantCapacity, 1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 197827f654740f2a26ad62a5c155af9199af9e69b889claireho char tempBuffer[ULOC_FULLNAME_CAPACITY]; 197927f654740f2a26ad62a5c155af9199af9e69b889claireho const char* tmpLocaleID; 1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198627f654740f2a26ad62a5c155af9199af9e69b889claireho if (_hasBCP47Extension(localeID)) { 198727f654740f2a26ad62a5c155af9199af9e69b889claireho _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), err); 198827f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 198927f654740f2a26ad62a5c155af9199af9e69b889claireho if (localeID==NULL) { 199027f654740f2a26ad62a5c155af9199af9e69b889claireho localeID=uloc_getDefault(); 199127f654740f2a26ad62a5c155af9199af9e69b889claireho } 199227f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID=localeID; 1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the language */ 199627f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getLanguage(tmpLocaleID, NULL, 0, &tmpLocaleID); 199727f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *scriptID; 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the script if available */ 200027f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getScript(tmpLocaleID+1, NULL, 0, &scriptID); 200127f654740f2a26ad62a5c155af9199af9e69b889claireho if(scriptID != tmpLocaleID+1) { 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Found optional script */ 200327f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = scriptID; 2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the Country */ 200627f654740f2a26ad62a5c155af9199af9e69b889claireho if (_isIDSeparator(*tmpLocaleID)) { 200750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *cntryID; 200827f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getCountry(tmpLocaleID+1, NULL, 0, &cntryID); 200927f654740f2a26ad62a5c155af9199af9e69b889claireho if (cntryID != tmpLocaleID+1) { 201050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Found optional country */ 201127f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = cntryID; 201250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 201327f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 201427f654740f2a26ad62a5c155af9199af9e69b889claireho /* If there was no country ID, skip a possible extra IDSeparator */ 201527f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpLocaleID != cntryID && _isIDSeparator(tmpLocaleID[1])) { 201627f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID++; 201727f654740f2a26ad62a5c155af9199af9e69b889claireho } 201827f654740f2a26ad62a5c155af9199af9e69b889claireho i=_getVariant(tmpLocaleID+1, *tmpLocaleID, variant, variantCapacity); 2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* removed by weiv. We don't want to handle POSIX variants anymore. Use canonicalization function */ 2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if we do not have a variant tag yet then try a POSIX variant after '@' */ 2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!haveVariant && (localeID=uprv_strrchr(localeID, '@'))!=NULL) { 2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=_getVariant(localeID+1, '@', variant, variantCapacity); 2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(variant, variantCapacity, i, err); 2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getName(const char* localeID, 2035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* name, 2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nameCapacity, 2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _canonicalize(localeID, name, nameCapacity, 0, err); 2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getBaseName(const char* localeID, 2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* name, 2045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nameCapacity, 2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 2047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _canonicalize(localeID, name, nameCapacity, _ULOC_STRIP_KEYWORDS, err); 2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_canonicalize(const char* localeID, 2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* name, 2054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nameCapacity, 2055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 2056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _canonicalize(localeID, name, nameCapacity, _ULOC_CANONICALIZE, err); 2058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 2061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getISO3Language(const char* localeID) 2062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int16_t offset; 2064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char lang[ULOC_LANG_CAPACITY]; 2065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 2066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (localeID == NULL) 2068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID = uloc_getDefault(); 2070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getLanguage(localeID, lang, ULOC_LANG_CAPACITY, &err); 2072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(err)) 2073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ""; 2074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = _findIndex(LANGUAGES, lang); 2075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset < 0) 2076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ""; 2077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return LANGUAGES_3[offset]; 2078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 2081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getISO3Country(const char* localeID) 2082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int16_t offset; 2084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cntry[ULOC_LANG_CAPACITY]; 2085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 2086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (localeID == NULL) 2088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID = uloc_getDefault(); 2090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getCountry(localeID, cntry, ULOC_LANG_CAPACITY, &err); 2092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(err)) 2093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ""; 2094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = _findIndex(COUNTRIES, cntry); 2095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset < 0) 2096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ""; 2097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return COUNTRIES_3[offset]; 2099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI uint32_t U_EXPORT2 2102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getLCID(const char* localeID) 2103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 2105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char langID[ULOC_FULLNAME_CAPACITY]; 2106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getLanguage(localeID, langID, sizeof(langID), &status); 2108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 2109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 211259d709d503bab6e2b61931737e662dd293b40578ccornelius if (uprv_strchr(localeID, '@')) { 211359d709d503bab6e2b61931737e662dd293b40578ccornelius // uprv_convertToLCID does not support keywords other than collation. 211459d709d503bab6e2b61931737e662dd293b40578ccornelius // Remove all keywords except collation. 211559d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t len; 211659d709d503bab6e2b61931737e662dd293b40578ccornelius char collVal[ULOC_KEYWORDS_CAPACITY]; 211759d709d503bab6e2b61931737e662dd293b40578ccornelius char tmpLocaleID[ULOC_FULLNAME_CAPACITY]; 211859d709d503bab6e2b61931737e662dd293b40578ccornelius 211959d709d503bab6e2b61931737e662dd293b40578ccornelius len = uloc_getKeywordValue(localeID, "collation", collVal, 212059d709d503bab6e2b61931737e662dd293b40578ccornelius sizeof(collVal)/sizeof(collVal[0]) - 1, &status); 212159d709d503bab6e2b61931737e662dd293b40578ccornelius 212259d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_SUCCESS(status) && len > 0) { 212359d709d503bab6e2b61931737e662dd293b40578ccornelius collVal[len] = 0; 212459d709d503bab6e2b61931737e662dd293b40578ccornelius 212559d709d503bab6e2b61931737e662dd293b40578ccornelius len = uloc_getBaseName(localeID, tmpLocaleID, 212659d709d503bab6e2b61931737e662dd293b40578ccornelius sizeof(tmpLocaleID)/sizeof(tmpLocaleID[0]) - 1, &status); 212759d709d503bab6e2b61931737e662dd293b40578ccornelius 212859d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_SUCCESS(status)) { 212959d709d503bab6e2b61931737e662dd293b40578ccornelius tmpLocaleID[len] = 0; 213059d709d503bab6e2b61931737e662dd293b40578ccornelius 213159d709d503bab6e2b61931737e662dd293b40578ccornelius len = uloc_setKeywordValue("collation", collVal, tmpLocaleID, 213259d709d503bab6e2b61931737e662dd293b40578ccornelius sizeof(tmpLocaleID)/sizeof(tmpLocaleID[0]) - len - 1, &status); 213359d709d503bab6e2b61931737e662dd293b40578ccornelius 213459d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_SUCCESS(status)) { 213559d709d503bab6e2b61931737e662dd293b40578ccornelius tmpLocaleID[len] = 0; 213659d709d503bab6e2b61931737e662dd293b40578ccornelius return uprv_convertToLCID(langID, tmpLocaleID, &status); 213759d709d503bab6e2b61931737e662dd293b40578ccornelius } 213859d709d503bab6e2b61931737e662dd293b40578ccornelius } 213959d709d503bab6e2b61931737e662dd293b40578ccornelius } 214059d709d503bab6e2b61931737e662dd293b40578ccornelius 214159d709d503bab6e2b61931737e662dd293b40578ccornelius // fall through - all keywords are simply ignored 214259d709d503bab6e2b61931737e662dd293b40578ccornelius status = U_ZERO_ERROR; 214359d709d503bab6e2b61931737e662dd293b40578ccornelius } 214459d709d503bab6e2b61931737e662dd293b40578ccornelius 2145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_convertToLCID(langID, localeID, &status); 2146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getLocaleForLCID(uint32_t hostid, char *locale, int32_t localeCapacity, 2150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 2151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 215259d709d503bab6e2b61931737e662dd293b40578ccornelius return uprv_convertToPosix(hostid, locale, localeCapacity, status); 2153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### Default locale **************************************************/ 2156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 2158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getDefault() 2159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return locale_get_default(); 2161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 2164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_setDefault(const char* newDefaultLocale, 2165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 2166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*err)) 2168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the error code isn't currently used for anything by this function*/ 2170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* propagate change to C++ */ 2172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru locale_set_default(newDefaultLocale); 2173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 21768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * Returns a list of all 2-letter language codes defined in ISO 639. This is a pointer 2177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to an array of pointers to arrays of char. All of these pointers are owned 2178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * by ICU-- do not delete them, and do not write through them. The array is 2179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * terminated with a null pointer. 2180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* const* U_EXPORT2 2182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getISOLanguages() 2183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return LANGUAGES; 2185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns a list of all 2-letter country codes defined in ISO 639. This is a 2189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * pointer to an array of pointers to arrays of char. All of these pointers are 2190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * owned by ICU-- do not delete them, and do not write through them. The array is 2191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * terminated with a null pointer. 2192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* const* U_EXPORT2 2194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getISOCountries() 2195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return COUNTRIES; 2197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* this function to be moved into cstring.c later */ 2201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char gDecimal = 0; 2202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic /* U_CAPI */ 2204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querudouble 2205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* U_EXPORT2 */ 2206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_uloc_strtod(const char *start, char **end) { 2207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *decimal; 2208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *myEnd; 2209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buf[30]; 2210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double rv; 2211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!gDecimal) { 2212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char rep[5]; 2213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* For machines that decide to change the decimal on you, 2214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru and try to be too smart with localization. 2215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru This normally should be just a '.'. */ 2216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sprintf(rep, "%+1.1f", 1.0); 2217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gDecimal = rep[2]; 2218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(gDecimal == '.') { 2221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_strtod(start, end); /* fall through to OS */ 2222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(buf, start, 29); 2224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf[29]=0; 2225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru decimal = uprv_strchr(buf, '.'); 2226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(decimal) { 2227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *decimal = gDecimal; 2228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_strtod(start, end); /* no decimal point */ 2230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rv = uprv_strtod(buf, &myEnd); 2232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(end) { 2233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *end = (char*)(start+(myEnd-buf)); /* cast away const (to follow uprv_strtod API.) */ 2234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return rv; 2236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct { 2240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float q; 2241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dummy; /* to avoid uninitialized memory copy from qsort */ 2242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *locale; 2243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} _acceptLangItem; 2244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 2246103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuloc_acceptLanguageCompare(const void * /*context*/, const void *a, const void *b) 2247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const _acceptLangItem *aa = (const _acceptLangItem*)a; 2249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const _acceptLangItem *bb = (const _acceptLangItem*)b; 2250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rc = 0; 2252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bb->q < aa->q) { 2253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = -1; /* A > B */ 2254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(bb->q > aa->q) { 2255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = 1; /* A < B */ 2256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = 0; /* A = B */ 2258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(rc==0) { 2261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = uprv_stricmp(aa->locale, bb->locale); 2262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* fprintf(stderr, "a:[%s:%g], b:[%s:%g] -> %d\n", 2266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru aa->locale, aa->q, 2267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bb->locale, bb->q, 2268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc);*/ 2269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return rc; 2272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querumt-mt, ja;q=0.76, en-us;q=0.95, en;q=0.92, en-gb;q=0.89, fr;q=0.87, iu-ca;q=0.84, iu;q=0.82, ja-jp;q=0.79, mt;q=0.97, de-de;q=0.74, de;q=0.71, es;q=0.68, it-it;q=0.66, it;q=0.63, vi-vn;q=0.61, vi;q=0.58, nl-nl;q=0.55, nl;q=0.53 2276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult *outResult, 2280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *httpAcceptLanguage, 2281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumeration* availableLocales, 2282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 2283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru _acceptLangItem *j; 2285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru _acceptLangItem smallBuffer[30]; 2286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char **strs; 2287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char tmp[ULOC_FULLNAME_CAPACITY +1]; 2288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t n = 0; 2289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *itemEnd; 2290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *paramEnd; 2291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s; 2292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *t; 2293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t res; 2294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 2295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t l = (int32_t)uprv_strlen(httpAcceptLanguage); 2296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t jSize; 2297c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru char *tempstr; /* Use for null pointer check */ 2298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j = smallBuffer; 2300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jSize = sizeof(smallBuffer)/sizeof(smallBuffer[0]); 2301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 2302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(s=httpAcceptLanguage;s&&*s;) { 2306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(isspace(*s)) /* eat space at the beginning */ 2307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s++; 2308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemEnd=uprv_strchr(s,','); 2309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru paramEnd=uprv_strchr(s,';'); 2310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!itemEnd) { 2311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemEnd = httpAcceptLanguage+l; /* end of string */ 2312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(paramEnd && paramEnd<itemEnd) { 2314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* semicolon (;) is closer than end (,) */ 2315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t = paramEnd+1; 2316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*t=='q') { 2317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t++; 2318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(isspace(*t)) { 2320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t++; 2321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*t=='=') { 2323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t++; 2324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(isspace(*t)) { 2326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t++; 2327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j[n].q = (float)_uloc_strtod(t,NULL); 2329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no semicolon - it's 1.0 */ 2331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j[n].q = 1.0f; 2332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru paramEnd = itemEnd; 2333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j[n].dummy=0; 2335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* eat spaces prior to semi */ 2336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(t=(paramEnd-1);(paramEnd>s)&&isspace(*t);t--) 2337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ; 2338c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* Check for null pointer from uprv_strndup */ 2339c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru tempstr = uprv_strndup(s,(int32_t)((t+1)-s)); 2340c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (tempstr == NULL) { 2341c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 2342c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return -1; 2343c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 2344c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru j[n].locale = tempstr; 2345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_canonicalize(j[n].locale,tmp,sizeof(tmp)/sizeof(tmp[0]),status); 2346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(strcmp(j[n].locale,tmp)) { 2347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(j[n].locale); 2348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru j[n].locale=uprv_strdup(tmp); 2349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*fprintf(stderr,"%d: s <%s> q <%g>\n", n, j[n].locale, j[n].q);*/ 2352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru n++; 2354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s = itemEnd; 2355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*s==',') { /* eat duplicate commas */ 2356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s++; 2357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(n>=jSize) { 2359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(j==smallBuffer) { /* overflowed the small buffer. */ 236054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius j = static_cast<_acceptLangItem *>(uprv_malloc(sizeof(j[0])*(jSize*2))); 2361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(j!=NULL) { 2362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(j,smallBuffer,sizeof(j[0])*jSize); 2363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr,"malloced at size %d\n", jSize); 2366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 236854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius j = static_cast<_acceptLangItem *>(uprv_realloc(j, sizeof(j[0])*jSize*2)); 2369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr,"re-alloced at size %d\n", jSize); 2371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jSize *= 2; 2374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(j==NULL) { 2375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 2376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_sortArray(j, n, sizeof(j[0]), uloc_acceptLanguageCompare, NULL, TRUE, status); 2381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 2382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(j != smallBuffer) { 2383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr,"freeing j %p\n", j); 2385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(j); 2387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 239054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius strs = static_cast<char **>(uprv_malloc((size_t)(sizeof(strs[0])*n))); 2391c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* Check for null pointer */ 2392c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (strs == NULL) { 2393c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free(j); /* Free to avoid memory leak */ 2394c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 2395c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return -1; 2396c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 2397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<n;i++) { 2398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*fprintf(stderr,"%d: s <%s> q <%g>\n", i, j[i].locale, j[i].q);*/ 2400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strs[i]=j[i].locale; 2402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = uloc_acceptLanguage(result, resultAvailable, outResult, 2404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (const char**)strs, n, availableLocales, status); 2405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<n;i++) { 2406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(strs[i]); 2407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(strs); 2409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(j != smallBuffer) { 2410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr,"freeing j %p\n", j); 2412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(j); 2414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 2416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_acceptLanguage(char *result, int32_t resultAvailable, 2421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UAcceptResult *outResult, const char **acceptList, 2422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t acceptListCount, 2423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumeration* availableLocales, 2424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 2425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i,j; 2427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len; 2428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t maxLen=0; 2429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char tmp[ULOC_FULLNAME_CAPACITY+1]; 2430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *l; 2431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char **fallbackList; 2432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 2433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 243554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius fallbackList = static_cast<char **>(uprv_malloc((size_t)(sizeof(fallbackList[0])*acceptListCount))); 2436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fallbackList==NULL) { 2437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 2438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<acceptListCount;i++) { 2441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr,"%02d: %s\n", i, acceptList[i]); 2443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((l=uenum_next(availableLocales, NULL, status))) { 2445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr," %s\n", l); 2447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (int32_t)uprv_strlen(l); 2449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!uprv_strcmp(acceptList[i], l)) { 2450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(outResult) { 2451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *outResult = ULOC_ACCEPT_VALID; 2452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "MATCH! %s\n", l); 2455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len>0) { 2457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(result, l, uprv_min(len, resultAvailable)); 2458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=0;j<i;j++) { 2460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[j]); 2461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList); 2463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(result, resultAvailable, len, status); 2464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len>maxLen) { 2466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxLen = len; 2467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uenum_reset(availableLocales, status); 2470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* save off parent info */ 2471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uloc_getParent(acceptList[i], tmp, sizeof(tmp)/sizeof(tmp[0]), status)!=0) { 2472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fallbackList[i] = uprv_strdup(tmp); 2473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fallbackList[i]=0; 2475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(maxLen--;maxLen>0;maxLen--) { 2479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<acceptListCount;i++) { 2480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fallbackList[i] && ((int32_t)uprv_strlen(fallbackList[i])==maxLen)) { 2481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr,"Try: [%s]", fallbackList[i]); 2483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((l=uenum_next(availableLocales, NULL, status))) { 2485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr," %s\n", l); 2487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (int32_t)uprv_strlen(l); 2489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!uprv_strcmp(fallbackList[i], l)) { 2490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(outResult) { 2491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *outResult = ULOC_ACCEPT_FALLBACK; 2492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "fallback MATCH! %s\n", l); 2495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len>0) { 2497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(result, l, uprv_min(len, resultAvailable)); 2498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=0;j<acceptListCount;j++) { 2500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[j]); 2501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList); 2503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(result, resultAvailable, len, status); 2504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uenum_reset(availableLocales, status); 2507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uloc_getParent(fallbackList[i], tmp, sizeof(tmp)/sizeof(tmp[0]), status)!=0) { 2509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[i]); 2510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fallbackList[i] = uprv_strdup(tmp); 2511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[i]); 2513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fallbackList[i]=0; 2514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(outResult) { 2518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *outResult = ULOC_ACCEPT_FAILED; 2519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<acceptListCount;i++) { 2522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[i]); 2523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList); 2525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*eof*/ 2529