10596faeddefbf198de137d5e893708495ab1584cFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 58de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert* Copyright (C) 1997-2016, International Business Machines 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File ULOC.CPP 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 04/01/97 aliu Creation. 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 08/21/98 stephen JDK 1.2 sync 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 12/08/98 rtg New Locale implementation and C API 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 03/15/99 damiba overhaul. 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 04/06/99 stephen changed setDefault() to realloc and copy 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 06/14/99 stephen Changed calls to ures_open for new params 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 07/21/99 stephen Modified setDefault() to propagate to C++ 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 05/14/04 alan 7 years later: refactored, cleaned up, fixed bugs, 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* brought canonicalization code into line with spec 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*****************************************************************************/ 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POSIX's locale format, from putil.c: [no spaces] 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ll [ _CC ] [ . MM ] [ @ VV] 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru l = lang, C = ctry, M = charmap, V = variant 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uloc.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h" 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ulocimp.h" 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "locmap.h" 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uarrsort.h" 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uenumimp.h" 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h" 470596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#include "charstr.h" 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> /* for sprintf */ 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 510596faeddefbf198de137d5e893708495ab1584cFredrik RoubertU_NAMESPACE_USE 5264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### Declarations **************************************************/ 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Locale stuff from locid.cpp */ 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void locale_set_default(const char *id); 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC const char *locale_get_default(void); 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC int32_t 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulocale_getKeywords(const char *localeID, 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *keywords, int32_t keywordCapacity, 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *values, int32_t valuesCapacity, int32_t *valLen, 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool valuesToo, 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status); 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### Data tables **************************************************/ 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Table of language codes, both 2- and 3-letter, with preference 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * given to 2-letter codes where possible. Includes 3-letter codes 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that lack a 2-letter equivalent. 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This list must be in sorted order. This list is returned directly 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to the user by some API. 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This list must be kept in sync with LANGUAGES_3, with corresponding 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * entries matched. 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This table should be terminated with a NULL entry, followed by a 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * second list, and another NULL entry. The first list is visible to 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * user code when this array is returned by API. The second list 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * contains codes we support, but do not expose through user API. 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Notes 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Tables updated per http://lcweb.loc.gov/standards/iso639-2/ to 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * include the revisions up to 2001/7/27 *CWB* 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The 3 character codes are the terminology codes like RFC 3066. This 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is compatible with prior ICU codes 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * "in" "iw" "ji" "jw" & "sh" have been withdrawn but are still in the 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * table but now at the end of the table because 3 character codes are 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * duplicates. This avoids bad searches going from 3 to 2 character 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * codes. 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The range qaa-qtz is reserved for local use 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* Generated using org.unicode.cldr.icu.GenerateISO639LanguageTables */ 100c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert/* ISO639 table version is 20150505 */ 101ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert/* Subsequent hand addition of selected languages */ 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const LANGUAGES[] = { 10364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "aa", "ab", "ace", "ach", "ada", "ady", "ae", "aeb", 10464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "af", "afh", "agq", "ain", "ak", "akk", "akz", "ale", 10564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "aln", "alt", "am", "an", "ang", "anp", "ar", "arc", 1060596faeddefbf198de137d5e893708495ab1584cFredrik Roubert "arn", "aro", "arp", "arq", "ars", "arw", "ary", "arz", "as", 10764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "asa", "ase", "ast", "av", "avk", "awa", "ay", "az", 10864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ba", "bal", "ban", "bar", "bas", "bax", "bbc", "bbj", 10964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "be", "bej", "bem", "bew", "bez", "bfd", "bfq", "bg", 11064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "bgn", "bho", "bi", "bik", "bin", "bjn", "bkm", "bla", 11164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "bm", "bn", "bo", "bpy", "bqi", "br", "bra", "brh", 11264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "brx", "bs", "bss", "bua", "bug", "bum", "byn", "byv", 113ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert "ca", "cad", "car", "cay", "cch", "ccp", "ce", "ceb", "cgg", 11464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ch", "chb", "chg", "chk", "chm", "chn", "cho", "chp", 11564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "chr", "chy", "ckb", "co", "cop", "cps", "cr", "crh", 11664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "cs", "csb", "cu", "cv", "cy", 11764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "da", "dak", "dar", "dav", "de", "del", "den", "dgr", 11864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "din", "dje", "doi", "dsb", "dtp", "dua", "dum", "dv", 11964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "dyo", "dyu", "dz", "dzg", 12064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ebu", "ee", "efi", "egl", "egy", "eka", "el", "elx", 12164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "en", "enm", "eo", "es", "esu", "et", "eu", "ewo", 12264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ext", 12364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "fa", "fan", "fat", "ff", "fi", "fil", "fit", "fj", 12464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "fo", "fon", "fr", "frc", "frm", "fro", "frp", "frr", 12564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "frs", "fur", "fy", 12664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ga", "gaa", "gag", "gan", "gay", "gba", "gbz", "gd", 12764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "gez", "gil", "gl", "glk", "gmh", "gn", "goh", "gom", 12864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "gon", "gor", "got", "grb", "grc", "gsw", "gu", "guc", 12964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "gur", "guz", "gv", "gwi", 13064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ha", "hai", "hak", "haw", "he", "hi", "hif", "hil", 13164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "hit", "hmn", "ho", "hr", "hsb", "hsn", "ht", "hu", 13264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "hup", "hy", "hz", 13364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ia", "iba", "ibb", "id", "ie", "ig", "ii", "ik", 13464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ilo", "inh", "io", "is", "it", "iu", "izh", 13564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ja", "jam", "jbo", "jgo", "jmc", "jpr", "jrb", "jut", 13664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "jv", 13764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ka", "kaa", "kab", "kac", "kaj", "kam", "kaw", "kbd", 13864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kbl", "kcg", "kde", "kea", "ken", "kfo", "kg", "kgp", 13964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kha", "kho", "khq", "khw", "ki", "kiu", "kj", "kk", 14064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kkj", "kl", "kln", "km", "kmb", "kn", "ko", "koi", 14164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kok", "kos", "kpe", "kr", "krc", "kri", "krj", "krl", 14264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kru", "ks", "ksb", "ksf", "ksh", "ku", "kum", "kut", 14364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kv", "kw", "ky", 14464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "la", "lad", "lag", "lah", "lam", "lb", "lez", "lfn", 14564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "lg", "li", "lij", "liv", "lkt", "lmo", "ln", "lo", 14664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "lol", "loz", "lrc", "lt", "ltg", "lu", "lua", "lui", 14764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "lun", "luo", "lus", "luy", "lv", "lzh", "lzz", 14864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "mad", "maf", "mag", "mai", "mak", "man", "mas", "mde", 14964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "mdf", "mdh", "mdr", "men", "mer", "mfe", "mg", "mga", 15064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "mgh", "mgo", "mh", "mi", "mic", "min", "mis", "mk", 15164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ml", "mn", "mnc", "mni", "moh", "mos", "mr", "mrj", 15264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ms", "mt", "mua", "mul", "mus", "mwl", "mwr", "mwv", 15364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "my", "mye", "myv", "mzn", 15464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "na", "nan", "nap", "naq", "nb", "nd", "nds", "ne", 15564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "new", "ng", "nia", "niu", "njo", "nl", "nmg", "nn", 15664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "nnh", "no", "nog", "non", "nov", "nqo", "nr", "nso", 15764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "nus", "nv", "nwc", "ny", "nym", "nyn", "nyo", "nzi", 15864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "oc", "oj", "om", "or", "os", "osa", "ota", 15964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "pa", "pag", "pal", "pam", "pap", "pau", "pcd", "pdc", 16064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "pdt", "peo", "pfl", "phn", "pi", "pl", "pms", "pnt", 16164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "pon", "prg", "pro", "ps", "pt", 16264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "qu", "quc", "qug", 16364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "raj", "rap", "rar", "rgn", "rif", "rm", "rn", "ro", 16464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "rof", "rom", "rtm", "ru", "rue", "rug", "rup", 16564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "rw", "rwk", 16664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sa", "sad", "sah", "sam", "saq", "sas", "sat", "saz", 16764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sba", "sbp", "sc", "scn", "sco", "sd", "sdc", "sdh", 16864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "se", "see", "seh", "sei", "sel", "ses", "sg", "sga", 16964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sgs", "shi", "shn", "shu", "si", "sid", "sk", 17064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sl", "sli", "sly", "sm", "sma", "smj", "smn", "sms", 17164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sn", "snk", "so", "sog", "sq", "sr", "srn", "srr", 17264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ss", "ssy", "st", "stq", "su", "suk", "sus", "sux", 17364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sv", "sw", "swb", "swc", "syc", "syr", "szl", 17464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ta", "tcy", "te", "tem", "teo", "ter", "tet", "tg", 17564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "th", "ti", "tig", "tiv", "tk", "tkl", "tkr", "tl", 17664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "tlh", "tli", "tly", "tmh", "tn", "to", "tog", "tpi", 17764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "tr", "tru", "trv", "ts", "tsd", "tsi", "tt", "ttt", 17864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "tum", "tvl", "tw", "twq", "ty", "tyv", "tzm", 17964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "udm", "ug", "uga", "uk", "umb", "und", "ur", "uz", 18064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "vai", "ve", "vec", "vep", "vi", "vls", "vmf", "vo", 18164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "vot", "vro", "vun", 18264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "wa", "wae", "wal", "war", "was", "wbp", "wo", "wuu", 18364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "xal", "xh", "xmf", "xog", 18464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "yao", "yap", "yav", "ybb", "yi", "yo", "yrl", "yue", 18564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "za", "zap", "zbl", "zea", "zen", "zgh", "zh", "zu", 18664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "zun", "zxx", "zza", 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL, 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "in", "iw", "ji", "jw", "sh", /* obsolete language codes */ 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* const DEPRECATED_LANGUAGES[]={ 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "in", "iw", "ji", "jw", NULL, NULL 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* const REPLACEMENT_LANGUAGES[]={ 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "id", "he", "yi", "jv", NULL, NULL 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Table of 3-letter language codes. 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is a lookup table used to convert 3-letter language codes to 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * their 2-letter equivalent, where possible. It must be kept in sync 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * with LANGUAGES. For all valid i, LANGUAGES[i] must refer to the 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * same language as LANGUAGES_3[i]. The commented-out lines are 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * copied from LANGUAGES to make eyeballing this baby easier. 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Where a 3-letter language code has no 2-letter equivalent, the 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 3-letter code occupies both LANGUAGES[i] and LANGUAGES_3[i]. 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This table should be terminated with a NULL entry, followed by a 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * second list, and another NULL entry. The two lists correspond to 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the two lists in LANGUAGES. 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* Generated using org.unicode.cldr.icu.GenerateISO639LanguageTables */ 216c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert/* ISO639 table version is 20150505 */ 217ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert/* Subsequent hand addition of selected languages */ 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const LANGUAGES_3[] = { 21964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "aar", "abk", "ace", "ach", "ada", "ady", "ave", "aeb", 22064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "afr", "afh", "agq", "ain", "aka", "akk", "akz", "ale", 22164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "aln", "alt", "amh", "arg", "ang", "anp", "ara", "arc", 2220596faeddefbf198de137d5e893708495ab1584cFredrik Roubert "arn", "aro", "arp", "arq", "ars", "arw", "ary", "arz", "asm", 22364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "asa", "ase", "ast", "ava", "avk", "awa", "aym", "aze", 22464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "bak", "bal", "ban", "bar", "bas", "bax", "bbc", "bbj", 22564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "bel", "bej", "bem", "bew", "bez", "bfd", "bfq", "bul", 22664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "bgn", "bho", "bis", "bik", "bin", "bjn", "bkm", "bla", 22764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "bam", "ben", "bod", "bpy", "bqi", "bre", "bra", "brh", 22864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "brx", "bos", "bss", "bua", "bug", "bum", "byn", "byv", 229ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert "cat", "cad", "car", "cay", "cch", "ccp", "che", "ceb", "cgg", 23064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "cha", "chb", "chg", "chk", "chm", "chn", "cho", "chp", 23164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "chr", "chy", "ckb", "cos", "cop", "cps", "cre", "crh", 23264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ces", "csb", "chu", "chv", "cym", 23364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "dan", "dak", "dar", "dav", "deu", "del", "den", "dgr", 23464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "din", "dje", "doi", "dsb", "dtp", "dua", "dum", "div", 23564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "dyo", "dyu", "dzo", "dzg", 23664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ebu", "ewe", "efi", "egl", "egy", "eka", "ell", "elx", 23764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "eng", "enm", "epo", "spa", "esu", "est", "eus", "ewo", 23864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ext", 23964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "fas", "fan", "fat", "ful", "fin", "fil", "fit", "fij", 24064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "fao", "fon", "fra", "frc", "frm", "fro", "frp", "frr", 24164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "frs", "fur", "fry", 24264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "gle", "gaa", "gag", "gan", "gay", "gba", "gbz", "gla", 24364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "gez", "gil", "glg", "glk", "gmh", "grn", "goh", "gom", 24464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "gon", "gor", "got", "grb", "grc", "gsw", "guj", "guc", 24564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "gur", "guz", "glv", "gwi", 24664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "hau", "hai", "hak", "haw", "heb", "hin", "hif", "hil", 24764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "hit", "hmn", "hmo", "hrv", "hsb", "hsn", "hat", "hun", 24864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "hup", "hye", "her", 24964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ina", "iba", "ibb", "ind", "ile", "ibo", "iii", "ipk", 25064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ilo", "inh", "ido", "isl", "ita", "iku", "izh", 25164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "jpn", "jam", "jbo", "jgo", "jmc", "jpr", "jrb", "jut", 25264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "jav", 25364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kat", "kaa", "kab", "kac", "kaj", "kam", "kaw", "kbd", 25464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kbl", "kcg", "kde", "kea", "ken", "kfo", "kon", "kgp", 25564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kha", "kho", "khq", "khw", "kik", "kiu", "kua", "kaz", 25664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kkj", "kal", "kln", "khm", "kmb", "kan", "kor", "koi", 25764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kok", "kos", "kpe", "kau", "krc", "kri", "krj", "krl", 25864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kru", "kas", "ksb", "ksf", "ksh", "kur", "kum", "kut", 25964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kom", "cor", "kir", 26064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "lat", "lad", "lag", "lah", "lam", "ltz", "lez", "lfn", 26164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "lug", "lim", "lij", "liv", "lkt", "lmo", "lin", "lao", 26264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "lol", "loz", "lrc", "lit", "ltg", "lub", "lua", "lui", 26364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "lun", "luo", "lus", "luy", "lav", "lzh", "lzz", 26464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "mad", "maf", "mag", "mai", "mak", "man", "mas", "mde", 26564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "mdf", "mdh", "mdr", "men", "mer", "mfe", "mlg", "mga", 26664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "mgh", "mgo", "mah", "mri", "mic", "min", "mis", "mkd", 26764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "mal", "mon", "mnc", "mni", "moh", "mos", "mar", "mrj", 26864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "msa", "mlt", "mua", "mul", "mus", "mwl", "mwr", "mwv", 26964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "mya", "mye", "myv", "mzn", 27064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "nau", "nan", "nap", "naq", "nob", "nde", "nds", "nep", 27164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "new", "ndo", "nia", "niu", "njo", "nld", "nmg", "nno", 27264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "nnh", "nor", "nog", "non", "nov", "nqo", "nbl", "nso", 27364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "nus", "nav", "nwc", "nya", "nym", "nyn", "nyo", "nzi", 27464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "oci", "oji", "orm", "ori", "oss", "osa", "ota", 27564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "pan", "pag", "pal", "pam", "pap", "pau", "pcd", "pdc", 27664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "pdt", "peo", "pfl", "phn", "pli", "pol", "pms", "pnt", 27764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "pon", "prg", "pro", "pus", "por", 27864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "que", "quc", "qug", 27964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "raj", "rap", "rar", "rgn", "rif", "roh", "run", "ron", 28064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "rof", "rom", "rtm", "rus", "rue", "rug", "rup", 28164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "kin", "rwk", 28264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "san", "sad", "sah", "sam", "saq", "sas", "sat", "saz", 28364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sba", "sbp", "srd", "scn", "sco", "snd", "sdc", "sdh", 28464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sme", "see", "seh", "sei", "sel", "ses", "sag", "sga", 28564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sgs", "shi", "shn", "shu", "sin", "sid", "slk", 28664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "slv", "sli", "sly", "smo", "sma", "smj", "smn", "sms", 28764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "sna", "snk", "som", "sog", "sqi", "srp", "srn", "srr", 28864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "ssw", "ssy", "sot", "stq", "sun", "suk", "sus", "sux", 28964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "swe", "swa", "swb", "swc", "syc", "syr", "szl", 29064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "tam", "tcy", "tel", "tem", "teo", "ter", "tet", "tgk", 29164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "tha", "tir", "tig", "tiv", "tuk", "tkl", "tkr", "tgl", 29264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "tlh", "tli", "tly", "tmh", "tsn", "ton", "tog", "tpi", 29364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "tur", "tru", "trv", "tso", "tsd", "tsi", "tat", "ttt", 29464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "tum", "tvl", "twi", "twq", "tah", "tyv", "tzm", 29564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "udm", "uig", "uga", "ukr", "umb", "und", "urd", "uzb", 29664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "vai", "ven", "vec", "vep", "vie", "vls", "vmf", "vol", 29764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "vot", "vro", "vun", 29864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "wln", "wae", "wal", "war", "was", "wbp", "wol", "wuu", 29964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "xal", "xho", "xmf", "xog", 30064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "yao", "yap", "yav", "ybb", "yid", "yor", "yrl", "yue", 30164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "zha", "zap", "zbl", "zea", "zen", "zgh", "zho", "zul", 30264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "zun", "zxx", "zza", 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL, 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "in", "iw", "ji", "jw", "sh", */ 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ind", "heb", "yid", "jaw", "srp", 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Table of 2-letter country codes. 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This list must be in sorted order. This list is returned directly 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to the user by some API. 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This list must be kept in sync with COUNTRIES_3, with corresponding 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * entries matched. 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This table should be terminated with a NULL entry, followed by a 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * second list, and another NULL entry. The first list is visible to 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * user code when this array is returned by API. The second list 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * contains codes we support, but do not expose through user API. 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Notes: 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * ZR(ZAR) is now CD(COD) and FX(FXX) is PS(PSE) as per 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * http://www.evertype.com/standards/iso3166/iso3166-1-en.html added 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * new codes keeping the old ones for compatibility updated to include 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1999/12/03 revisions *CWB* 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * RO(ROM) is now RO(ROU) according to 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * http://www.iso.org/iso/en/prods-services/iso3166ma/03updates-on-iso-3166/nlv3e-rou.html 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const COUNTRIES[] = { 3348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "AD", "AE", "AF", "AG", "AI", "AL", "AM", 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", 3378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", 3408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", 3588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", 3598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "WS", "YE", "YT", "ZA", "ZM", "ZW", 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL, 3658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "AN", "BU", "CS", "FX", "RO", "SU", "TP", "YD", "YU", "ZR", /* obsolete country codes */ 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const char* const DEPRECATED_COUNTRIES[] = { 3708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "AN", "BU", "CS", "DD", "DY", "FX", "HV", "NH", "RH", "SU", "TP", "UK", "VD", "YD", "YU", "ZR", NULL, NULL /* deprecated country list */ 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* const REPLACEMENT_COUNTRIES[] = { 3738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "AN", "BU", "CS", "DD", "DY", "FX", "HV", "NH", "RH", "SU", "TP", "UK", "VD", "YD", "YU", "ZR" */ 37464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert "CW", "MM", "RS", "DE", "BJ", "FR", "BF", "VU", "ZW", "RU", "TL", "GB", "VN", "YE", "RS", "CD", NULL, NULL /* replacement country codes */ 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 37664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Table of 3-letter country codes. 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is a lookup table used to convert 3-letter country codes to 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * their 2-letter equivalent. It must be kept in sync with COUNTRIES. 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * For all valid i, COUNTRIES[i] must refer to the same country as 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * COUNTRIES_3[i]. The commented-out lines are copied from COUNTRIES 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to make eyeballing this baby easier. 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This table should be terminated with a NULL entry, followed by a 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * second list, and another NULL entry. The two lists correspond to 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the two lists in COUNTRIES. 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const COUNTRIES_3[] = { 3918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "AD", "AE", "AF", "AG", "AI", "AL", "AM", */ 3928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", */ 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "ALA", "AZE", 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", */ 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "BIH", "BRB", "BGD", "BEL", "BFA", "BGR", "BHR", "BDI", 3978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", */ 3988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "BEN", "BLM", "BMU", "BRN", "BOL", "BES", "BRA", "BHS", "BTN", "BVT", 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", */ 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG", 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", */ 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "CHE", "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI", 4038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", */ 4048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "CUB", "CPV", "CUW", "CXR", "CYP", "CZE", "DEU", "DJI", "DNK", 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", */ 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH", "ERI", 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", */ 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA", 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", */ 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GAB", "GBR", "GRD", "GEO", "GUF", "GGY", "GHA", "GIB", "GRL", 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", */ 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GMB", "GIN", "GLP", "GNQ", "GRC", "SGS", "GTM", "GUM", 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", */ 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI", "HUN", 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS" */ 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "IDN", "IRL", "ISR", "IMN", "IND", "IOT", "IRQ", "IRN", "ISL", 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", */ 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "ITA", "JEY", "JAM", "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR", 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", */ 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "COM", "KNA", "PRK", "KOR", "KWT", "CYM", "KAZ", "LAO", 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", */ 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX", 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", */ 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "LVA", "LBY", "MAR", "MCO", "MDA", "MNE", "MAF", "MDG", "MHL", "MKD", 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", */ 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "MLI", "MMR", "MNG", "MAC", "MNP", "MTQ", "MRT", "MSR", 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", */ 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "MLT", "MUS", "MDV", "MWI", "MEX", "MYS", "MOZ", "NAM", 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", */ 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL", 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", */ 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "NRU", "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG", 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", */ 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "PHL", "PAK", "POL", "SPM", "PCN", "PRI", "PSE", "PRT", 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", */ 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "PLW", "PRY", "QAT", "REU", "ROU", "SRB", "RUS", "RWA", "SAU", 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", */ 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM", 4398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", */ 4408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "SVK", "SLE", "SMR", "SEN", "SOM", "SUR", "SSD", "STP", "SLV", 4418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", */ 4428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "SXM", "SYR", "SWZ", "TCA", "TCD", "ATF", "TGO", "THA", "TJK", 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", */ 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "TKL", "TLS", "TKM", "TUN", "TON", "TUR", "TTO", "TUV", 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", */ 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB", 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", */ 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "VAT", "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", "WLF", 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* "WS", "YE", "YT", "ZA", "ZM", "ZW", */ 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "WSM", "YEM", "MYT", "ZAF", "ZMB", "ZWE", 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL, 4528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* "AN", "BU", "CS", "FX", "RO", "SU", "TP", "YD", "YU", "ZR" */ 4538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius "ANT", "BUR", "SCG", "FXX", "ROM", "SUN", "TMP", "YMD", "YUG", "ZAR", 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNULL 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct CanonicalizationMap { 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *id; /* input ID */ 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *canonicalID; /* canonicalized output ID */ 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *keyword; /* keyword, or NULL if none */ 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *value; /* keyword value, or NULL if kw==NULL */ 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} CanonicalizationMap; 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * A map to canonicalize locale IDs. This handles a variety of 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * different semantic kinds of transformations. 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const CanonicalizationMap CANONICALIZE_MAP[] = { 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "", "en_US_POSIX", NULL, NULL }, /* .NET name */ 47027f654740f2a26ad62a5c155af9199af9e69b889claireho { "c", "en_US_POSIX", NULL, NULL }, /* POSIX name */ 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "posix", "en_US_POSIX", NULL, NULL }, /* POSIX name (alias of C) */ 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "art_LOJBAN", "jbo", NULL, NULL }, /* registered name */ 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "az_AZ_CYRL", "az_Cyrl_AZ", NULL, NULL }, /* .NET name */ 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "az_AZ_LATN", "az_Latn_AZ", NULL, NULL }, /* .NET name */ 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "ca_ES_PREEURO", "ca_ES", "currency", "ESP" }, 476c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "de__PHONEBOOK", "de", "collation", "phonebook" }, /* Old ICU name */ 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "de_AT_PREEURO", "de_AT", "currency", "ATS" }, 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "de_DE_PREEURO", "de_DE", "currency", "DEM" }, 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "de_LU_PREEURO", "de_LU", "currency", "LUF" }, 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "el_GR_PREEURO", "el_GR", "currency", "GRD" }, 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "en_BE_PREEURO", "en_BE", "currency", "BEF" }, 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "en_IE_PREEURO", "en_IE", "currency", "IEP" }, 483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "es__TRADITIONAL", "es", "collation", "traditional" }, /* Old ICU name */ 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "es_ES_PREEURO", "es_ES", "currency", "ESP" }, 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "eu_ES_PREEURO", "eu_ES", "currency", "ESP" }, 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "fi_FI_PREEURO", "fi_FI", "currency", "FIM" }, 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "fr_BE_PREEURO", "fr_BE", "currency", "BEF" }, 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "fr_FR_PREEURO", "fr_FR", "currency", "FRF" }, 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "fr_LU_PREEURO", "fr_LU", "currency", "LUF" }, 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "ga_IE_PREEURO", "ga_IE", "currency", "IEP" }, 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "gl_ES_PREEURO", "gl_ES", "currency", "ESP" }, 492c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "hi__DIRECT", "hi", "collation", "direct" }, /* Old ICU name */ 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "it_IT_PREEURO", "it_IT", "currency", "ITL" }, 494c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "ja_JP_TRADITIONAL", "ja_JP", "calendar", "japanese" }, /* Old ICU name */ 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "nb_NO_NY", "nn_NO", NULL, NULL }, /* "markus said this was ok" :-) */ 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "nl_BE_PREEURO", "nl_BE", "currency", "BEF" }, 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "nl_NL_PREEURO", "nl_NL", "currency", "NLG" }, 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "pt_PT_PREEURO", "pt_PT", "currency", "PTE" }, 499c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "sr_SP_CYRL", "sr_Cyrl_RS", NULL, NULL }, /* .NET name */ 500c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "sr_SP_LATN", "sr_Latn_RS", NULL, NULL }, /* .NET name */ 501c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "sr_YU_CYRILLIC", "sr_Cyrl_RS", NULL, NULL }, /* Linux name */ 502c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "th_TH_TRADITIONAL", "th_TH", "calendar", "buddhist" }, /* Old ICU name */ 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "uz_UZ_CYRILLIC", "uz_Cyrl_UZ", NULL, NULL }, /* Linux name */ 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "uz_UZ_CYRL", "uz_Cyrl_UZ", NULL, NULL }, /* .NET name */ 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "uz_UZ_LATN", "uz_Latn_UZ", NULL, NULL }, /* .NET name */ 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "zh_CHS", "zh_Hans", NULL, NULL }, /* .NET name */ 507c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "zh_CHT", "zh_Hant", NULL, NULL }, /* .NET name */ 508103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_GAN", "gan", NULL, NULL }, /* registered name */ 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { "zh_GUOYU", "zh", NULL, NULL }, /* registered name */ 510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_HAKKA", "hak", NULL, NULL }, /* registered name */ 511103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_MIN_NAN", "nan", NULL, NULL }, /* registered name */ 512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_WUU", "wuu", NULL, NULL }, /* registered name */ 513103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_XIANG", "hsn", NULL, NULL }, /* registered name */ 514103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { "zh_YUE", "yue", NULL, NULL }, /* registered name */ 515c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}; 516c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 517c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querutypedef struct VariantMap { 518c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char *variant; /* input ID */ 519c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char *keyword; /* keyword, or NULL if none */ 520c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char *value; /* keyword value, or NULL if kw==NULL */ 521c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} VariantMap; 522c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 523c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const VariantMap VARIANT_MAP[] = { 524c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "EURO", "currency", "EUR" }, 525c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "PINYIN", "collation", "pinyin" }, /* Solaris variant */ 526c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { "STROKE", "collation", "stroke" } /* Solaris variant */ 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 52927f654740f2a26ad62a5c155af9199af9e69b889claireho/* ### BCP47 Conversion *******************************************/ 53027f654740f2a26ad62a5c155af9199af9e69b889claireho/* Test if the locale id has BCP47 u extension and does not have '@' */ 53127f654740f2a26ad62a5c155af9199af9e69b889claireho#define _hasBCP47Extension(id) (id && uprv_strstr(id, "@") == NULL && getShortestSubtagLength(localeID) == 1) 53227f654740f2a26ad62a5c155af9199af9e69b889claireho/* Converts the BCP47 id to Unicode id. Does nothing to id if conversion fails */ 53327f654740f2a26ad62a5c155af9199af9e69b889claireho#define _ConvertBCP47(finalID, id, buffer, length,err) \ 534ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert if (uloc_forLanguageTag(id, buffer, length, NULL, err) <= 0 || \ 535ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert U_FAILURE(*err) || *err == U_STRING_NOT_TERMINATED_WARNING) { \ 53627f654740f2a26ad62a5c155af9199af9e69b889claireho finalID=id; \ 537ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert if (*err == U_STRING_NOT_TERMINATED_WARNING) { *err = U_BUFFER_OVERFLOW_ERROR; } \ 53827f654740f2a26ad62a5c155af9199af9e69b889claireho } else { \ 53927f654740f2a26ad62a5c155af9199af9e69b889claireho finalID=buffer; \ 54027f654740f2a26ad62a5c155af9199af9e69b889claireho } 54127f654740f2a26ad62a5c155af9199af9e69b889claireho/* Gets the size of the shortest subtag in the given localeID. */ 54227f654740f2a26ad62a5c155af9199af9e69b889clairehostatic int32_t getShortestSubtagLength(const char *localeID) { 543ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert int32_t localeIDLength = static_cast<int32_t>(uprv_strlen(localeID)); 54427f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t length = localeIDLength; 54527f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t tmpLength = 0; 54627f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t i; 54727f654740f2a26ad62a5c155af9199af9e69b889claireho UBool reset = TRUE; 54827f654740f2a26ad62a5c155af9199af9e69b889claireho 54927f654740f2a26ad62a5c155af9199af9e69b889claireho for (i = 0; i < localeIDLength; i++) { 55027f654740f2a26ad62a5c155af9199af9e69b889claireho if (localeID[i] != '_' && localeID[i] != '-') { 55127f654740f2a26ad62a5c155af9199af9e69b889claireho if (reset) { 55227f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLength = 0; 55327f654740f2a26ad62a5c155af9199af9e69b889claireho reset = FALSE; 55427f654740f2a26ad62a5c155af9199af9e69b889claireho } 55527f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLength++; 55627f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 55727f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpLength != 0 && tmpLength < length) { 55827f654740f2a26ad62a5c155af9199af9e69b889claireho length = tmpLength; 55927f654740f2a26ad62a5c155af9199af9e69b889claireho } 56027f654740f2a26ad62a5c155af9199af9e69b889claireho reset = TRUE; 56127f654740f2a26ad62a5c155af9199af9e69b889claireho } 56227f654740f2a26ad62a5c155af9199af9e69b889claireho } 56327f654740f2a26ad62a5c155af9199af9e69b889claireho 56427f654740f2a26ad62a5c155af9199af9e69b889claireho return length; 56527f654740f2a26ad62a5c155af9199af9e69b889claireho} 56627f654740f2a26ad62a5c155af9199af9e69b889claireho 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### Keywords **************************************************/ 5680596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#define UPRV_ISDIGIT(c) (((c) >= '0') && ((c) <= '9')) 5690596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#define UPRV_ISALPHANUM(c) (uprv_isASCIILetter(c) || UPRV_ISDIGIT(c) ) 5700596faeddefbf198de137d5e893708495ab1584cFredrik Roubert/* Punctuation/symbols allowed in legacy key values */ 5710596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#define UPRV_OK_VALUE_PUNCTUATION(c) ((c) == '_' || (c) == '-' || (c) == '+' || (c) == '/') 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ULOC_KEYWORD_BUFFER_LEN 25 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ULOC_MAX_NO_KEYWORDS 25 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 57627f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI const char * U_EXPORT2 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulocale_getKeywordsStart(const char *localeID) { 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *result = NULL; 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((result = uprv_strchr(localeID, '@')) != NULL) { 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (U_CHARSET_FAMILY == U_EBCDIC_FAMILY) 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We do this because the @ sign is variant, and the @ sign used on one 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru EBCDIC machine won't be compiled the same way on other EBCDIC based 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru machines. */ 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static const uint8_t ebcdicSigns[] = { 0x7C, 0x44, 0x66, 0x80, 0xAC, 0xAE, 0xAF, 0xB5, 0xEC, 0xEF, 0x00 }; 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *charToFind = ebcdicSigns; 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*charToFind) { 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((result = uprv_strchr(localeID, *charToFind)) != NULL) { 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charToFind++; 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param buf buffer of size [ULOC_KEYWORD_BUFFER_LEN] 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param keywordName incoming name to be canonicalized 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param status return status (keyword too long) 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return length of the keyword name 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t locale_canonKeywordName(char *buf, const char *keywordName, UErrorCode *status) 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 6080596faeddefbf198de137d5e893708495ab1584cFredrik Roubert int32_t keywordNameLen = 0; 60964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 6100596faeddefbf198de137d5e893708495ab1584cFredrik Roubert for (; *keywordName != 0; keywordName++) { 6110596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!UPRV_ISALPHANUM(*keywordName)) { 6120596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed keyword name */ 6130596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 6140596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 6150596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keywordNameLen < ULOC_KEYWORD_BUFFER_LEN - 1) { 6160596faeddefbf198de137d5e893708495ab1584cFredrik Roubert buf[keywordNameLen++] = uprv_tolower(*keywordName); 6170596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } else { 6180596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* keyword name too long for internal buffer */ 6190596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_INTERNAL_PROGRAM_ERROR; 6200596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 6210596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 6230596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keywordNameLen == 0) { 6240596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty keyword name */ 6250596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 6270596faeddefbf198de137d5e893708495ab1584cFredrik Roubert buf[keywordNameLen] = 0; /* terminate */ 62864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return keywordNameLen; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct { 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keyword[ULOC_KEYWORD_BUFFER_LEN]; 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordLen; 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *valueStart; 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t valueLen; 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} KeywordStruct; 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 640103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliuscompareKeywordStructs(const void * /*context*/, const void *left, const void *right) { 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* leftString = ((const KeywordStruct *)left)->keyword; 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* rightString = ((const KeywordStruct *)right)->keyword; 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_strcmp(leftString, rightString); 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Both addKeyword and addValue must already be in canonical form. 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Either both addKeyword and addValue are NULL, or neither is NULL. 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If they are not NULL they must be zero terminated. 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If addKeyword is not NULL is must have length small enough to fit in KeywordStruct.keyword. 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_getKeywords(const char *localeID, 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *keywords, int32_t keywordCapacity, 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *values, int32_t valuesCapacity, int32_t *valLen, 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool valuesToo, 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* addKeyword, 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* addValue, 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru KeywordStruct keywordList[ULOC_MAX_NO_KEYWORDS]; 66364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t maxKeywords = ULOC_MAX_NO_KEYWORDS; 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t numKeywords = 0; 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* pos = localeID; 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* equalSign = NULL; 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* semicolon = NULL; 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0, j, n; 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordsLen = 0; 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t valuesLen = 0; 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(prev == '@') { /* start of keyword definition */ 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we will grab pairs, trim spaces, lowercase keywords, sort and return */ 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool duplicate = FALSE; 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip leading spaces */ 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*pos == ' ') { 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pos++; 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!*pos) { /* handle trailing "; " */ 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(numKeywords == maxKeywords) { 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru equalSign = uprv_strchr(pos, '='); 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru semicolon = uprv_strchr(pos, ';'); 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* lack of '=' [foo@currency] is illegal */ 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* ';' before '=' [foo@currency;collation=pinyin] is illegal */ 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!equalSign || (semicolon && semicolon<equalSign)) { 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* need to normalize both keyword and keyword name */ 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(equalSign - pos >= ULOC_KEYWORD_BUFFER_LEN) { 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keyword name too long for internal buffer */ 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0, n = 0; i < equalSign - pos; ++i) { 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pos[i] != ' ') { 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].keyword[n++] = uprv_tolower(pos[i]); 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 70759d709d503bab6e2b61931737e662dd293b40578ccornelius 70859d709d503bab6e2b61931737e662dd293b40578ccornelius /* zero-length keyword is an error. */ 70959d709d503bab6e2b61931737e662dd293b40578ccornelius if (n == 0) { 71059d709d503bab6e2b61931737e662dd293b40578ccornelius *status = U_INVALID_FORMAT_ERROR; 71159d709d503bab6e2b61931737e662dd293b40578ccornelius return 0; 71259d709d503bab6e2b61931737e662dd293b40578ccornelius } 71359d709d503bab6e2b61931737e662dd293b40578ccornelius 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].keyword[n] = 0; 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].keywordLen = n; 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* now grab the value part. First we skip the '=' */ 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru equalSign++; 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* then we leading spaces */ 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*equalSign == ' ') { 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru equalSign++; 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 72259d709d503bab6e2b61931737e662dd293b40578ccornelius 72359d709d503bab6e2b61931737e662dd293b40578ccornelius /* Premature end or zero-length value */ 724c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (!*equalSign || equalSign == semicolon) { 72559d709d503bab6e2b61931737e662dd293b40578ccornelius *status = U_INVALID_FORMAT_ERROR; 72659d709d503bab6e2b61931737e662dd293b40578ccornelius return 0; 72759d709d503bab6e2b61931737e662dd293b40578ccornelius } 72859d709d503bab6e2b61931737e662dd293b40578ccornelius 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueStart = equalSign; 73059d709d503bab6e2b61931737e662dd293b40578ccornelius 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pos = semicolon; 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = 0; 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pos) { 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*(pos - i - 1) == ' ') { 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i++; 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueLen = (int32_t)(pos - equalSign - i); 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pos++; 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = (int32_t)uprv_strlen(equalSign); 741816c50fb47edc483a0516072584640b520045214claireho while(i && equalSign[i-1] == ' ') { 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i--; 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueLen = i; 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If this is a duplicate keyword, then ignore it */ 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j=0; j<numKeywords; ++j) { 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(keywordList[j].keyword, keywordList[numKeywords].keyword) == 0) { 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru duplicate = TRUE; 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!duplicate) { 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++numKeywords; 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(pos); 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Handle addKeyword/addValue. */ 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (addKeyword != NULL) { 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool duplicate = FALSE; 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ASSERT(addValue != NULL); 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Search for duplicate; if found, do nothing. Explicit keyword 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru overrides addKeyword. */ 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j=0; j<numKeywords; ++j) { 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(keywordList[j].keyword, addKeyword) == 0) { 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru duplicate = TRUE; 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!duplicate) { 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (numKeywords == maxKeywords) { 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(keywordList[numKeywords].keyword, addKeyword); 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].keywordLen = (int32_t)uprv_strlen(addKeyword); 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueStart = addValue; 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordList[numKeywords].valueLen = (int32_t)uprv_strlen(addValue); 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++numKeywords; 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ASSERT(addValue == NULL); 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* now we have a list of keywords */ 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we need to sort it */ 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_sortArray(keywordList, numKeywords, sizeof(KeywordStruct), compareKeywordStructs, NULL, FALSE, status); 78864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Now construct the keyword part */ 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0; i < numKeywords; i++) { 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordsLen + keywordList[i].keywordLen + 1< keywordCapacity) { 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(keywords+keywordsLen, keywordList[i].keyword); 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(valuesToo) { 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywords[keywordsLen + keywordList[i].keywordLen] = '='; 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywords[keywordsLen + keywordList[i].keywordLen] = 0; 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordsLen += keywordList[i].keywordLen + 1; 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(valuesToo) { 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(keywordsLen + keywordList[i].valueLen < keywordCapacity) { 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(keywords+keywordsLen, keywordList[i].valueStart, keywordList[i].valueLen); 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordsLen += keywordList[i].valueLen; 80564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i < numKeywords - 1) { 80764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(keywordsLen < keywordCapacity) { 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywords[keywordsLen] = ';'; 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordsLen++; 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(values) { 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(valuesLen + keywordList[i].valueLen + 1< valuesCapacity) { 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(values+valuesLen, keywordList[i].valueStart); 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru values[valuesLen + keywordList[i].valueLen] = 0; 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru valuesLen += keywordList[i].valueLen + 1; 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(values) { 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru values[valuesLen] = 0; 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(valLen) { 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *valLen = valuesLen; 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 82764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return u_terminateChars(keywords, keywordCapacity, keywordsLen, status); 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC int32_t 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulocale_getKeywords(const char *localeID, 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *keywords, int32_t keywordCapacity, 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *values, int32_t valuesCapacity, int32_t *valLen, 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool valuesToo, 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) { 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _getKeywords(localeID, prev, keywords, keywordCapacity, 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru values, valuesCapacity, valLen, valuesToo, 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, NULL, status); 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getKeywordValue(const char* localeID, 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* keywordName, 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* buffer, int32_t bufferCapacity, 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status) 85064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert{ 85127f654740f2a26ad62a5c155af9199af9e69b889claireho const char* startSearchHere = NULL; 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* nextSeparator = NULL; 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN]; 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char localeKeywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN]; 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result = 0; 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status && U_SUCCESS(*status) && localeID) { 85827f654740f2a26ad62a5c155af9199af9e69b889claireho char tempBuffer[ULOC_FULLNAME_CAPACITY]; 85927f654740f2a26ad62a5c155af9199af9e69b889claireho const char* tmpLocaleID; 86027f654740f2a26ad62a5c155af9199af9e69b889claireho 8610596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keywordName == NULL || keywordName[0] == 0) { 8620596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; 8630596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 8640596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 8650596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 8660596faeddefbf198de137d5e893708495ab1584cFredrik Roubert locale_canonKeywordName(keywordNameBuffer, keywordName, status); 8670596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if(U_FAILURE(*status)) { 8680596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 8690596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 8700596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 87127f654740f2a26ad62a5c155af9199af9e69b889claireho if (_hasBCP47Extension(localeID)) { 87227f654740f2a26ad62a5c155af9199af9e69b889claireho _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), status); 87327f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 87427f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID=localeID; 87527f654740f2a26ad62a5c155af9199af9e69b889claireho } 87664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 8770596faeddefbf198de137d5e893708495ab1584cFredrik Roubert startSearchHere = locale_getKeywordsStart(tmpLocaleID); 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(startSearchHere == NULL) { 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no keywords, return at once */ 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* find the first keyword */ 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(startSearchHere) { 8850596faeddefbf198de137d5e893708495ab1584cFredrik Roubert const char* keyValueTail; 8860596faeddefbf198de137d5e893708495ab1584cFredrik Roubert int32_t keyValueLen; 8870596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 8880596faeddefbf198de137d5e893708495ab1584cFredrik Roubert startSearchHere++; /* skip @ or ; */ 8890596faeddefbf198de137d5e893708495ab1584cFredrik Roubert nextSeparator = uprv_strchr(startSearchHere, '='); 8900596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if(!nextSeparator) { 8910596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* key must have =value */ 8920596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 8930596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 8940596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* strip leading & trailing spaces (TC decided to tolerate these) */ 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*startSearchHere == ' ') { 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere++; 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 8980596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueTail = nextSeparator; 8990596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while (keyValueTail > startSearchHere && *(keyValueTail-1) == ' ') { 9000596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueTail--; 9010596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 9020596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* now keyValueTail points to first char after the keyName */ 9030596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* copy & normalize keyName from locale */ 9040596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (startSearchHere == keyValueTail) { 9050596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty keyword name in passed-in locale */ 9060596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9080596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueLen = 0; 9090596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while (startSearchHere < keyValueTail) { 9100596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!UPRV_ISALPHANUM(*startSearchHere)) { 9110596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed keyword name */ 9120596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 9130596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 9140596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keyValueLen < ULOC_KEYWORD_BUFFER_LEN - 1) { 9150596faeddefbf198de137d5e893708495ab1584cFredrik Roubert localeKeywordNameBuffer[keyValueLen++] = uprv_tolower(*startSearchHere++); 9160596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } else { 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keyword name too long for internal buffer */ 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 9200596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9220596faeddefbf198de137d5e893708495ab1584cFredrik Roubert localeKeywordNameBuffer[keyValueLen] = 0; /* terminate */ 92364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere = uprv_strchr(nextSeparator, ';'); 92564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uprv_strcmp(keywordNameBuffer, localeKeywordNameBuffer) == 0) { 9270596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* current entry matches the keyword. */ 9280596faeddefbf198de137d5e893708495ab1584cFredrik Roubert nextSeparator++; /* skip '=' */ 9290596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* First strip leading & trailing spaces (TC decided to tolerate these) */ 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*nextSeparator == ' ') { 9310596faeddefbf198de137d5e893708495ab1584cFredrik Roubert nextSeparator++; 9320596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 9330596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueTail = (startSearchHere)? startSearchHere: nextSeparator + uprv_strlen(nextSeparator); 9340596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while(keyValueTail > nextSeparator && *(keyValueTail-1) == ' ') { 9350596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueTail--; 9360596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 9370596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* Now copy the value, but check well-formedness */ 9380596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (nextSeparator == keyValueTail) { 9390596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty key value name in passed-in locale */ 9400596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9420596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueLen = 0; 9430596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while (nextSeparator < keyValueTail) { 9440596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!UPRV_ISALPHANUM(*nextSeparator) && !UPRV_OK_VALUE_PUNCTUATION(*nextSeparator)) { 9450596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed key value */ 9460596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 9470596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 9480596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keyValueLen < bufferCapacity) { 9490596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* Should we lowercase value to return here? Tests expect as-is. */ 9500596faeddefbf198de137d5e893708495ab1584cFredrik Roubert buffer[keyValueLen++] = *nextSeparator++; 9510596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } else { /* keep advancing so we return correct length in case of overflow */ 9520596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueLen++; 9530596faeddefbf198de137d5e893708495ab1584cFredrik Roubert nextSeparator++; 9540596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9560596faeddefbf198de137d5e893708495ab1584cFredrik Roubert result = u_terminateChars(buffer, bufferCapacity, keyValueLen, status); 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_setKeywordValue(const char* keywordName, 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* keywordValue, 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* buffer, int32_t bufferCapacity, 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status) 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* TODO: sorting. removal. */ 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordNameLen; 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordValueLen; 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t bufLen; 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t needLen = 0; 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN]; 9760596faeddefbf198de137d5e893708495ab1584cFredrik Roubert char keywordValueBuffer[ULOC_KEYWORDS_CAPACITY+1]; 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char localeKeywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN]; 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rc; 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* nextSeparator = NULL; 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* nextEqualsign = NULL; 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* startSearchHere = NULL; 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* keywordStart = NULL; 9830596faeddefbf198de137d5e893708495ab1584cFredrik Roubert CharString updatedKeysAndValues; 9840596faeddefbf198de137d5e893708495ab1584cFredrik Roubert int32_t updatedKeysAndValuesLen; 9850596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UBool handledInputKeyAndValue = FALSE; 9860596faeddefbf198de137d5e893708495ab1584cFredrik Roubert char keyValuePrefix = '@'; 9870596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 98864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(U_FAILURE(*status)) { 98964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return -1; 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9910596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keywordName == NULL || keywordName[0] == 0 || bufferCapacity <= 1) { 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9950596faeddefbf198de137d5e893708495ab1584cFredrik Roubert bufLen = (int32_t)uprv_strlen(buffer); 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bufferCapacity<bufLen) { 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* The capacity is less than the length?! Is this NULL terminated? */ 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordNameLen = locale_canonKeywordName(keywordNameBuffer, keywordName, status); 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10050596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 10060596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keywordValueLen = 0; 10070596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if(keywordValue) { 10080596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while (*keywordValue != 0) { 10090596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!UPRV_ISALPHANUM(*keywordValue) && !UPRV_OK_VALUE_PUNCTUATION(*keywordValue)) { 10100596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed key value */ 10110596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 10120596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 10130596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keywordValueLen < ULOC_KEYWORDS_CAPACITY) { 10140596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* Should we force lowercase in value to set? */ 10150596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keywordValueBuffer[keywordValueLen++] = *keywordValue++; 10160596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } else { 10170596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* keywordValue too long for internal buffer */ 10180596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_INTERNAL_PROGRAM_ERROR; 10190596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 10200596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 10210596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 10220596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 10230596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keywordValueBuffer[keywordValueLen] = 0; /* terminate */ 10240596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere = (char*)locale_getKeywordsStart(buffer); 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(startSearchHere == NULL || (startSearchHere[1]==0)) { 10270596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if(keywordValueLen == 0) { /* no keywords = nothing to remove */ 102864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return bufLen; 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needLen = bufLen+1+keywordNameLen+1+keywordValueLen; 103264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(startSearchHere) { /* had a single @ */ 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needLen--; /* already had the @ */ 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* startSearchHere points at the @ */ 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere=buffer+bufLen; 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(needLen >= bufferCapacity) { 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_BUFFER_OVERFLOW_ERROR; 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return needLen; /* no change */ 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10420596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *startSearchHere++ = '@'; 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(startSearchHere, keywordNameBuffer); 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startSearchHere += keywordNameLen; 10450596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *startSearchHere++ = '='; 10460596faeddefbf198de137d5e893708495ab1584cFredrik Roubert uprv_strcpy(startSearchHere, keywordValueBuffer); 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return needLen; 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* end shortcut - no @ */ 104964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart = startSearchHere; 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* search for keyword */ 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(keywordStart) { 10530596faeddefbf198de137d5e893708495ab1584cFredrik Roubert const char* keyValueTail; 10540596faeddefbf198de137d5e893708495ab1584cFredrik Roubert int32_t keyValueLen; 10550596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 10560596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keywordStart++; /* skip @ or ; */ 10570596faeddefbf198de137d5e893708495ab1584cFredrik Roubert nextEqualsign = uprv_strchr(keywordStart, '='); 10580596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!nextEqualsign) { 10590596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* key must have =value */ 10600596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 10610596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 10620596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* strip leading & trailing spaces (TC decided to tolerate these) */ 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*keywordStart == ' ') { 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart++; 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10660596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueTail = nextEqualsign; 10670596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while (keyValueTail > keywordStart && *(keyValueTail-1) == ' ') { 10680596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueTail--; 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10700596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* now keyValueTail points to first char after the keyName */ 10710596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* copy & normalize keyName from locale */ 10720596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keywordStart == keyValueTail) { 10730596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty keyword name in passed-in locale */ 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10760596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueLen = 0; 10770596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while (keywordStart < keyValueTail) { 10780596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!UPRV_ISALPHANUM(*keywordStart)) { 10790596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed keyword name */ 10800596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 10810596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 10820596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (keyValueLen < ULOC_KEYWORD_BUFFER_LEN - 1) { 10830596faeddefbf198de137d5e893708495ab1584cFredrik Roubert localeKeywordNameBuffer[keyValueLen++] = uprv_tolower(*keywordStart++); 10840596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } else { 10850596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* keyword name too long for internal buffer */ 10860596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_INTERNAL_PROGRAM_ERROR; 10870596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 10880596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10900596faeddefbf198de137d5e893708495ab1584cFredrik Roubert localeKeywordNameBuffer[keyValueLen] = 0; /* terminate */ 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextSeparator = uprv_strchr(nextEqualsign, ';'); 10930596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 10940596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* start processing the value part */ 10950596faeddefbf198de137d5e893708495ab1584cFredrik Roubert nextEqualsign++; /* skip '=' */ 10960596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* First strip leading & trailing spaces (TC decided to tolerate these) */ 10970596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while(*nextEqualsign == ' ') { 10980596faeddefbf198de137d5e893708495ab1584cFredrik Roubert nextEqualsign++; 10990596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11000596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueTail = (nextSeparator)? nextSeparator: nextEqualsign + uprv_strlen(nextEqualsign); 11010596faeddefbf198de137d5e893708495ab1584cFredrik Roubert while(keyValueTail > nextEqualsign && *(keyValueTail-1) == ' ') { 11020596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValueTail--; 11030596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11040596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (nextEqualsign == keyValueTail) { 11050596faeddefbf198de137d5e893708495ab1584cFredrik Roubert *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty key value in passed-in locale */ 11060596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 11070596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11080596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = uprv_strcmp(keywordNameBuffer, localeKeywordNameBuffer); 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(rc == 0) { 11110596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* Current entry matches the input keyword. Update the entry */ 11120596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if(keywordValueLen > 0) { /* updating a value */ 11130596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keyValuePrefix, *status); 11140596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValuePrefix = ';'; /* for any subsequent key-value pair */ 11150596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keywordNameBuffer, keywordNameLen, *status); 11160596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append('=', *status); 11170596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keywordValueBuffer, keywordValueLen, *status); 11180596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } /* else removing this entry, don't emit anything */ 11190596faeddefbf198de137d5e893708495ab1584cFredrik Roubert handledInputKeyAndValue = TRUE; 11200596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } else { 11210596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* input keyword sorts earlier than current entry, add before current entry */ 11220596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (rc < 0 && keywordValueLen > 0 && !handledInputKeyAndValue) { 11230596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* insert new entry at this location */ 11240596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keyValuePrefix, *status); 11250596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValuePrefix = ';'; /* for any subsequent key-value pair */ 11260596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keywordNameBuffer, keywordNameLen, *status); 11270596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append('=', *status); 11280596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keywordValueBuffer, keywordValueLen, *status); 11290596faeddefbf198de137d5e893708495ab1584cFredrik Roubert handledInputKeyAndValue = TRUE; 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 11310596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* copy the current entry */ 11320596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keyValuePrefix, *status); 11330596faeddefbf198de137d5e893708495ab1584cFredrik Roubert keyValuePrefix = ';'; /* for any subsequent key-value pair */ 11340596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(localeKeywordNameBuffer, keyValueLen, *status); 11350596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append('=', *status); 11360596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(nextEqualsign, keyValueTail-nextEqualsign, *status); 11370596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11380596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!nextSeparator && keywordValueLen > 0 && !handledInputKeyAndValue) { 11390596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* append new entry at the end, it sorts later than existing entries */ 11400596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keyValuePrefix, *status); 11410596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* skip keyValuePrefix update, no subsequent key-value pair */ 11420596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keywordNameBuffer, keywordNameLen, *status); 11430596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append('=', *status); 11440596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValues.append(keywordValueBuffer, keywordValueLen, *status); 11450596faeddefbf198de137d5e893708495ab1584cFredrik Roubert handledInputKeyAndValue = TRUE; 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordStart = nextSeparator; 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* end loop searching */ 114964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 11500596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* Any error from updatedKeysAndValues.append above would be internal and not due to 11510596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * problems with the passed-in locale. So if we did encounter problems with the 11520596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * passed-in locale above, those errors took precedence and overrode any error 11530596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * status from updatedKeysAndValues.append, and also caused a return of 0. If there 11540596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * are errors here they are from updatedKeysAndValues.append; they do cause an 11550596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * error return but the passed-in locale is unmodified and the original bufLen is 11560596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * returned. 11570596faeddefbf198de137d5e893708495ab1584cFredrik Roubert */ 11580596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!handledInputKeyAndValue || U_FAILURE(*status)) { 11590596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* if input key/value specified removal of a keyword not present in locale, or 11600596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * there was an error in CharString.append, leave original locale alone. */ 11610596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return bufLen; 11620596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11630596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 11640596faeddefbf198de137d5e893708495ab1584cFredrik Roubert updatedKeysAndValuesLen = updatedKeysAndValues.length(); 11650596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* needLen = length of the part before '@' + length of updated key-value part including '@' */ 11660596faeddefbf198de137d5e893708495ab1584cFredrik Roubert needLen = (int32_t)(startSearchHere - buffer) + updatedKeysAndValuesLen; 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(needLen >= bufferCapacity) { 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_BUFFER_OVERFLOW_ERROR; 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return needLen; /* no change */ 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 11710596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (updatedKeysAndValuesLen > 0) { 11720596faeddefbf198de137d5e893708495ab1584cFredrik Roubert uprv_strncpy(startSearchHere, updatedKeysAndValues.data(), updatedKeysAndValuesLen); 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[needLen]=0; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return needLen; 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### ID parsing implementation **************************************************/ 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _isPrefixLetter(a) ((a=='x')||(a=='X')||(a=='i')||(a=='I')) 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*returns TRUE if one of the special prefixes is here (s=string) 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 'x-' or 'i-' */ 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _isIDPrefix(s) (_isPrefixLetter(s[0])&&_isIDSeparator(s[1])) 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Dot terminates it because of POSIX form where dot precedes the codepage 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * except for variant 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _isTerminator(a) ((a==0)||(a=='.')||(a=='@')) 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char* _strnchr(const char* str, int32_t len, char c) { 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ASSERT(str != 0 && len >= 0); 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (len-- != 0) { 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char d = *str; 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (d == c) { 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (char*) str; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (d == 0) { 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++str; 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Lookup 'key' in the array 'list'. The array 'list' should contain 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * a NULL entry, followed by more entries, and a second NULL entry. 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The 'list' param should be LANGUAGES, LANGUAGES_3, COUNTRIES, or 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * COUNTRIES_3. 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int16_t _findIndex(const char* const* list, const char* key) 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* const* anchor = list; 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t pass = 0; 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Make two passes through two NULL-terminated arrays at 'list' */ 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (pass++ < 2) { 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (*list) { 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(key, *list) == 0) { 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int16_t)(list - anchor); 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru list++; 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++list; /* skip final NULL *CWB*/ 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* count the length of src while copying it to dest; return strlen(src) */ 1231103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline int32_t 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_copyCount(char *dest, int32_t destCapacity, const char *src) { 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *anchor; 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru anchor=src; 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((c=*src)==0) { 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)(src-anchor); 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(destCapacity<=0) { 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)((src-anchor)+uprv_strlen(src)); 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++src; 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *dest++=c; 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --destCapacity; 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125064339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertU_CFUNC const char* 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getCurrentCountryID(const char* oldID){ 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset = _findIndex(DEPRECATED_COUNTRIES, oldID); 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset >= 0) { 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return REPLACEMENT_COUNTRIES[offset]; 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return oldID; 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 125864339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertU_CFUNC const char* 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getCurrentLanguageID(const char* oldID){ 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset = _findIndex(DEPRECATED_LANGUAGES, oldID); 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset >= 0) { 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return REPLACEMENT_LANGUAGES[offset]; 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 126464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return oldID; 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the internal functions _getLanguage(), _getCountry(), _getVariant() 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * avoid duplicating code to handle the earlier locale ID pieces 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * in the functions for the later ones by 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * setting the *pEnd pointer to where they stopped parsing 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TODO try to use this in Locale 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 127450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC int32_t 127550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoulocimp_getLanguage(const char *localeID, 127650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *language, int32_t languageCapacity, 127750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char **pEnd) { 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset; 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char lang[4]={ 0, 0, 0, 0 }; /* temporary buffer to hold language code for searching */ 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if it starts with i- or x- then copy that prefix */ 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDPrefix(localeID)) { 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<languageCapacity) { 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru language[i]=(char)uprv_tolower(*localeID); 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<languageCapacity) { 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru language[i+1]='-'; 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i+=2; 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID+=2; 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 129364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the language as far as possible and count its length */ 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(!_isTerminator(*localeID) && !_isIDSeparator(*localeID)) { 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<languageCapacity) { 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru language[i]=(char)uprv_tolower(*localeID); 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<3) { 1300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(i>=0); 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lang[i]=(char)uprv_tolower(*localeID); 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i++; 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID++; 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i==3) { 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* convert 3 character code to 2 character code if possible *CWB*/ 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset=_findIndex(LANGUAGES_3, lang); 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(offset>=0) { 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=_copyCount(language, languageCapacity, LANGUAGES[offset]); 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pEnd!=NULL) { 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pEnd=localeID; 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return i; 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 132150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC int32_t 132250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoulocimp_getScript(const char *localeID, 132350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *script, int32_t scriptCapacity, 132450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char **pEnd) 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t idLen = 0; 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pEnd != NULL) { 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pEnd = localeID; 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the second item as far as possible and count its length */ 1333103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius while(!_isTerminator(localeID[idLen]) && !_isIDSeparator(localeID[idLen]) 1334103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius && uprv_isASCIILetter(localeID[idLen])) { 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idLen++; 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If it's exactly 4 characters long, then it's a script and not a country. */ 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (idLen == 4) { 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pEnd != NULL) { 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pEnd = localeID+idLen; 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(idLen > scriptCapacity) { 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idLen = scriptCapacity; 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (idLen >= 1) { 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru script[0]=(char)uprv_toupper(*(localeID++)); 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 1; i < idLen; i++) { 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru script[i]=(char)uprv_tolower(*(localeID++)); 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idLen = 0; 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return idLen; 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 136050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC int32_t 136150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoulocimp_getCountry(const char *localeID, 136250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *country, int32_t countryCapacity, 136350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char **pEnd) 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 136550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t idLen=0; 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cnty[ULOC_COUNTRY_CAPACITY]={ 0, 0, 0, 0 }; 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset; 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the country as far as possible and count its length */ 137050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(!_isTerminator(localeID[idLen]) && !_isIDSeparator(localeID[idLen])) { 137150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(idLen<(ULOC_COUNTRY_CAPACITY-1)) { /*CWB*/ 137250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho cnty[idLen]=(char)uprv_toupper(localeID[idLen]); 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 137450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho idLen++; 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 137750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* the country should be either length 2 or 3 */ 137850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (idLen == 2 || idLen == 3) { 137950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool gotCountry = FALSE; 138050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* convert 3 character code to 2 character code if possible *CWB*/ 138150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(idLen==3) { 138250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho offset=_findIndex(COUNTRIES_3, cnty); 138350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(offset>=0) { 138450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho idLen=_copyCount(country, countryCapacity, COUNTRIES[offset]); 138550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho gotCountry = TRUE; 138650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 138750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 138850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (!gotCountry) { 138950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t i = 0; 139050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0; i < idLen; i++) { 139150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (i < countryCapacity) { 139250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho country[i]=(char)uprv_toupper(localeID[i]); 139350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 139450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 139650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho localeID+=idLen; 139750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 139850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho idLen = 0; 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pEnd!=NULL) { 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pEnd=localeID; 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 140450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 140550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return idLen; 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param needSeparator if true, then add leading '_' if any variants 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * are added to 'variant' 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_getVariantEx(const char *localeID, 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *variant, int32_t variantCapacity, 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool needSeparator) { 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get one or more variant tags and separate them with '_' */ 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDSeparator(prev)) { 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get a variant string after a '-' or '_' */ 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(!_isTerminator(*localeID)) { 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (needSeparator) { 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i<variantCapacity) { 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i] = '_'; 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needSeparator = FALSE; 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<variantCapacity) { 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i]=(char)uprv_toupper(*localeID); 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(variant[i]=='-') { 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i]='_'; 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i++; 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID++; 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there is no variant tag after a '-' or '_' then look for '@' */ 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i==0) { 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(prev=='@') { 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keep localeID */ 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if((localeID=locale_getKeywordsStart(localeID))!=NULL) { 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++localeID; /* point after the '@' */ 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(!_isTerminator(*localeID)) { 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (needSeparator) { 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i<variantCapacity) { 1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i] = '_'; 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru needSeparator = FALSE; 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<variantCapacity) { 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i]=(char)uprv_toupper(*localeID); 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(variant[i]=='-' || variant[i]==',') { 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant[i]='_'; 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i++; 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID++; 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 146864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return i; 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_getVariant(const char *localeID, 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char prev, 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *variant, int32_t variantCapacity) { 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _getVariantEx(localeID, prev, variant, variantCapacity, FALSE); 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Delete ALL instances of a variant from the given list of one or 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * more variants. Example: "FOO_EURO_BAR_EURO" => "FOO_BAR". 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param variants the source string of one or more variants, 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * separated by '_'. This will be MODIFIED IN PLACE. Not zero 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * terminated; if it is, trailing zero will NOT be maintained. 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param variantsLen length of variants 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param toDelete variant to delete, without separators, e.g. "EURO" 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * or "PREEURO"; not zero terminated 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param toDeleteLen length of toDelete 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return number of characters deleted from variants 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_deleteVariant(char* variants, int32_t variantsLen, 1493c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char* toDelete, int32_t toDeleteLen) 1494c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t delta = 0; /* number of chars deleted */ 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) { 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool flag = FALSE; 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variantsLen < toDeleteLen) { 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return delta; 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strncmp(variants, toDelete, toDeleteLen) == 0 && 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (variantsLen == toDeleteLen || 1503c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru (flag=(variants[toDeleteLen] == '_')))) 1504c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t d = toDeleteLen + (flag?1:0); 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variantsLen -= d; 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delta += d; 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variantsLen > 0) { 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(variants, variants+d, variantsLen); 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* p = _strnchr(variants, variantsLen, '_'); 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p == NULL) { 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return delta; 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variantsLen -= (int32_t)(p - variants); 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variants = p; 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Keyword enumeration */ 1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct UKeywordsContext { 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* keywords; 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* current; 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} UKeywordsContext; 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 153064339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertU_CDECL_BEGIN 153164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_kw_closeKeywords(UEnumeration *enumerator) { 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(((UKeywordsContext *)enumerator->context)->keywords); 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(enumerator->context); 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(enumerator); 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 1540103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuloc_kw_countKeywords(UEnumeration *en, UErrorCode * /*status*/) { 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *kw = ((UKeywordsContext *)en->context)->keywords; 1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result = 0; 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*kw) { 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result++; 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru kw += uprv_strlen(kw)+1; 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 155064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertstatic const char * U_CALLCONV 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_kw_nextKeyword(UEnumeration* en, 1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t* resultLength, 1553103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode* /*status*/) { 1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* result = ((UKeywordsContext *)en->context)->current; 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len = 0; 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*result) { 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (int32_t)uprv_strlen(((UKeywordsContext *)en->context)->current); 1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UKeywordsContext *)en->context)->current += len+1; 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = NULL; 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (resultLength) { 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *resultLength = len; 1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 156864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertstatic void U_CALLCONV 156964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertuloc_kw_resetKeywords(UEnumeration* en, 1570103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode* /*status*/) { 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UKeywordsContext *)en->context)->current = ((UKeywordsContext *)en->context)->keywords; 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 157464339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertU_CDECL_END 157564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 157664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UEnumeration gKeywordsEnum = { 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_kw_closeKeywords, 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_kw_countKeywords, 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uenum_unextDefault, 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_kw_nextKeyword, 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_kw_resetKeywords 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UEnumeration* U_EXPORT2 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_openKeywordList(const char *keywordList, int32_t keywordListSize, UErrorCode* status) 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1590c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UKeywordsContext *myContext = NULL; 1591c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UEnumeration *result = NULL; 1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1593c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(U_FAILURE(*status)) { 1594c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 1595c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1596c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); 1597c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* Null pointer test */ 1598c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (result == NULL) { 1599c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1600c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 1601c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1602c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(result, &gKeywordsEnum, sizeof(UEnumeration)); 160354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius myContext = static_cast<UKeywordsContext *>(uprv_malloc(sizeof(UKeywordsContext))); 1604c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (myContext == NULL) { 1605c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1606c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free(result); 1607c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 1608c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1609c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru myContext->keywords = (char *)uprv_malloc(keywordListSize+1); 1610c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(myContext->keywords, keywordList, keywordListSize); 1611c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru myContext->keywords[keywordListSize] = 0; 1612c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru myContext->current = myContext->keywords; 1613c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->context = myContext; 1614c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return result; 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UEnumeration* U_EXPORT2 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_openKeywords(const char* localeID, 161964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode* status) 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keywords[256]; 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordsCapacity = 256; 162427f654740f2a26ad62a5c155af9199af9e69b889claireho char tempBuffer[ULOC_FULLNAME_CAPACITY]; 162527f654740f2a26ad62a5c155af9199af9e69b889claireho const char* tmpLocaleID; 162627f654740f2a26ad62a5c155af9199af9e69b889claireho 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status==NULL || U_FAILURE(*status)) { 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 163064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 163127f654740f2a26ad62a5c155af9199af9e69b889claireho if (_hasBCP47Extension(localeID)) { 163227f654740f2a26ad62a5c155af9199af9e69b889claireho _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), status); 163327f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 163427f654740f2a26ad62a5c155af9199af9e69b889claireho if (localeID==NULL) { 163527f654740f2a26ad62a5c155af9199af9e69b889claireho localeID=uloc_getDefault(); 163627f654740f2a26ad62a5c155af9199af9e69b889claireho } 163727f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID=localeID; 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the language */ 164127f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getLanguage(tmpLocaleID, NULL, 0, &tmpLocaleID); 164227f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *scriptID; 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the script if available */ 164527f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getScript(tmpLocaleID+1, NULL, 0, &scriptID); 164627f654740f2a26ad62a5c155af9199af9e69b889claireho if(scriptID != tmpLocaleID+1) { 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Found optional script */ 164827f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = scriptID; 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the Country */ 165127f654740f2a26ad62a5c155af9199af9e69b889claireho if (_isIDSeparator(*tmpLocaleID)) { 165227f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getCountry(tmpLocaleID+1, NULL, 0, &tmpLocaleID); 165327f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 165427f654740f2a26ad62a5c155af9199af9e69b889claireho _getVariant(tmpLocaleID+1, *tmpLocaleID, NULL, 0); 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keywords are located after '@' */ 166027f654740f2a26ad62a5c155af9199af9e69b889claireho if((tmpLocaleID = locale_getKeywordsStart(tmpLocaleID)) != NULL) { 166127f654740f2a26ad62a5c155af9199af9e69b889claireho i=locale_getKeywords(tmpLocaleID+1, '@', keywords, keywordsCapacity, NULL, 0, NULL, FALSE, status); 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i) { 1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uloc_openKeywordList(keywords, i, status); 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* bit-flags for 'options' parameter of _canonicalize */ 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _ULOC_STRIP_KEYWORDS 0x2 1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _ULOC_CANONICALIZE 0x1 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define OPTION_SET(options, mask) ((options & mask) != 0) 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char i_default[] = {'i', '-', 'd', 'e', 'f', 'a', 'u', 'l', 't'}; 16798de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert#define I_DEFAULT_LENGTH UPRV_LENGTHOF(i_default) 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Canonicalize the given localeID, to level 1 or to level 2, 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * depending on the options. To specify level 1, pass in options=0. 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * To specify level 2, pass in options=_ULOC_CANONICALIZE. 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is the code underlying uloc_getName and uloc_canonicalize. 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_canonicalize(const char* localeID, 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* result, 1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t resultCapacity, 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t options, 1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) { 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t j, len, fieldCount=0, scriptSize=0, variantSize=0, nameCapacity; 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char localeBuffer[ULOC_FULLNAME_CAPACITY]; 169627f654740f2a26ad62a5c155af9199af9e69b889claireho char tempBuffer[ULOC_FULLNAME_CAPACITY]; 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* origLocaleID; 169827f654740f2a26ad62a5c155af9199af9e69b889claireho const char* tmpLocaleID; 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* keywordAssign = NULL; 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* separatorIndicator = NULL; 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* addKeyword = NULL; 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* addValue = NULL; 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* name; 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* variant = NULL; /* pointer into name, or NULL */ 1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*err)) { 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 170964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 171027f654740f2a26ad62a5c155af9199af9e69b889claireho if (_hasBCP47Extension(localeID)) { 171127f654740f2a26ad62a5c155af9199af9e69b889claireho _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), err); 171227f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 171327f654740f2a26ad62a5c155af9199af9e69b889claireho if (localeID==NULL) { 171427f654740f2a26ad62a5c155af9199af9e69b889claireho localeID=uloc_getDefault(); 171527f654740f2a26ad62a5c155af9199af9e69b889claireho } 171627f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID=localeID; 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 171827f654740f2a26ad62a5c155af9199af9e69b889claireho 171927f654740f2a26ad62a5c155af9199af9e69b889claireho origLocaleID=tmpLocaleID; 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if we are doing a full canonicalization, then put results in 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeBuffer, if necessary; otherwise send them to result. */ 172350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (/*OPTION_SET(options, _ULOC_CANONICALIZE) &&*/ 1724103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius (result == NULL || resultCapacity < (int32_t)sizeof(localeBuffer))) { 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = localeBuffer; 1726103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius nameCapacity = (int32_t)sizeof(localeBuffer); 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = result; 1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nameCapacity = resultCapacity; 1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get all pieces, one after another, and separate with '_' */ 173327f654740f2a26ad62a5c155af9199af9e69b889claireho len=ulocimp_getLanguage(tmpLocaleID, name, nameCapacity, &tmpLocaleID); 1734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len == I_DEFAULT_LENGTH && uprv_strncmp(origLocaleID, i_default, len) == 0) { 1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *d = uloc_getDefault(); 173764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 173850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho len = (int32_t)uprv_strlen(d); 1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (name != NULL) { 1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(name, d, len); 1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 174327f654740f2a26ad62a5c155af9199af9e69b889claireho } else if(_isIDSeparator(*tmpLocaleID)) { 1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *scriptID; 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fieldCount; 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len<nameCapacity) { 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len]='_'; 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1752103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius scriptSize=ulocimp_getScript(tmpLocaleID+1, 1753103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius (len<nameCapacity ? name+len : NULL), nameCapacity-len, &scriptID); 1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(scriptSize > 0) { 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Found optional script */ 175627f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = scriptID; 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fieldCount; 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len+=scriptSize; 175927f654740f2a26ad62a5c155af9199af9e69b889claireho if (_isIDSeparator(*tmpLocaleID)) { 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If there is something else, then we add the _ */ 1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len<nameCapacity) { 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len]='_'; 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 176827f654740f2a26ad62a5c155af9199af9e69b889claireho if (_isIDSeparator(*tmpLocaleID)) { 176950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *cntryID; 1770103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t cntrySize = ulocimp_getCountry(tmpLocaleID+1, 1771103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius (len<nameCapacity ? name+len : NULL), nameCapacity-len, &cntryID); 177250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (cntrySize > 0) { 177350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Found optional country */ 177427f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = cntryID; 177550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho len+=cntrySize; 177650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 177727f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 177854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius /* If there is something else, then we add the _ if we found country before. */ 177954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (cntrySize >= 0 && ! _isIDSeparator(*(tmpLocaleID+1)) ) { 178050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++fieldCount; 178150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(len<nameCapacity) { 178250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho name[len]='_'; 178350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 178450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++len; 1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 178650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1787103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius variantSize = _getVariant(tmpLocaleID+1, *tmpLocaleID, 1788103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius (len<nameCapacity ? name+len : NULL), nameCapacity-len); 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variantSize > 0) { 1790103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius variant = len<nameCapacity ? name+len : NULL; 1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += variantSize; 179227f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID += variantSize + 1; /* skip '_' and variant */ 1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Copy POSIX-style charset specifier, if any [mr.utf8] */ 179927f654740f2a26ad62a5c155af9199af9e69b889claireho if (!OPTION_SET(options, _ULOC_CANONICALIZE) && *tmpLocaleID == '.') { 1800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool done = FALSE; 1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 180227f654740f2a26ad62a5c155af9199af9e69b889claireho char c = *tmpLocaleID; 1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (c) { 1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: 1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case '@': 1806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru done = TRUE; 1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len<nameCapacity) { 1810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len] = c; 1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 181327f654740f2a26ad62a5c155af9199af9e69b889claireho ++tmpLocaleID; 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while (!done); 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Scan ahead to next '@' and determine if it is followed by '=' and/or ';' 182027f654740f2a26ad62a5c155af9199af9e69b889claireho After this, tmpLocaleID either points to '@' or is NULL */ 182127f654740f2a26ad62a5c155af9199af9e69b889claireho if ((tmpLocaleID=locale_getKeywordsStart(tmpLocaleID))!=NULL) { 182227f654740f2a26ad62a5c155af9199af9e69b889claireho keywordAssign = uprv_strchr(tmpLocaleID, '='); 182327f654740f2a26ad62a5c155af9199af9e69b889claireho separatorIndicator = uprv_strchr(tmpLocaleID, ';'); 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Copy POSIX-style variant, if any [mr@FOO] */ 1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!OPTION_SET(options, _ULOC_CANONICALIZE) && 182827f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID != NULL && keywordAssign == NULL) { 1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) { 183027f654740f2a26ad62a5c155af9199af9e69b889claireho char c = *tmpLocaleID; 1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (c == 0) { 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len<nameCapacity) { 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len] = c; 1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 183827f654740f2a26ad62a5c155af9199af9e69b889claireho ++tmpLocaleID; 1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (OPTION_SET(options, _ULOC_CANONICALIZE)) { 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Handle @FOO variant if @ is present and not followed by = */ 184427f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpLocaleID!=NULL && keywordAssign==NULL) { 1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t posixVariantSize; 1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Add missing '_' if needed */ 1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fieldCount < 2 || (fieldCount < 3 && scriptSize > 0)) { 1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len<nameCapacity) { 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len]='_'; 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fieldCount; 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(fieldCount<2); 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 185627f654740f2a26ad62a5c155af9199af9e69b889claireho posixVariantSize = _getVariantEx(tmpLocaleID+1, '@', name+len, nameCapacity-len, 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (UBool)(variantSize > 0)); 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (posixVariantSize > 0) { 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variant == NULL) { 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variant = name+len; 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += posixVariantSize; 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru variantSize += posixVariantSize; 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1867c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* Handle generic variants first */ 1868c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (variant) { 18698de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert for (j=0; j<UPRV_LENGTHOF(VARIANT_MAP); j++) { 1870c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char* variantToCompare = VARIANT_MAP[j].variant; 1871c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t n = (int32_t)uprv_strlen(variantToCompare); 1872c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t variantLen = _deleteVariant(variant, uprv_min(variantSize, (nameCapacity-len)), variantToCompare, n); 1873c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru len -= variantLen; 1874c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (variantLen > 0) { 1875ab19ce4e2e94e2c9e847a6ae07773a48e4d40713claireho if (len > 0 && name[len-1] == '_') { /* delete trailing '_' */ 1876c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru --len; 1877c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1878c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru addKeyword = VARIANT_MAP[j].keyword; 1879c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru addValue = VARIANT_MAP[j].value; 1880c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 1881c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1882c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1883ab19ce4e2e94e2c9e847a6ae07773a48e4d40713claireho if (len > 0 && len <= nameCapacity && name[len-1] == '_') { /* delete trailing '_' */ 1884c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru --len; 1885c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Look up the ID in the canonicalization map */ 18898de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert for (j=0; j<UPRV_LENGTHOF(CANONICALIZE_MAP); j++) { 1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* id = CANONICALIZE_MAP[j].id; 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t n = (int32_t)uprv_strlen(id); 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len == n && uprv_strncmp(name, id, n) == 0) { 189327f654740f2a26ad62a5c155af9199af9e69b889claireho if (n == 0 && tmpLocaleID != NULL) { 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* Don't remap "" if keywords present */ 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = _copyCount(name, nameCapacity, CANONICALIZE_MAP[j].canonicalID); 1897c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (CANONICALIZE_MAP[j].keyword) { 1898c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru addKeyword = CANONICALIZE_MAP[j].keyword; 1899c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru addValue = CANONICALIZE_MAP[j].value; 1900c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!OPTION_SET(options, _ULOC_STRIP_KEYWORDS)) { 190727f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpLocaleID!=NULL && keywordAssign!=NULL && 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (!separatorIndicator || separatorIndicator > keywordAssign)) { 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len<nameCapacity) { 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name[len]='@'; 1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++len; 1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++fieldCount; 1914103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius len += _getKeywords(tmpLocaleID+1, '@', (len<nameCapacity ? name+len : NULL), nameCapacity-len, 1915103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius NULL, 0, NULL, TRUE, addKeyword, addValue, err); 1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (addKeyword != NULL) { 191754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_ASSERT(addValue != NULL && len < nameCapacity); 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* inelegant but works -- later make _getKeywords do this? */ 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += _copyCount(name+len, nameCapacity-len, "@"); 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += _copyCount(name+len, nameCapacity-len, addKeyword); 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += _copyCount(name+len, nameCapacity-len, "="); 1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += _copyCount(name+len, nameCapacity-len, addValue); 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*err) && result != NULL && name == localeBuffer) { 1927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(result, localeBuffer, (len > resultCapacity) ? resultCapacity : len); 1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(result, resultCapacity, len, err); 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### ID parsing API **************************************************/ 1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getParent(const char* localeID, 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* parent, 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t parentCapacity, 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *lastUnderscore; 1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 194364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*err)) 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 194664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (localeID == NULL) 1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID = uloc_getDefault(); 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lastUnderscore=uprv_strrchr(localeID, '_'); 1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(lastUnderscore!=NULL) { 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=(int32_t)(lastUnderscore-localeID); 1953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=0; 1955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i>0 && parent != localeID) { 1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(parent, localeID, uprv_min(i, parentCapacity)); 1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(parent, parentCapacity, i, err); 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getLanguage(const char* localeID, 1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* language, 1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t languageCapacity, 1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* uloc_getLanguage will return a 2 character iso-639 code if one exists. *CWB*/ 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (err==NULL || U_FAILURE(*err)) { 1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 197564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(localeID==NULL) { 1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID=uloc_getDefault(); 1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i=ulocimp_getLanguage(localeID, language, languageCapacity, NULL); 1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(language, languageCapacity, i, err); 1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getScript(const char* localeID, 1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* script, 1987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t scriptCapacity, 1988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* err) 1989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 1991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(localeID==NULL) { 1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID=uloc_getDefault(); 1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip the language */ 200150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ulocimp_getLanguage(localeID, NULL, 0, &localeID); 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDSeparator(*localeID)) { 200350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i=ulocimp_getScript(localeID+1, script, scriptCapacity, NULL); 2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(script, scriptCapacity, i, err); 2006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getCountry(const char* localeID, 2010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* country, 2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t countryCapacity, 201264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode* err) 2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(localeID==NULL) { 2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID=uloc_getDefault(); 2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the language */ 202550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ulocimp_getLanguage(localeID, NULL, 0, &localeID); 2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDSeparator(*localeID)) { 2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *scriptID; 2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the script if available */ 202950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ulocimp_getScript(localeID+1, NULL, 0, &scriptID); 2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(scriptID != localeID+1) { 2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Found optional script */ 2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID = scriptID; 2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(_isIDSeparator(*localeID)) { 203550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i=ulocimp_getCountry(localeID+1, country, countryCapacity, NULL); 2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(country, countryCapacity, i, err); 2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getVariant(const char* localeID, 2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* variant, 2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t variantCapacity, 204564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode* err) 2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 204727f654740f2a26ad62a5c155af9199af9e69b889claireho char tempBuffer[ULOC_FULLNAME_CAPACITY]; 204827f654740f2a26ad62a5c155af9199af9e69b889claireho const char* tmpLocaleID; 2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 205064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 2051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 205464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 205527f654740f2a26ad62a5c155af9199af9e69b889claireho if (_hasBCP47Extension(localeID)) { 205627f654740f2a26ad62a5c155af9199af9e69b889claireho _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), err); 205727f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 205827f654740f2a26ad62a5c155af9199af9e69b889claireho if (localeID==NULL) { 205927f654740f2a26ad62a5c155af9199af9e69b889claireho localeID=uloc_getDefault(); 206027f654740f2a26ad62a5c155af9199af9e69b889claireho } 206127f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID=localeID; 2062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 206364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 2064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the language */ 206527f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getLanguage(tmpLocaleID, NULL, 0, &tmpLocaleID); 206627f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 2067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *scriptID; 2068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the script if available */ 206927f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getScript(tmpLocaleID+1, NULL, 0, &scriptID); 207027f654740f2a26ad62a5c155af9199af9e69b889claireho if(scriptID != tmpLocaleID+1) { 2071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Found optional script */ 207227f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = scriptID; 2073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Skip the Country */ 207527f654740f2a26ad62a5c155af9199af9e69b889claireho if (_isIDSeparator(*tmpLocaleID)) { 207650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *cntryID; 207727f654740f2a26ad62a5c155af9199af9e69b889claireho ulocimp_getCountry(tmpLocaleID+1, NULL, 0, &cntryID); 207827f654740f2a26ad62a5c155af9199af9e69b889claireho if (cntryID != tmpLocaleID+1) { 207950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Found optional country */ 208027f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID = cntryID; 208150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 208227f654740f2a26ad62a5c155af9199af9e69b889claireho if(_isIDSeparator(*tmpLocaleID)) { 208327f654740f2a26ad62a5c155af9199af9e69b889claireho /* If there was no country ID, skip a possible extra IDSeparator */ 208427f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpLocaleID != cntryID && _isIDSeparator(tmpLocaleID[1])) { 208527f654740f2a26ad62a5c155af9199af9e69b889claireho tmpLocaleID++; 208627f654740f2a26ad62a5c155af9199af9e69b889claireho } 208727f654740f2a26ad62a5c155af9199af9e69b889claireho i=_getVariant(tmpLocaleID+1, *tmpLocaleID, variant, variantCapacity); 2088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 209164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 2092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* removed by weiv. We don't want to handle POSIX variants anymore. Use canonicalization function */ 2093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if we do not have a variant tag yet then try a POSIX variant after '@' */ 2094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!haveVariant && (localeID=uprv_strrchr(localeID, '@'))!=NULL) { 2096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=_getVariant(localeID+1, '@', variant, variantCapacity); 2097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(variant, variantCapacity, i, err); 2100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getName(const char* localeID, 2104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* name, 2105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nameCapacity, 210664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode* err) 2107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _canonicalize(localeID, name, nameCapacity, 0, err); 2109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getBaseName(const char* localeID, 2113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* name, 2114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nameCapacity, 211564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode* err) 2116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _canonicalize(localeID, name, nameCapacity, _ULOC_STRIP_KEYWORDS, err); 2118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_canonicalize(const char* localeID, 2122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char* name, 2123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nameCapacity, 212464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode* err) 2125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return _canonicalize(localeID, name, nameCapacity, _ULOC_CANONICALIZE, err); 2127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 212864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 2129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 213064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertuloc_getISO3Language(const char* localeID) 2131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int16_t offset; 2133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char lang[ULOC_LANG_CAPACITY]; 2134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 213564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 2136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (localeID == NULL) 2137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID = uloc_getDefault(); 2139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getLanguage(localeID, lang, ULOC_LANG_CAPACITY, &err); 2141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(err)) 2142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ""; 2143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = _findIndex(LANGUAGES, lang); 2144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset < 0) 2145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ""; 2146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return LANGUAGES_3[offset]; 2147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 215064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertuloc_getISO3Country(const char* localeID) 2151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int16_t offset; 2153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cntry[ULOC_LANG_CAPACITY]; 2154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 215564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 2156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (localeID == NULL) 2157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeID = uloc_getDefault(); 2159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getCountry(localeID, cntry, ULOC_LANG_CAPACITY, &err); 2161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(err)) 2162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ""; 2163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = _findIndex(COUNTRIES, cntry); 2164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (offset < 0) 2165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ""; 216664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 2167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return COUNTRIES_3[offset]; 2168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI uint32_t U_EXPORT2 217164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertuloc_getLCID(const char* localeID) 2172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 2174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char langID[ULOC_FULLNAME_CAPACITY]; 21750596faeddefbf198de137d5e893708495ab1584cFredrik Roubert uint32_t lcid = 0; 21760596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 21770596faeddefbf198de137d5e893708495ab1584cFredrik Roubert /* Check for incomplete id. */ 21780596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (!localeID || uprv_strlen(localeID) < 2) { 21790596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return 0; 21800596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 21810596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 21820596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // Attempt platform lookup if available 21830596faeddefbf198de137d5e893708495ab1584cFredrik Roubert lcid = uprv_convertToLCIDPlatform(localeID); 21840596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (lcid > 0) 21850596faeddefbf198de137d5e893708495ab1584cFredrik Roubert { 21860596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // Windows found an LCID, return that 21870596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return lcid; 21880596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 2189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getLanguage(localeID, langID, sizeof(langID), &status); 2191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 2192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 219559d709d503bab6e2b61931737e662dd293b40578ccornelius if (uprv_strchr(localeID, '@')) { 219659d709d503bab6e2b61931737e662dd293b40578ccornelius // uprv_convertToLCID does not support keywords other than collation. 219759d709d503bab6e2b61931737e662dd293b40578ccornelius // Remove all keywords except collation. 219859d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t len; 219959d709d503bab6e2b61931737e662dd293b40578ccornelius char collVal[ULOC_KEYWORDS_CAPACITY]; 220059d709d503bab6e2b61931737e662dd293b40578ccornelius char tmpLocaleID[ULOC_FULLNAME_CAPACITY]; 220159d709d503bab6e2b61931737e662dd293b40578ccornelius 220259d709d503bab6e2b61931737e662dd293b40578ccornelius len = uloc_getKeywordValue(localeID, "collation", collVal, 22038de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert UPRV_LENGTHOF(collVal) - 1, &status); 220459d709d503bab6e2b61931737e662dd293b40578ccornelius 220559d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_SUCCESS(status) && len > 0) { 220659d709d503bab6e2b61931737e662dd293b40578ccornelius collVal[len] = 0; 220759d709d503bab6e2b61931737e662dd293b40578ccornelius 220859d709d503bab6e2b61931737e662dd293b40578ccornelius len = uloc_getBaseName(localeID, tmpLocaleID, 22098de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert UPRV_LENGTHOF(tmpLocaleID) - 1, &status); 221059d709d503bab6e2b61931737e662dd293b40578ccornelius 22118de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert if (U_SUCCESS(status) && len > 0) { 221259d709d503bab6e2b61931737e662dd293b40578ccornelius tmpLocaleID[len] = 0; 221359d709d503bab6e2b61931737e662dd293b40578ccornelius 221459d709d503bab6e2b61931737e662dd293b40578ccornelius len = uloc_setKeywordValue("collation", collVal, tmpLocaleID, 22158de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert UPRV_LENGTHOF(tmpLocaleID) - len - 1, &status); 221659d709d503bab6e2b61931737e662dd293b40578ccornelius 22178de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert if (U_SUCCESS(status) && len > 0) { 221859d709d503bab6e2b61931737e662dd293b40578ccornelius tmpLocaleID[len] = 0; 221959d709d503bab6e2b61931737e662dd293b40578ccornelius return uprv_convertToLCID(langID, tmpLocaleID, &status); 222059d709d503bab6e2b61931737e662dd293b40578ccornelius } 222159d709d503bab6e2b61931737e662dd293b40578ccornelius } 222259d709d503bab6e2b61931737e662dd293b40578ccornelius } 222359d709d503bab6e2b61931737e662dd293b40578ccornelius 222459d709d503bab6e2b61931737e662dd293b40578ccornelius // fall through - all keywords are simply ignored 222559d709d503bab6e2b61931737e662dd293b40578ccornelius status = U_ZERO_ERROR; 222659d709d503bab6e2b61931737e662dd293b40578ccornelius } 222759d709d503bab6e2b61931737e662dd293b40578ccornelius 2228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_convertToLCID(langID, localeID, &status); 2229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getLocaleForLCID(uint32_t hostid, char *locale, int32_t localeCapacity, 2233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 2234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 223559d709d503bab6e2b61931737e662dd293b40578ccornelius return uprv_convertToPosix(hostid, locale, localeCapacity, status); 2236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ### Default locale **************************************************/ 2239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 2241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_getDefault() 2242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return locale_get_default(); 2244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 2247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_setDefault(const char* newDefaultLocale, 224864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode* err) 2249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*err)) 2251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the error code isn't currently used for anything by this function*/ 225364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 2254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* propagate change to C++ */ 2255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru locale_set_default(newDefaultLocale); 2256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 22598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * Returns a list of all 2-letter language codes defined in ISO 639. This is a pointer 2260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to an array of pointers to arrays of char. All of these pointers are owned 2261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * by ICU-- do not delete them, and do not write through them. The array is 2262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * terminated with a null pointer. 2263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* const* U_EXPORT2 226564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertuloc_getISOLanguages() 2266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return LANGUAGES; 2268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns a list of all 2-letter country codes defined in ISO 639. This is a 2272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * pointer to an array of pointers to arrays of char. All of these pointers are 2273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * owned by ICU-- do not delete them, and do not write through them. The array is 2274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * terminated with a null pointer. 2275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* const* U_EXPORT2 227764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertuloc_getISOCountries() 2278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return COUNTRIES; 2280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* this function to be moved into cstring.c later */ 2284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char gDecimal = 0; 2285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic /* U_CAPI */ 2287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querudouble 2288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* U_EXPORT2 */ 2289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_uloc_strtod(const char *start, char **end) { 2290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *decimal; 2291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *myEnd; 2292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buf[30]; 2293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double rv; 2294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!gDecimal) { 2295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char rep[5]; 2296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* For machines that decide to change the decimal on you, 2297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru and try to be too smart with localization. 2298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru This normally should be just a '.'. */ 2299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sprintf(rep, "%+1.1f", 1.0); 2300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gDecimal = rep[2]; 2301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(gDecimal == '.') { 2304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_strtod(start, end); /* fall through to OS */ 2305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(buf, start, 29); 2307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf[29]=0; 2308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru decimal = uprv_strchr(buf, '.'); 2309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(decimal) { 2310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *decimal = gDecimal; 2311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_strtod(start, end); /* no decimal point */ 2313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rv = uprv_strtod(buf, &myEnd); 2315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(end) { 2316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *end = (char*)(start+(myEnd-buf)); /* cast away const (to follow uprv_strtod API.) */ 2317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return rv; 2319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 232264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Rouberttypedef struct { 2323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru float q; 2324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dummy; /* to avoid uninitialized memory copy from qsort */ 232564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert char locale[ULOC_FULLNAME_CAPACITY+1]; 2326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} _acceptLangItem; 2327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 2329103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuloc_acceptLanguageCompare(const void * /*context*/, const void *a, const void *b) 2330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const _acceptLangItem *aa = (const _acceptLangItem*)a; 2332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const _acceptLangItem *bb = (const _acceptLangItem*)b; 2333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rc = 0; 2335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bb->q < aa->q) { 2336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = -1; /* A > B */ 2337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(bb->q > aa->q) { 2338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = 1; /* A < B */ 2339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = 0; /* A = B */ 2341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(rc==0) { 2344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc = uprv_stricmp(aa->locale, bb->locale); 2345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 234864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert /* fprintf(stderr, "a:[%s:%g], b:[%s:%g] -> %d\n", 234964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert aa->locale, aa->q, 2350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bb->locale, bb->q, 2351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rc);*/ 2352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return rc; 2355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 235764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert/* 2358b13da9df870a61b11249bf741347908dbea0edd8Jean-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 2359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult *outResult, 2363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *httpAcceptLanguage, 2364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumeration* availableLocales, 2365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 2366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 236764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert MaybeStackArray<_acceptLangItem, 4> items; // Struct for collecting items. 2368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char tmp[ULOC_FULLNAME_CAPACITY +1]; 2369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t n = 0; 2370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *itemEnd; 2371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *paramEnd; 2372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s; 2373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *t; 2374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t res; 2375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 2376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t l = (int32_t)uprv_strlen(httpAcceptLanguage); 2377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 2379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(s=httpAcceptLanguage;s&&*s;) { 2383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(isspace(*s)) /* eat space at the beginning */ 2384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s++; 2385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemEnd=uprv_strchr(s,','); 2386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru paramEnd=uprv_strchr(s,';'); 2387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!itemEnd) { 2388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemEnd = httpAcceptLanguage+l; /* end of string */ 2389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 239064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(paramEnd && paramEnd<itemEnd) { 2391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* semicolon (;) is closer than end (,) */ 2392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t = paramEnd+1; 2393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*t=='q') { 2394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t++; 2395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(isspace(*t)) { 2397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t++; 2398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*t=='=') { 2400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t++; 2401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(isspace(*t)) { 2403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t++; 2404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 240564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items[n].q = (float)_uloc_strtod(t,NULL); 2406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no semicolon - it's 1.0 */ 240864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items[n].q = 1.0f; 2409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru paramEnd = itemEnd; 2410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 241164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items[n].dummy=0; 2412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* eat spaces prior to semi */ 2413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(t=(paramEnd-1);(paramEnd>s)&&isspace(*t);t--) 2414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ; 241564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert int32_t slen = ((t+1)-s); 241664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(slen > ULOC_FULLNAME_CAPACITY) { 241764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert *status = U_BUFFER_OVERFLOW_ERROR; 241864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return -1; // too big 241964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 242064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert uprv_strncpy(items[n].locale, s, slen); 242164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items[n].locale[slen]=0; // terminate 242264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert int32_t clen = uloc_canonicalize(items[n].locale, tmp, UPRV_LENGTHOF(tmp)-1, status); 242364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(U_FAILURE(*status)) return -1; 242464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if((clen!=slen) || (uprv_strncmp(items[n].locale, tmp, slen))) { 242564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert // canonicalization had an effect- copy back 242664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert uprv_strncpy(items[n].locale, tmp, clen); 242764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items[n].locale[clen] = 0; // terminate 2428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*fprintf(stderr,"%d: s <%s> q <%g>\n", n, j[n].locale, j[n].q);*/ 2431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru n++; 2433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s = itemEnd; 2434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*s==',') { /* eat duplicate commas */ 2435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s++; 2436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 243764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(n>=items.getCapacity()) { // If we need more items 243864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(NULL == items.resize(items.getCapacity()*2, items.getCapacity())) { 243964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert *status = U_MEMORY_ALLOCATION_ERROR; 244064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return -1; 244164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 2442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 244364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert fprintf(stderr,"malloced at size %d\n", items.getCapacity()); 2444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 244764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert uprv_sortArray(items.getAlias(), n, sizeof(items[0]), uloc_acceptLanguageCompare, NULL, TRUE, status); 244864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if (U_FAILURE(*status)) { 2449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 245164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert LocalMemory<const char*> strs(NULL); 245264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if (strs.allocateInsteadAndReset(n) == NULL) { 2453c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 2454c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return -1; 2455c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 2456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<n;i++) { 2457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*fprintf(stderr,"%d: s <%s> q <%g>\n", i, j[i].locale, j[i].q);*/ 2459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 246064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert strs[i]=items[i].locale; 2461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 246264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert res = uloc_acceptLanguage(result, resultAvailable, outResult, 246364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert strs.getAlias(), n, availableLocales, status); 2464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 2465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 246964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertuloc_acceptLanguage(char *result, int32_t resultAvailable, 2470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UAcceptResult *outResult, const char **acceptList, 2471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t acceptListCount, 2472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumeration* availableLocales, 2473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 2474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i,j; 2476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len; 2477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t maxLen=0; 2478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char tmp[ULOC_FULLNAME_CAPACITY+1]; 2479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *l; 2480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char **fallbackList; 2481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 2482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 248454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius fallbackList = static_cast<char **>(uprv_malloc((size_t)(sizeof(fallbackList[0])*acceptListCount))); 2485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fallbackList==NULL) { 2486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 2487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<acceptListCount;i++) { 2490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr,"%02d: %s\n", i, acceptList[i]); 2492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2493ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert while((l=uenum_next(availableLocales, NULL, status)) != NULL) { 2494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr," %s\n", l); 2496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (int32_t)uprv_strlen(l); 2498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!uprv_strcmp(acceptList[i], l)) { 249964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(outResult) { 2500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *outResult = ULOC_ACCEPT_VALID; 2501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "MATCH! %s\n", l); 2504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len>0) { 2506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(result, l, uprv_min(len, resultAvailable)); 2507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=0;j<i;j++) { 2509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[j]); 2510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList); 251264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return u_terminateChars(result, resultAvailable, len, status); 2513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len>maxLen) { 2515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxLen = len; 2516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 251864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert uenum_reset(availableLocales, status); 2519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* save off parent info */ 25208de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert if(uloc_getParent(acceptList[i], tmp, UPRV_LENGTHOF(tmp), status)!=0) { 2521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fallbackList[i] = uprv_strdup(tmp); 2522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fallbackList[i]=0; 2524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(maxLen--;maxLen>0;maxLen--) { 2528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<acceptListCount;i++) { 2529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fallbackList[i] && ((int32_t)uprv_strlen(fallbackList[i])==maxLen)) { 2530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr,"Try: [%s]", fallbackList[i]); 2532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2533ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert while((l=uenum_next(availableLocales, NULL, status)) != NULL) { 2534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr," %s\n", l); 2536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (int32_t)uprv_strlen(l); 2538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!uprv_strcmp(fallbackList[i], l)) { 253964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(outResult) { 2540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *outResult = ULOC_ACCEPT_FALLBACK; 2541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(ULOC_DEBUG) 2543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "fallback MATCH! %s\n", l); 2544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len>0) { 2546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(result, l, uprv_min(len, resultAvailable)); 2547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=0;j<acceptListCount;j++) { 2549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[j]); 2550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList); 2552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(result, resultAvailable, len, status); 2553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 255564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert uenum_reset(availableLocales, status); 2556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 25578de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert if(uloc_getParent(fallbackList[i], tmp, UPRV_LENGTHOF(tmp), status)!=0) { 2558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[i]); 2559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fallbackList[i] = uprv_strdup(tmp); 2560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[i]); 2562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fallbackList[i]=0; 2563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 256664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(outResult) { 2567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *outResult = ULOC_ACCEPT_FAILED; 2568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<acceptListCount;i++) { 2571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList[i]); 2572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fallbackList); 2574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2577f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CAPI const char* U_EXPORT2 2578f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusuloc_toUnicodeLocaleKey(const char* keyword) 2579f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius{ 2580f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char* bcpKey = ulocimp_toBcpKey(keyword); 2581f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (bcpKey == NULL && ultag_isUnicodeLocaleKey(keyword, -1)) { 2582f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // unknown keyword, but syntax is fine.. 2583f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return keyword; 2584f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2585f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return bcpKey; 2586f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 2587f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 2588f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CAPI const char* U_EXPORT2 2589f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusuloc_toUnicodeLocaleType(const char* keyword, const char* value) 2590f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius{ 2591f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char* bcpType = ulocimp_toBcpType(keyword, value, NULL, NULL); 2592f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (bcpType == NULL && ultag_isUnicodeLocaleType(value, -1)) { 2593f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // unknown keyword, but syntax is fine.. 2594f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return value; 2595f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2596f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return bcpType; 2597f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 2598f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 2599f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UBool 2600f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusisWellFormedLegacyKey(const char* legacyKey) 2601f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius{ 2602f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char* p = legacyKey; 2603f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius while (*p) { 2604f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (!UPRV_ISALPHANUM(*p)) { 2605f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return FALSE; 2606f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2607f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius p++; 2608f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2609f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TRUE; 2610f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 2611f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 2612f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UBool 2613f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusisWellFormedLegacyType(const char* legacyType) 2614f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius{ 2615f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char* p = legacyType; 2616f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t alphaNumLen = 0; 2617f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius while (*p) { 2618f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (*p == '_' || *p == '/' || *p == '-') { 2619f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (alphaNumLen == 0) { 2620f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return FALSE; 2621f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2622f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius alphaNumLen = 0; 2623f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else if (UPRV_ISALPHANUM(*p)) { 2624f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius alphaNumLen++; 2625f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 2626f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return FALSE; 2627f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2628f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius p++; 2629f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2630f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return (alphaNumLen != 0); 2631f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 2632f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 2633f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CAPI const char* U_EXPORT2 2634f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusuloc_toLegacyKey(const char* keyword) 2635f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius{ 2636f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char* legacyKey = ulocimp_toLegacyKey(keyword); 2637f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (legacyKey == NULL) { 2638f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Checks if the specified locale key is well-formed with the legacy locale syntax. 2639f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // 2640f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Note: 26410596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // LDML/CLDR provides some definition of keyword syntax in 26420596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier and 26430596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // * http://www.unicode.org/reports/tr35/#Old_Locale_Extension_Syntax 26440596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // Keys can only consist of [0-9a-zA-Z]. 2645f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (isWellFormedLegacyKey(keyword)) { 2646f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return keyword; 2647f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2648f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2649f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return legacyKey; 2650f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 2651f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 2652f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CAPI const char* U_EXPORT2 2653f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusuloc_toLegacyType(const char* keyword, const char* value) 2654f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius{ 2655f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char* legacyType = ulocimp_toLegacyType(keyword, value, NULL, NULL); 2656f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (legacyType == NULL) { 2657f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Checks if the specified locale type is well-formed with the legacy locale syntax. 2658f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // 2659f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Note: 26600596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // LDML/CLDR provides some definition of keyword syntax in 26610596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier and 26620596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // * http://www.unicode.org/reports/tr35/#Old_Locale_Extension_Syntax 26630596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // Values (types) can only consist of [0-9a-zA-Z], plus for legacy values 26640596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // we allow [/_-+] in the middle (e.g. "Etc/GMT+1", "Asia/Tel_Aviv") 2665f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (isWellFormedLegacyType(value)) { 2666f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return value; 2667f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2668f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2669f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return legacyType; 2670f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 2671f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 2672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*eof*/ 2673