]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/cloctst.c
ICU-64260.0.1.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cloctst.c
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
b75a7d8f
A
3/********************************************************************
4 * COPYRIGHT:
a961784b 5 * Copyright (c) 1997-2016, International Business Machines Corporation and
b75a7d8f
A
6 * others. All Rights Reserved.
7 ********************************************************************/
46f4442e 8/*****************************************************************************
b75a7d8f
A
9*
10* File CLOCTST.C
11*
12* Modification History:
13* Name Description
14* Madhu Katragadda Ported for C API
46f4442e 15******************************************************************************
b75a7d8f 16*/
374ca955 17#include "cloctst.h"
b75a7d8f
A
18#include <stdlib.h>
19#include <stdio.h>
20#include <string.h>
b75a7d8f 21#include "cintltst.h"
2ca993e8 22#include "cmemory.h"
b75a7d8f 23#include "cstring.h"
73c04bcf
A
24#include "uparse.h"
25#include "uresimp.h"
3d1f044b 26#include "uassert.h"
b331163b 27#include "cmemory.h"
b75a7d8f 28
374ca955
A
29#include "unicode/putil.h"
30#include "unicode/ubrk.h"
31#include "unicode/uchar.h"
32#include "unicode/ucol.h"
33#include "unicode/udat.h"
34#include "unicode/uloc.h"
35#include "unicode/umsg.h"
36#include "unicode/ures.h"
37#include "unicode/uset.h"
38#include "unicode/ustring.h"
39#include "unicode/utypes.h"
40#include "unicode/ulocdata.h"
57a6839d 41#include "unicode/uldnames.h"
374ca955 42#include "unicode/parseerr.h" /* may not be included with some uconfig switches */
729e4ab9 43#include "udbgutil.h"
4f1e1a09 44#if !U_PLATFORM_HAS_WIN32_API
b331163b 45#include "unicode/ualoc.h" /* Apple-specific */
4f1e1a09 46#endif
b75a7d8f 47
b75a7d8f 48static void TestNullDefault(void);
374ca955 49static void TestNonexistentLanguageExemplars(void);
46f4442e 50static void TestLocDataErrorCodeChaining(void);
2ca993e8 51static void TestLocDataWithRgTag(void);
73c04bcf 52static void TestLanguageExemplarsFallbacks(void);
57a6839d 53static void TestDisplayNameBrackets(void);
73c04bcf 54
729e4ab9
A
55static void TestUnicodeDefines(void);
56
b331163b 57static void TestIsRightToLeft(void);
f3c0d7a5 58static void TestBadLocaleIDs(void);
3d1f044b
A
59static void TestBug20370(void);
60static void TestBug20321UnicodeLocaleKey(void);
b331163b 61
f3c0d7a5 62static void TestUldnNameVariants(void);
3d1f044b 63static void TestRootUndEmpty(void);
4f1e1a09 64#if !U_PLATFORM_HAS_WIN32_API
b331163b 65static void TestGetLanguagesForRegion(void);
08b89b0a 66static void TestGetAppleParent(void);
b331163b 67static void TestAppleLocalizationsToUse(void);
4f1e1a09 68#endif
08b89b0a 69
b75a7d8f
A
70void PrintDataTable();
71
72/*---------------------------------------------------
73 table of valid data
74 --------------------------------------------------- */
374ca955
A
75#define LOCALE_SIZE 9
76#define LOCALE_INFO_SIZE 28
b75a7d8f 77
46f4442e 78static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = {
b75a7d8f 79 /* language code */
374ca955
A
80 { "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" },
81 /* script code */
729e4ab9 82 { "", "", "", "", "", "", "", "", "" },
b75a7d8f 83 /* country code */
374ca955 84 { "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" },
b75a7d8f 85 /* variant code */
374ca955 86 { "", "", "", "", "NY", "", "", "", "" },
b75a7d8f 87 /* full name */
374ca955
A
88 { "en_US", "fr_FR", "ca_ES",
89 "el_GR", "no_NO_NY", "zh_Hans_CN",
90 "de_DE@collation=phonebook", "es@collation=traditional", "ja_JP@calendar=japanese" },
b75a7d8f 91 /* ISO-3 language */
374ca955 92 { "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" },
b75a7d8f 93 /* ISO-3 country */
374ca955
A
94 { "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" },
95 /* LCID */
73c04bcf 96 { "409", "40c", "403", "408", "814", "804", "10407", "40a", "411" },
b75a7d8f
A
97
98 /* display language (English) */
374ca955
A
99 { "English", "French", "Catalan", "Greek", "Norwegian", "Chinese", "German", "Spanish", "Japanese" },
100 /* display script code (English) */
101 { "", "", "", "", "", "Simplified Han", "", "", "" },
b75a7d8f 102 /* display country (English) */
4f1e1a09 103 { "United States", "France", "Spain", "Greece", "Norway", "China mainland", "Germany", "", "Japan" },
b75a7d8f 104 /* display variant (English) */
374ca955 105 { "", "", "", "", "NY", "", "", "", "" },
b75a7d8f 106 /* display name (English) */
374ca955 107 { "English (United States)", "French (France)", "Catalan (Spain)",
3d1f044b 108 "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese, Simplified (China mainland)",
4388f060 109 "German (Germany, Sort Order=Phonebook Sort Order)", "Spanish (Sort Order=Traditional Sort Order)", "Japanese (Japan, Calendar=Japanese Calendar)" },
b75a7d8f
A
110
111 /* display language (French) */
374ca955
A
112 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "chinois", "allemand", "espagnol", "japonais" },
113 /* display script code (French) */
57a6839d 114 { "", "", "", "", "", "sinogrammes simplifi\\u00e9s", "", "", "" },
b75a7d8f 115 /* display country (French) */
4f1e1a09 116 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine continentale", "Allemagne", "", "Japon" },
b75a7d8f 117 /* display variant (French) */
374ca955 118 { "", "", "", "", "NY", "", "", "", "" },
b75a7d8f 119 /* display name (French) */
374ca955 120 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)",
3d1f044b 121 "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois simplifi\\u00e9 (Chine continentale)",
b331163b 122 "allemand (Allemagne, ordre de tri=ordre de l\\u2019annuaire)", "espagnol (ordre de tri=ordre traditionnel)", "japonais (Japon, calendrier=calendrier japonais)" },
374ca955
A
123
124 /* display language (Catalan) */
46f4442e 125 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "xin\\u00E8s", "alemany", "espanyol", "japon\\u00E8s" },
374ca955 126 /* display script code (Catalan) */
57a6839d 127 { "", "", "", "", "", "han simplificat", "", "", "" },
374ca955 128 /* display country (Catalan) */
4f1e1a09 129 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina continental", "Alemanya", "", "Jap\\u00F3" },
374ca955
A
130 /* display variant (Catalan) */
131 { "", "", "", "", "NY", "", "", "", "" },
132 /* display name (Catalan) */
133 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)",
3d1f044b 134 "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E8s simplificat (Xina continental)",
57a6839d 135 "alemany (Alemanya, ordenaci\\u00F3=ordre de la guia telef\\u00F2nica)", "espanyol (ordenaci\\u00F3=ordre tradicional)", "japon\\u00E8s (Jap\\u00F3, calendari=calendari japon\\u00e8s)" },
b75a7d8f
A
136
137 /* display language (Greek) */
138 {
139 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
140 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
374ca955
A
141 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
142 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
143 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
144 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC",
145 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
146 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
147 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC"
b75a7d8f 148 },
374ca955 149 /* display script code (Greek) */
46f4442e 150
57a6839d 151 { "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd", "", "", "" },
b75a7d8f
A
152 /* display country (Greek) */
153 {
57a6839d 154 "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
b75a7d8f 155 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
374ca955 156 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
b75a7d8f 157 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
374ca955 158 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
4f1e1a09 159 "\\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE",
374ca955
A
160 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1",
161 "",
162 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
b75a7d8f
A
163 },
164 /* display variant (Greek) */
374ca955 165 { "", "", "", "", "NY", "", "", "", "" }, /* TODO: currently there is no translation for NY in Greek fix this test when we have it */
b75a7d8f
A
166 /* display name (Greek) */
167 {
57a6839d 168 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
b75a7d8f 169 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
374ca955
A
170 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
171 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
57a6839d 172 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
3d1f044b 173 "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1 \\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE)",
57a6839d 174 "\\u0393\\u03b5\\u03c1\\u03bc\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0393\\u03b5\\u03c1\\u03bc\\u03b1\\u03bd\\u03af\\u03b1, \\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2 \\u03c4\\u03b7\\u03bb\\u03b5\\u03c6\\u03c9\\u03bd\\u03b9\\u03ba\\u03bf\\u03cd \\u03ba\\u03b1\\u03c4\\u03b1\\u03bb\\u03cc\\u03b3\\u03bf\\u03c5)",
51004dcb 175 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a0\\u03b1\\u03c1\\u03b1\\u03b4\\u03bf\\u03c3\\u03b9\\u03b1\\u03ba\\u03ae \\u03c3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2)",
57a6839d 176 "\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03af\\u03b1, \\u0397\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf=\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03cc \\u03b7\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf)"
b75a7d8f
A
177 }
178};
179
180static UChar*** dataTable=0;
181enum {
182 ENGLISH = 0,
183 FRENCH = 1,
374ca955 184 CATALAN = 2,
b75a7d8f
A
185 GREEK = 3,
186 NORWEGIAN = 4
187};
188
189enum {
190 LANG = 0,
374ca955
A
191 SCRIPT = 1,
192 CTRY = 2,
193 VAR = 3,
194 NAME = 4,
195 LANG3 = 5,
196 CTRY3 = 6,
197 LCID = 7,
198 DLANG_EN = 8,
199 DSCRIPT_EN = 9,
200 DCTRY_EN = 10,
201 DVAR_EN = 11,
202 DNAME_EN = 12,
203 DLANG_FR = 13,
204 DSCRIPT_FR = 14,
205 DCTRY_FR = 15,
206 DVAR_FR = 16,
207 DNAME_FR = 17,
208 DLANG_CA = 18,
209 DSCRIPT_CA = 19,
210 DCTRY_CA = 20,
211 DVAR_CA = 21,
212 DNAME_CA = 22,
213 DLANG_EL = 23,
214 DSCRIPT_EL = 24,
215 DCTRY_EL = 25,
216 DVAR_EL = 26,
217 DNAME_EL = 27
b75a7d8f
A
218};
219
374ca955
A
220#define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
221
b75a7d8f
A
222void addLocaleTest(TestNode** root);
223
224void addLocaleTest(TestNode** root)
225{
374ca955
A
226 TESTCASE(TestObsoleteNames); /* srl- move */
227 TESTCASE(TestBasicGetters);
228 TESTCASE(TestNullDefault);
229 TESTCASE(TestPrefixes);
230 TESTCASE(TestSimpleResourceInfo);
231 TESTCASE(TestDisplayNames);
232 TESTCASE(TestGetAvailableLocales);
233 TESTCASE(TestDataDirectory);
729e4ab9 234#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
374ca955 235 TESTCASE(TestISOFunctions);
729e4ab9 236#endif
374ca955
A
237 TESTCASE(TestISO3Fallback);
238 TESTCASE(TestUninstalledISO3Names);
239 TESTCASE(TestSimpleDisplayNames);
240 TESTCASE(TestVariantParsing);
374ca955
A
241 TESTCASE(TestKeywordVariants);
242 TESTCASE(TestKeywordVariantParsing);
243 TESTCASE(TestCanonicalization);
3d1f044b 244 TESTCASE(TestCanonicalizationBuffer);
374ca955
A
245 TESTCASE(TestKeywordSet);
246 TESTCASE(TestKeywordSetError);
247 TESTCASE(TestDisplayKeywords);
248 TESTCASE(TestDisplayKeywordValues);
249 TESTCASE(TestGetBaseName);
729e4ab9 250#if !UCONFIG_NO_FILE_IO
374ca955 251 TESTCASE(TestGetLocale);
729e4ab9 252#endif
374ca955
A
253 TESTCASE(TestDisplayNameWarning);
254 TESTCASE(TestNonexistentLanguageExemplars);
46f4442e 255 TESTCASE(TestLocDataErrorCodeChaining);
2ca993e8 256 TESTCASE(TestLocDataWithRgTag);
73c04bcf
A
257 TESTCASE(TestLanguageExemplarsFallbacks);
258 TESTCASE(TestCalendar);
259 TESTCASE(TestDateFormat);
260 TESTCASE(TestCollation);
261 TESTCASE(TestULocale);
262 TESTCASE(TestUResourceBundle);
263 TESTCASE(TestDisplayName);
264 TESTCASE(TestAcceptLanguage);
265 TESTCASE(TestGetLocaleForLCID);
46f4442e
A
266 TESTCASE(TestOrientation);
267 TESTCASE(TestLikelySubtags);
729e4ab9 268 TESTCASE(TestToLanguageTag);
3d1f044b 269 TESTCASE(TestBug20132);
729e4ab9 270 TESTCASE(TestForLanguageTag);
3d1f044b
A
271 TESTCASE(TestInvalidLanguageTag);
272 TESTCASE(TestLangAndRegionCanonicalize);
729e4ab9
A
273 TESTCASE(TestTrailingNull);
274 TESTCASE(TestUnicodeDefines);
51004dcb 275 TESTCASE(TestEnglishExemplarCharacters);
57a6839d 276 TESTCASE(TestDisplayNameBrackets);
b331163b
A
277 TESTCASE(TestIsRightToLeft);
278 TESTCASE(TestToUnicodeLocaleKey);
279 TESTCASE(TestToLegacyKey);
280 TESTCASE(TestToUnicodeLocaleType);
281 TESTCASE(TestToLegacyType);
f3c0d7a5 282 TESTCASE(TestBadLocaleIDs);
3d1f044b
A
283 TESTCASE(TestBug20370);
284 TESTCASE(TestBug20321UnicodeLocaleKey);
2ca993e8 285 TESTCASE(TestUldnNameVariants);
3d1f044b 286 TESTCASE(TestRootUndEmpty);
4f1e1a09 287#if !U_PLATFORM_HAS_WIN32_API
b331163b 288 TESTCASE(TestGetLanguagesForRegion);
08b89b0a 289 TESTCASE(TestGetAppleParent);
b331163b 290 TESTCASE(TestAppleLocalizationsToUse);
4f1e1a09 291#endif
b75a7d8f
A
292}
293
294
295/* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
296static void TestBasicGetters() {
297 int32_t i;
298 int32_t cap;
299 UErrorCode status = U_ZERO_ERROR;
300 char *testLocale = 0;
301 char *temp = 0, *name = 0;
302 log_verbose("Testing Basic Getters\n");
303 for (i = 0; i < LOCALE_SIZE; i++) {
304 testLocale=(char*)malloc(sizeof(char) * (strlen(rawData2[NAME][i])+1));
305 strcpy(testLocale,rawData2[NAME][i]);
306
307 log_verbose("Testing %s .....\n", testLocale);
308 cap=uloc_getLanguage(testLocale, NULL, 0, &status);
309 if(status==U_BUFFER_OVERFLOW_ERROR){
310 status=U_ZERO_ERROR;
311 temp=(char*)malloc(sizeof(char) * (cap+1));
312 uloc_getLanguage(testLocale, temp, cap+1, &status);
313 }
314 if(U_FAILURE(status)){
315 log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status));
316 }
317 if (0 !=strcmp(temp,rawData2[LANG][i])) {
318 log_err(" Language code mismatch: %s versus %s\n", temp, rawData2[LANG][i]);
319 }
320
321
322 cap=uloc_getCountry(testLocale, temp, cap, &status);
323 if(status==U_BUFFER_OVERFLOW_ERROR){
324 status=U_ZERO_ERROR;
325 temp=(char*)realloc(temp, sizeof(char) * (cap+1));
326 uloc_getCountry(testLocale, temp, cap+1, &status);
327 }
328 if(U_FAILURE(status)){
329 log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status));
330 }
331 if (0 != strcmp(temp, rawData2[CTRY][i])) {
332 log_err(" Country code mismatch: %s versus %s\n", temp, rawData2[CTRY][i]);
333
334 }
335
336 cap=uloc_getVariant(testLocale, temp, cap, &status);
337 if(status==U_BUFFER_OVERFLOW_ERROR){
338 status=U_ZERO_ERROR;
339 temp=(char*)realloc(temp, sizeof(char) * (cap+1));
340 uloc_getVariant(testLocale, temp, cap+1, &status);
341 }
342 if(U_FAILURE(status)){
343 log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status));
344 }
345 if (0 != strcmp(temp, rawData2[VAR][i])) {
346 log_err("Variant code mismatch: %s versus %s\n", temp, rawData2[VAR][i]);
347 }
348
349 cap=uloc_getName(testLocale, NULL, 0, &status);
350 if(status==U_BUFFER_OVERFLOW_ERROR){
351 status=U_ZERO_ERROR;
352 name=(char*)malloc(sizeof(char) * (cap+1));
353 uloc_getName(testLocale, name, cap+1, &status);
354 } else if(status==U_ZERO_ERROR) {
355 log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale);
356 }
357 if(U_FAILURE(status)){
358 log_err("ERROR: in uloc_getName %s\n", myErrorName(status));
359 }
360 if (0 != strcmp(name, rawData2[NAME][i])){
361 log_err(" Mismatch in getName: %s versus %s\n", name, rawData2[NAME][i]);
362 }
363
b75a7d8f
A
364 free(temp);
365 free(name);
366
367 free(testLocale);
368 }
369}
370
371static void TestNullDefault() {
372 UErrorCode status = U_ZERO_ERROR;
373 char original[ULOC_FULLNAME_CAPACITY];
374
375 uprv_strcpy(original, uloc_getDefault());
376 uloc_setDefault("qq_BLA", &status);
377 if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
378 log_err(" Mismatch in uloc_setDefault: qq_BLA versus %s\n", uloc_getDefault());
379 }
380 uloc_setDefault(NULL, &status);
381 if (uprv_strcmp(uloc_getDefault(), original) != 0) {
382 log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
383 }
374ca955
A
384
385 {
386 /* Test that set & get of default locale work, and that
387 * default locales are cached and reused, and not overwritten.
388 */
389 const char *n_en_US;
390 const char *n_fr_FR;
391 const char *n2_en_US;
392
393 status = U_ZERO_ERROR;
394 uloc_setDefault("en_US", &status);
395 n_en_US = uloc_getDefault();
396 if (strcmp(n_en_US, "en_US") != 0) {
397 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US);
398 }
399
400 uloc_setDefault("fr_FR", &status);
401 n_fr_FR = uloc_getDefault();
402 if (strcmp(n_en_US, "en_US") != 0) {
403 log_err("uloc_setDefault altered previously default string."
404 "Expected \"en_US\", got \"%s\"\n", n_en_US);
405 }
406 if (strcmp(n_fr_FR, "fr_FR") != 0) {
407 log_err("Wrong result from uloc_getDefault(). Expected \"fr_FR\", got %s\n", n_fr_FR);
408 }
409
410 uloc_setDefault("en_US", &status);
411 n2_en_US = uloc_getDefault();
412 if (strcmp(n2_en_US, "en_US") != 0) {
413 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US);
414 }
415 if (n2_en_US != n_en_US) {
416 log_err("Default locale cache failed to reuse en_US locale.\n");
417 }
418
419 if (U_FAILURE(status)) {
420 log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status));
421 }
422
423 }
424
b75a7d8f
A
425}
426/* Test the i- and x- and @ and . functionality
427*/
428
429#define PREFIXBUFSIZ 128
430
431static void TestPrefixes() {
374ca955
A
432 int row = 0;
433 int n;
434 const char *loc, *expected;
435
46f4442e 436 static const char * const testData[][7] =
374ca955
A
437 {
438 /* NULL canonicalize() column means "expect same as getName()" */
439 {"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", NULL},
440 {"en", "", "GB", "", "en-gb", "en_GB", NULL},
441 {"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", NULL},
442 {"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", NULL},
443 {"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", NULL},
444 {"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", NULL},
3d1f044b 445 {"hy", "", "", "AREVMDA", "hy_AREVMDA", "hy__AREVMDA", "hyw"},
51004dcb 446 {"de", "", "", "1901", "de-1901", "de__1901", NULL},
374ca955
A
447 {"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"},
448 {"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"},
449 {"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */
450 {"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"},
451 {"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
452 {"no", "", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"},
453 {"no", "", "NO", "", "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"},
454 {"no", "", "", "NY", "no__ny", "no__NY", NULL},
455 {"no", "", "", "", "no@ny", "no@ny", "no__NY"},
456 {"el", "Latn", "", "", "el-latn", "el_Latn", NULL},
457 {"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", NULL},
374ca955
A
458 {"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", NULL},
459 {"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", NULL},
4388f060 460 {"ab", "Cdef", "GH", "IJ", "ab_cdef_gh_ij", "ab_Cdef_GH_IJ", NULL}, /* total garbage */
3d1f044b
A
461
462 // Before ICU 64, ICU locale canonicalization had some additional mappings.
463 // They were removed for ICU-20187 "drop support for long-obsolete locale ID variants".
464 // The following now use standard canonicalization.
465 {"zh", "Hans", "", "PINYIN", "zh-Hans-pinyin", "zh_Hans__PINYIN", "zh_Hans__PINYIN"},
466 {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW_STROKE"},
467
374ca955
A
468 {NULL,NULL,NULL,NULL,NULL,NULL,NULL}
469 };
470
46f4442e 471 static const char * const testTitles[] = {
374ca955
A
472 "uloc_getLanguage()",
473 "uloc_getScript()",
474 "uloc_getCountry()",
475 "uloc_getVariant()",
476 "name",
477 "uloc_getName()",
478 "uloc_canonicalize()"
479 };
480
481 char buf[PREFIXBUFSIZ];
482 int32_t len;
483 UErrorCode err;
484
485
486 for(row=0;testData[row][0] != NULL;row++) {
487 loc = testData[row][NAME];
488 log_verbose("Test #%d: %s\n", row, loc);
489
490 err = U_ZERO_ERROR;
491 len=0;
492 buf[0]=0;
493 for(n=0;n<=(NAME+2);n++) {
494 if(n==NAME) continue;
495
496 for(len=0;len<PREFIXBUFSIZ;len++) {
497 buf[len] = '%'; /* Set a tripwire.. */
498 }
499 len = 0;
500
501 switch(n) {
502 case LANG:
503 len = uloc_getLanguage(loc, buf, PREFIXBUFSIZ, &err);
504 break;
505
506 case SCRIPT:
507 len = uloc_getScript(loc, buf, PREFIXBUFSIZ, &err);
508 break;
509
510 case CTRY:
511 len = uloc_getCountry(loc, buf, PREFIXBUFSIZ, &err);
512 break;
513
514 case VAR:
515 len = uloc_getVariant(loc, buf, PREFIXBUFSIZ, &err);
516 break;
517
518 case NAME+1:
519 len = uloc_getName(loc, buf, PREFIXBUFSIZ, &err);
520 break;
521
522 case NAME+2:
523 len = uloc_canonicalize(loc, buf, PREFIXBUFSIZ, &err);
524 break;
525
526 default:
527 strcpy(buf, "**??");
528 len=4;
529 }
530
531 if(U_FAILURE(err)) {
532 log_err("#%d: %s on %s: err %s\n",
533 row, testTitles[n], loc, u_errorName(err));
534 } else {
535 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
536 row, testTitles[n], loc, buf, len);
537
538 if(len != (int32_t)strlen(buf)) {
539 log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
540 row, testTitles[n], loc, buf, len, strlen(buf)+1);
541
542 }
543
544 /* see if they smashed something */
545 if(buf[len+1] != '%') {
546 log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
547 row, testTitles[n], loc, buf, buf[len+1]);
548 }
549
550 expected = testData[row][n];
551 if (expected == NULL && n == (NAME+2)) {
552 /* NULL expected canonicalize() means "expect same as getName()" */
553 expected = testData[row][NAME+1];
554 }
555 if(strcmp(buf, expected)) {
556 log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
557 row, testTitles[n], loc, buf, expected);
558
559 }
560 }
b75a7d8f 561 }
b75a7d8f 562 }
b75a7d8f
A
563}
564
565
566/* testing uloc_getISO3Language(), uloc_getISO3Country(), */
567static void TestSimpleResourceInfo() {
568 int32_t i;
569 char* testLocale = 0;
570 UChar* expected = 0;
374ca955 571
b75a7d8f
A
572 const char* temp;
573 char temp2[20];
574 testLocale=(char*)malloc(sizeof(char) * 1);
575 expected=(UChar*)malloc(sizeof(UChar) * 1);
374ca955
A
576
577 setUpDataTable();
b75a7d8f
A
578 log_verbose("Testing getISO3Language and getISO3Country\n");
579 for (i = 0; i < LOCALE_SIZE; i++) {
374ca955 580
b75a7d8f
A
581 testLocale=(char*)realloc(testLocale, sizeof(char) * (u_strlen(dataTable[NAME][i])+1));
582 u_austrcpy(testLocale, dataTable[NAME][i]);
374ca955 583
b75a7d8f 584 log_verbose("Testing %s ......\n", testLocale);
374ca955 585
b75a7d8f
A
586 temp=uloc_getISO3Language(testLocale);
587 expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
588 u_uastrcpy(expected,temp);
589 if (0 != u_strcmp(expected, dataTable[LANG3][i])) {
374ca955
A
590 log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected),
591 austrdup(dataTable[LANG3][i]));
b75a7d8f 592 }
374ca955 593
b75a7d8f
A
594 temp=uloc_getISO3Country(testLocale);
595 expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
596 u_uastrcpy(expected,temp);
597 if (0 != u_strcmp(expected, dataTable[CTRY3][i])) {
598 log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected),
374ca955 599 austrdup(dataTable[CTRY3][i]));
b75a7d8f 600 }
374ca955 601 sprintf(temp2, "%x", (int)uloc_getLCID(testLocale));
b75a7d8f
A
602 if (strcmp(temp2, rawData2[LCID][i]) != 0) {
603 log_err("LCID mismatch: %s versus %s\n", temp2 , rawData2[LCID][i]);
604 }
b75a7d8f 605 }
374ca955
A
606
607 free(expected);
608 free(testLocale);
609 cleanUpDataTable();
b75a7d8f
A
610}
611
4388f060
A
612/* if len < 0, we convert until we hit UChar 0x0000, which is not output. will add trailing null
613 * if there's room but won't be included in result. result < 0 indicates an error.
614 * Returns the number of chars written (not those that would be written if there's enough room.*/
615static int32_t UCharsToEscapedAscii(const UChar* utext, int32_t len, char* resultChars, int32_t buflen) {
616 static const struct {
617 char escapedChar;
618 UChar sourceVal;
619 } ESCAPE_MAP[] = {
620 /*a*/ {'a', 0x07},
621 /*b*/ {'b', 0x08},
622 /*e*/ {'e', 0x1b},
623 /*f*/ {'f', 0x0c},
624 /*n*/ {'n', 0x0a},
625 /*r*/ {'r', 0x0d},
626 /*t*/ {'t', 0x09},
627 /*v*/ {'v', 0x0b}
628 };
2ca993e8 629 static const int32_t ESCAPE_MAP_LENGTH = UPRV_LENGTHOF(ESCAPE_MAP);
4388f060
A
630 static const char HEX_DIGITS[] = {
631 '0', '1', '2', '3', '4', '5', '6', '7',
632 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
633 };
634 int32_t i, j;
635 int32_t resultLen = 0;
636 const int32_t limit = len<0 ? buflen : len; /* buflen is long enough to hit the buffer limit */
637 const int32_t escapeLimit1 = buflen-2;
638 const int32_t escapeLimit2 = buflen-6;
639 UChar uc;
640
641 if(utext==NULL || resultChars==NULL || buflen<0) {
642 return -1;
643 }
644
645 for(i=0;i<limit && resultLen<buflen;++i) {
646 uc=utext[i];
647 if(len<0 && uc==0) {
648 break;
649 }
650 if(uc<0x20) {
651 for(j=0;j<ESCAPE_MAP_LENGTH && uc!=ESCAPE_MAP[j].sourceVal;j++) {
652 }
653 if(j<ESCAPE_MAP_LENGTH) {
654 if(resultLen>escapeLimit1) {
655 break;
656 }
657 resultChars[resultLen++]='\\';
658 resultChars[resultLen++]=ESCAPE_MAP[j].escapedChar;
659 continue;
660 }
661 } else if(uc<0x7f) {
662 u_austrncpy(resultChars + resultLen, &uc, 1);
663 resultLen++;
664 continue;
665 }
666
667 if(resultLen>escapeLimit2) {
668 break;
669 }
670
671 /* have to escape the uchar */
672 resultChars[resultLen++]='\\';
673 resultChars[resultLen++]='u';
674 resultChars[resultLen++]=HEX_DIGITS[(uc>>12)&0xff];
675 resultChars[resultLen++]=HEX_DIGITS[(uc>>8)&0xff];
676 resultChars[resultLen++]=HEX_DIGITS[(uc>>4)&0xff];
677 resultChars[resultLen++]=HEX_DIGITS[uc&0xff];
678 }
679
680 if(resultLen<buflen) {
681 resultChars[resultLen] = 0;
682 }
683
684 return resultLen;
685}
686
b75a7d8f
A
687/*
688 * Jitterbug 2439 -- markus 20030425
689 *
690 * The lookup of display names must not fall back through the default
691 * locale because that yields useless results.
692 */
693static void TestDisplayNames()
694{
695 UChar buffer[100];
374ca955 696 UErrorCode errorCode=U_ZERO_ERROR;
b75a7d8f 697 int32_t length;
b75a7d8f
A
698 log_verbose("Testing getDisplayName for different locales\n");
699
700 log_verbose(" In locale = en_US...\n");
701 doTestDisplayNames("en_US", DLANG_EN);
702 log_verbose(" In locale = fr_FR....\n");
703 doTestDisplayNames("fr_FR", DLANG_FR);
374ca955
A
704 log_verbose(" In locale = ca_ES...\n");
705 doTestDisplayNames("ca_ES", DLANG_CA);
b75a7d8f
A
706 log_verbose(" In locale = gr_EL..\n");
707 doTestDisplayNames("el_GR", DLANG_EL);
708
709 /* test that the default locale has a display name for its own language */
710 errorCode=U_ZERO_ERROR;
b331163b 711 length=uloc_getDisplayLanguage(NULL, NULL, buffer, UPRV_LENGTHOF(buffer), &errorCode);
b75a7d8f
A
712 if(U_FAILURE(errorCode) || (length<=3 && buffer[0]<=0x7f)) {
713 /* check <=3 to reject getting the language code as a display name */
729e4ab9 714 log_data_err("unable to get a display string for the language of the default locale - %s (Are you missing data?)\n", u_errorName(errorCode));
b75a7d8f
A
715 }
716
717 /* test that we get the language code itself for an unknown language, and a default warning */
718 errorCode=U_ZERO_ERROR;
b331163b 719 length=uloc_getDisplayLanguage("qq", "rr", buffer, UPRV_LENGTHOF(buffer), &errorCode);
b75a7d8f
A
720 if(errorCode!=U_USING_DEFAULT_WARNING || length!=2 || buffer[0]!=0x71 || buffer[1]!=0x71) {
721 log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode));
722 }
73c04bcf
A
723
724 /* test that we get a default warning for a display name where one component is unknown (4255) */
725 errorCode=U_ZERO_ERROR;
b331163b 726 length=uloc_getDisplayName("qq_US_POSIX", "en_US", buffer, UPRV_LENGTHOF(buffer), &errorCode);
73c04bcf
A
727 if(errorCode!=U_USING_DEFAULT_WARNING) {
728 log_err("error getting the display name for a locale with an unknown language - %s\n", u_errorName(errorCode));
729 }
374ca955
A
730
731 {
732 int32_t i;
46f4442e
A
733 static const char *aLocale = "es@collation=traditional;calendar=japanese";
734 static const char *testL[] = { "en_US",
374ca955
A
735 "fr_FR",
736 "ca_ES",
737 "el_GR" };
4388f060 738 static const char *expect[] = { "Spanish (Calendar=Japanese Calendar, Sort Order=Traditional Sort Order)", /* note sorted order of keywords */
b331163b 739 "espagnol (calendrier=calendrier japonais, ordre de tri=ordre traditionnel)",
57a6839d
A
740 "espanyol (calendari=calendari japon\\u00e8s, ordenaci\\u00f3=ordre tradicional)",
741 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0397\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf=\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03cc \\u03b7\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf, \\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a0\\u03b1\\u03c1\\u03b1\\u03b4\\u03bf\\u03c3\\u03b9\\u03b1\\u03ba\\u03ae \\u03c3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2)" };
374ca955
A
742 UChar *expectBuffer;
743
b331163b 744 for(i=0;i<UPRV_LENGTHOF(testL);i++) {
374ca955 745 errorCode = U_ZERO_ERROR;
b331163b 746 uloc_getDisplayName(aLocale, testL[i], buffer, UPRV_LENGTHOF(buffer), &errorCode);
374ca955
A
747 if(U_FAILURE(errorCode)) {
748 log_err("FAIL in uloc_getDisplayName(%s,%s,..) -> %s\n", aLocale, testL[i], u_errorName(errorCode));
749 } else {
750 expectBuffer = CharsToUChars(expect[i]);
751 if(u_strcmp(buffer,expectBuffer)) {
729e4ab9 752 log_data_err("FAIL in uloc_getDisplayName(%s,%s,..) expected '%s' got '%s' (Are you missing data?)\n", aLocale, testL[i], expect[i], austrdup(buffer));
374ca955
A
753 } else {
754 log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale, testL[i], expect[i]);
755 }
756 free(expectBuffer);
757 }
758 }
759 }
4388f060
A
760
761 /* test that we properly preflight and return data when there's a non-default pattern,
762 see ticket #8262. */
763 {
764 int32_t i;
765 static const char *locale="az_Cyrl";
766 static const char *displayLocale="ja";
767 static const char *expectedChars =
3d1f044b
A
768 "\\u30a2\\u30bc\\u30eb\\u30d0\\u30a4\\u30b8\\u30e3\\u30f3\\u8a9e"
769 "\\uff08\\u30ad\\u30ea\\u30eb\\u6587\\u5b57\\uff09";
4388f060
A
770 UErrorCode ec=U_ZERO_ERROR;
771 UChar result[256];
772 int32_t len;
773 int32_t preflightLen=uloc_getDisplayName(locale, displayLocale, NULL, 0, &ec);
774 /* inconvenient semantics when preflighting, this condition is expected... */
775 if(ec==U_BUFFER_OVERFLOW_ERROR) {
776 ec=U_ZERO_ERROR;
777 }
b331163b 778 len=uloc_getDisplayName(locale, displayLocale, result, UPRV_LENGTHOF(result), &ec);
4388f060
A
779 if(U_FAILURE(ec)) {
780 log_err("uloc_getDisplayName(%s, %s...) returned error: %s",
781 locale, displayLocale, u_errorName(ec));
782 } else {
783 UChar *expected=CharsToUChars(expectedChars);
784 int32_t expectedLen=u_strlen(expected);
785
786 if(len!=expectedLen) {
787 log_data_err("uloc_getDisplayName(%s, %s...) returned string of length %d, expected length %d",
788 locale, displayLocale, len, expectedLen);
789 } else if(preflightLen!=expectedLen) {
790 log_err("uloc_getDisplayName(%s, %s...) returned preflight length %d, expected length %d",
791 locale, displayLocale, preflightLen, expectedLen);
792 } else if(u_strncmp(result, expected, len)) {
793 int32_t cap=len*6+1; /* worst case + space for trailing null */
794 char* resultChars=(char*)malloc(cap);
795 int32_t resultCharsLen=UCharsToEscapedAscii(result, len, resultChars, cap);
796 if(resultCharsLen<0 || resultCharsLen<cap-1) {
797 log_err("uloc_getDisplayName(%s, %s...) mismatch", locale, displayLocale);
798 } else {
799 log_err("uloc_getDisplayName(%s, %s...) returned '%s' but expected '%s'",
800 locale, displayLocale, resultChars, expectedChars);
801 }
802 free(resultChars);
803 resultChars=NULL;
804 } else {
805 /* test all buffer sizes */
806 for(i=len+1;i>=0;--i) {
807 len=uloc_getDisplayName(locale, displayLocale, result, i, &ec);
808 if(ec==U_BUFFER_OVERFLOW_ERROR) {
809 ec=U_ZERO_ERROR;
810 }
811 if(U_FAILURE(ec)) {
812 log_err("using buffer of length %d returned error %s", i, u_errorName(ec));
813 break;
814 }
815 if(len!=expectedLen) {
816 log_err("with buffer of length %d, expected length %d but got %d", i, expectedLen, len);
817 break;
818 }
819 /* There's no guarantee about what's in the buffer if we've overflowed, in particular,
820 * we don't know that it's been filled, so no point in checking. */
821 }
822 }
823
824 free(expected);
825 }
826 }
b75a7d8f
A
827}
828
829
830/* test for uloc_getAvialable() and uloc_countAvilable()*/
831static void TestGetAvailableLocales()
832{
833
834 const char *locList;
835 int32_t locCount,i;
836
837 log_verbose("Testing the no of avialable locales\n");
838 locCount=uloc_countAvailable();
839 if (locCount == 0)
840 log_data_err("countAvailable() returned an empty list!\n");
841
842 /* use something sensible w/o hardcoding the count */
843 else if(locCount < 0){
844 log_data_err("countAvailable() returned a wrong value!= %d\n", locCount);
845 }
846 else{
847 log_info("Number of locales returned = %d\n", locCount);
848 }
849 for(i=0;i<locCount;i++){
850 locList=uloc_getAvailable(i);
851
852 log_verbose(" %s\n", locList);
853 }
854}
855
856/* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
857static void TestDataDirectory()
858{
859
860 char oldDirectory[512];
861 const char *temp,*testValue1,*testValue2,*testValue3;
862 const char path[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING; /*give the required path */
863
864 log_verbose("Testing getDataDirectory()\n");
865 temp = u_getDataDirectory();
866 strcpy(oldDirectory, temp);
867
868 testValue1=uloc_getISO3Language("en_US");
869 log_verbose("first fetch of language retrieved %s\n", testValue1);
870
871 if (0 != strcmp(testValue1,"eng")){
872 log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1);
873 }
874
875 /*defining the path for DataDirectory */
876 log_verbose("Testing setDataDirectory\n");
877 u_setDataDirectory( path );
878 if(strcmp(path, u_getDataDirectory())==0)
879 log_verbose("setDataDirectory working fine\n");
880 else
881 log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path);
882
883 testValue2=uloc_getISO3Language("en_US");
884 log_verbose("second fetch of language retrieved %s \n", testValue2);
885
886 u_setDataDirectory(oldDirectory);
887 testValue3=uloc_getISO3Language("en_US");
888 log_verbose("third fetch of language retrieved %s \n", testValue3);
889
890 if (0 != strcmp(testValue3,"eng")) {
891 log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3);
892 }
893}
894
895
896
897/*=========================================================== */
898
899static UChar _NUL=0;
900
901static void doTestDisplayNames(const char* displayLocale, int32_t compareIndex)
902{
903 UErrorCode status = U_ZERO_ERROR;
904 int32_t i;
905 int32_t maxresultsize;
906
907 const char *testLocale;
908
909
910 UChar *testLang = 0;
374ca955 911 UChar *testScript = 0;
b75a7d8f
A
912 UChar *testCtry = 0;
913 UChar *testVar = 0;
914 UChar *testName = 0;
915
916
917 UChar* expectedLang = 0;
374ca955 918 UChar* expectedScript = 0;
b75a7d8f
A
919 UChar* expectedCtry = 0;
920 UChar* expectedVar = 0;
921 UChar* expectedName = 0;
922
923setUpDataTable();
924
925 for(i=0;i<LOCALE_SIZE; ++i)
926 {
927 testLocale=rawData2[NAME][i];
928
929 log_verbose("Testing..... %s\n", testLocale);
930
931 maxresultsize=0;
932 maxresultsize=uloc_getDisplayLanguage(testLocale, displayLocale, NULL, maxresultsize, &status);
933 if(status==U_BUFFER_OVERFLOW_ERROR)
934 {
935 status=U_ZERO_ERROR;
936 testLang=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
937 uloc_getDisplayLanguage(testLocale, displayLocale, testLang, maxresultsize + 1, &status);
938 }
939 else
940 {
941 testLang=&_NUL;
942 }
943 if(U_FAILURE(status)){
944 log_err("Error in getDisplayLanguage() %s\n", myErrorName(status));
945 }
946
374ca955
A
947 maxresultsize=0;
948 maxresultsize=uloc_getDisplayScript(testLocale, displayLocale, NULL, maxresultsize, &status);
949 if(status==U_BUFFER_OVERFLOW_ERROR)
950 {
951 status=U_ZERO_ERROR;
952 testScript=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
953 uloc_getDisplayScript(testLocale, displayLocale, testScript, maxresultsize + 1, &status);
954 }
955 else
956 {
957 testScript=&_NUL;
958 }
959 if(U_FAILURE(status)){
960 log_err("Error in getDisplayScript() %s\n", myErrorName(status));
961 }
962
b75a7d8f
A
963 maxresultsize=0;
964 maxresultsize=uloc_getDisplayCountry(testLocale, displayLocale, NULL, maxresultsize, &status);
965 if(status==U_BUFFER_OVERFLOW_ERROR)
966 {
967 status=U_ZERO_ERROR;
968 testCtry=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
969 uloc_getDisplayCountry(testLocale, displayLocale, testCtry, maxresultsize + 1, &status);
970 }
971 else
972 {
973 testCtry=&_NUL;
974 }
975 if(U_FAILURE(status)){
976 log_err("Error in getDisplayCountry() %s\n", myErrorName(status));
977 }
978
979 maxresultsize=0;
980 maxresultsize=uloc_getDisplayVariant(testLocale, displayLocale, NULL, maxresultsize, &status);
981 if(status==U_BUFFER_OVERFLOW_ERROR)
982 {
983 status=U_ZERO_ERROR;
984 testVar=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
985 uloc_getDisplayVariant(testLocale, displayLocale, testVar, maxresultsize + 1, &status);
986 }
987 else
988 {
989 testVar=&_NUL;
990 }
991 if(U_FAILURE(status)){
992 log_err("Error in getDisplayVariant() %s\n", myErrorName(status));
993 }
994
995 maxresultsize=0;
996 maxresultsize=uloc_getDisplayName(testLocale, displayLocale, NULL, maxresultsize, &status);
997 if(status==U_BUFFER_OVERFLOW_ERROR)
998 {
999 status=U_ZERO_ERROR;
1000 testName=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
1001 uloc_getDisplayName(testLocale, displayLocale, testName, maxresultsize + 1, &status);
1002 }
1003 else
1004 {
1005 testName=&_NUL;
1006 }
1007 if(U_FAILURE(status)){
1008 log_err("Error in getDisplayName() %s\n", myErrorName(status));
1009 }
1010
1011 expectedLang=dataTable[compareIndex][i];
1012 if(u_strlen(expectedLang)== 0)
1013 expectedLang=dataTable[DLANG_EN][i];
1014
374ca955
A
1015 expectedScript=dataTable[compareIndex + 1][i];
1016 if(u_strlen(expectedScript)== 0)
1017 expectedScript=dataTable[DSCRIPT_EN][i];
1018
1019 expectedCtry=dataTable[compareIndex + 2][i];
b75a7d8f
A
1020 if(u_strlen(expectedCtry)== 0)
1021 expectedCtry=dataTable[DCTRY_EN][i];
1022
374ca955
A
1023 expectedVar=dataTable[compareIndex + 3][i];
1024 if(u_strlen(expectedVar)== 0)
b75a7d8f
A
1025 expectedVar=dataTable[DVAR_EN][i];
1026
374ca955 1027 expectedName=dataTable[compareIndex + 4][i];
b75a7d8f
A
1028 if(u_strlen(expectedName) == 0)
1029 expectedName=dataTable[DNAME_EN][i];
1030
1031 if (0 !=u_strcmp(testLang,expectedLang)) {
729e4ab9 1032 log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testLang), austrdup(expectedLang), displayLocale);
b75a7d8f
A
1033 }
1034
374ca955 1035 if (0 != u_strcmp(testScript,expectedScript)) {
729e4ab9 1036 log_data_err(" Display Script mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testScript), austrdup(expectedScript), displayLocale);
374ca955
A
1037 }
1038
b75a7d8f 1039 if (0 != u_strcmp(testCtry,expectedCtry)) {
729e4ab9 1040 log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testCtry), austrdup(expectedCtry), displayLocale);
b75a7d8f
A
1041 }
1042
1043 if (0 != u_strcmp(testVar,expectedVar)) {
729e4ab9 1044 log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testVar), austrdup(expectedVar), displayLocale);
b75a7d8f
A
1045 }
1046
1047 if(0 != u_strcmp(testName, expectedName)) {
729e4ab9 1048 log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testName), austrdup(expectedName), displayLocale);
b75a7d8f
A
1049 }
1050
1051 if(testName!=&_NUL) {
1052 free(testName);
1053 }
1054 if(testLang!=&_NUL) {
1055 free(testLang);
1056 }
374ca955
A
1057 if(testScript!=&_NUL) {
1058 free(testScript);
1059 }
b75a7d8f
A
1060 if(testCtry!=&_NUL) {
1061 free(testCtry);
1062 }
1063 if(testVar!=&_NUL) {
1064 free(testVar);
1065 }
1066 }
1067cleanUpDataTable();
1068}
1069
57a6839d
A
1070/*------------------------------
1071 * TestDisplayNameBrackets
1072 */
1073
1074typedef struct {
1075 const char * displayLocale;
1076 const char * namedRegion;
1077 const char * namedLocale;
1078 const char * regionName;
b331163b
A
1079 const char * ulocLocaleName;
1080 const char * uldnLocaleName;
57a6839d
A
1081} DisplayNameBracketsItem;
1082
1083static const DisplayNameBracketsItem displayNameBracketsItems[] = {
b331163b
A
1084 { "en", "CC", "en_CC", "Cocos (Keeling) Islands", "English (Cocos [Keeling] Islands)", "English (Cocos [Keeling] Islands)" },
1085 { "en", "MM", "my_MM", "Myanmar (Burma)", "Burmese (Myanmar [Burma])", "Burmese (Myanmar)" },
1086 { "en", "MM", "my_Mymr_MM", "Myanmar (Burma)", "Burmese (Myanmar, Myanmar [Burma])", "Burmese (Myanmar, Myanmar)" },
1087 { "zh", "CC", "en_CC", "\\u79D1\\u79D1\\u65AF\\uFF08\\u57FA\\u6797\\uFF09\\u7FA4\\u5C9B",
3d1f044b
A
1088 "\\u82F1\\u8BED\\uFF08\\u79D1\\u79D1\\u65AF\\uFF3B\\u57FA\\u6797\\uFF3D\\u7FA4\\u5C9B\\uFF09",
1089 "\\u82F1\\u8BED\\uFF08\\u79D1\\u79D1\\u65AF\\uFF3B\\u57FA\\u6797\\uFF3D\\u7FA4\\u5C9B\\uFF09" },
b331163b 1090 { "zh", "CG", "fr_CG", "\\u521A\\u679C\\uFF08\\u5E03\\uFF09",
3d1f044b
A
1091 "\\u6CD5\\u8BED\\uFF08\\u521A\\u679C\\uFF3B\\u5E03\\uFF3D\\uFF09",
1092 "\\u6CD5\\u8BED\\uFF08\\u521A\\u679C\\uFF3B\\u5E03\\uFF3D\\uFF09" },
b331163b 1093 { NULL, NULL, NULL, NULL, NULL, NULL }
57a6839d
A
1094};
1095
1096enum { kDisplayNameBracketsMax = 128 };
1097
1098static void TestDisplayNameBrackets()
1099{
1100 const DisplayNameBracketsItem * itemPtr = displayNameBracketsItems;
1101 for (; itemPtr->displayLocale != NULL; itemPtr++) {
1102 ULocaleDisplayNames * uldn;
1103 UErrorCode status;
1104 UChar expectRegionName[kDisplayNameBracketsMax];
b331163b
A
1105 UChar expectUlocLocaleName[kDisplayNameBracketsMax];
1106 UChar expectUldnLocaleName[kDisplayNameBracketsMax];
57a6839d
A
1107 UChar getName[kDisplayNameBracketsMax];
1108 int32_t ulen;
1109
1110 (void) u_unescape(itemPtr->regionName, expectRegionName, kDisplayNameBracketsMax);
b331163b
A
1111 (void) u_unescape(itemPtr->ulocLocaleName, expectUlocLocaleName, kDisplayNameBracketsMax);
1112 (void) u_unescape(itemPtr->uldnLocaleName, expectUldnLocaleName, kDisplayNameBracketsMax);
57a6839d
A
1113
1114 status = U_ZERO_ERROR;
1115 ulen = uloc_getDisplayCountry(itemPtr->namedLocale, itemPtr->displayLocale, getName, kDisplayNameBracketsMax, &status);
1116 if ( U_FAILURE(status) || u_strcmp(getName, expectRegionName) != 0 ) {
1117 log_data_err("uloc_getDisplayCountry for displayLocale %s and namedLocale %s returns unexpected name or status %s\n", itemPtr->displayLocale, itemPtr->namedLocale, myErrorName(status));
1118 }
1119
1120 status = U_ZERO_ERROR;
1121 ulen = uloc_getDisplayName(itemPtr->namedLocale, itemPtr->displayLocale, getName, kDisplayNameBracketsMax, &status);
b331163b 1122 if ( U_FAILURE(status) || u_strcmp(getName, expectUlocLocaleName) != 0 ) {
57a6839d
A
1123 log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %s returns unexpected name or status %s\n", itemPtr->displayLocale, itemPtr->namedLocale, myErrorName(status));
1124 }
b331163b
A
1125 if ( U_FAILURE(status) ) {
1126 log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %-10s returns unexpected status %s\n", itemPtr->displayLocale, itemPtr->namedLocale, myErrorName(status));
1127 } else if ( u_strcmp(getName, expectUlocLocaleName) != 0 ) {
1128 char bbuf[128];
1129 u_strToUTF8(bbuf, 128, NULL, getName, ulen, &status);
1130 log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %-10s returns unexpected name (len %d): \"%s\"\n", itemPtr->displayLocale, itemPtr->namedLocale, ulen, bbuf);
1131 }
57a6839d
A
1132
1133#if !UCONFIG_NO_FORMATTING
1134 status = U_ZERO_ERROR;
1135 uldn = uldn_open(itemPtr->displayLocale, ULDN_STANDARD_NAMES, &status);
1136 if (U_SUCCESS(status)) {
1137 status = U_ZERO_ERROR;
1138 ulen = uldn_regionDisplayName(uldn, itemPtr->namedRegion, getName, kDisplayNameBracketsMax, &status);
1139 if ( U_FAILURE(status) || u_strcmp(getName, expectRegionName) != 0 ) {
1140 log_data_err("uldn_regionDisplayName for displayLocale %s and namedRegion %s returns unexpected name or status %s\n", itemPtr->displayLocale, itemPtr->namedRegion, myErrorName(status));
1141 }
1142
1143 status = U_ZERO_ERROR;
1144 ulen = uldn_localeDisplayName(uldn, itemPtr->namedLocale, getName, kDisplayNameBracketsMax, &status);
b331163b
A
1145 if ( U_FAILURE(status) ) {
1146 log_data_err("uldn_localeDisplayName for displayLocale %s and namedLocale %-10s returns unexpected status %s\n", itemPtr->displayLocale, itemPtr->namedLocale, myErrorName(status));
1147 } else if ( u_strcmp(getName, expectUldnLocaleName) != 0 ) {
1148 char bbuf[128];
1149 u_strToUTF8(bbuf, 128, NULL, getName, ulen, &status);
1150 log_data_err("uldn_localeDisplayName for displayLocale %s and namedLocale %-10s returns unexpected name (len %d): \"%s\"\n", itemPtr->displayLocale, itemPtr->namedLocale, ulen, bbuf);
57a6839d
A
1151 }
1152
1153 uldn_close(uldn);
1154 } else {
1155 log_data_err("uldn_open fails for displayLocale %s, status=%s\n", itemPtr->displayLocale, u_errorName(status));
1156 }
1157#endif
1158 (void)ulen; /* Suppress variable not used warning */
1159 }
1160}
1161
1162/*------------------------------
1163 * TestISOFunctions
1164 */
1165
51004dcb 1166#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
1167/* test for uloc_getISOLanguages, uloc_getISOCountries */
1168static void TestISOFunctions()
1169{
1170 const char* const* str=uloc_getISOLanguages();
1171 const char* const* str1=uloc_getISOCountries();
1172 const char* test;
46f4442e
A
1173 const char *key = NULL;
1174 int32_t count = 0, skipped = 0;
b75a7d8f 1175 int32_t expect;
374ca955 1176 UResourceBundle *res;
46f4442e 1177 UResourceBundle *subRes;
374ca955 1178 UErrorCode status = U_ZERO_ERROR;
b75a7d8f
A
1179
1180 /* test getISOLanguages*/
1181 /*str=uloc_getISOLanguages(); */
1182 log_verbose("Testing ISO Languages: \n");
1183
374ca955
A
1184 /* use structLocale - this data is no longer in root */
1185 res = ures_openDirect(loadTestData(&status), "structLocale", &status);
46f4442e 1186 subRes = ures_getByKey(res, "Languages", NULL, &status);
374ca955 1187 if (U_FAILURE(status)) {
46f4442e
A
1188 log_data_err("There is an error in structLocale's ures_getByKey(\"Languages\"), status=%s\n", u_errorName(status));
1189 return;
374ca955
A
1190 }
1191
46f4442e 1192 expect = ures_getSize(subRes);
374ca955 1193 for(count = 0; *(str+count) != 0; count++)
b75a7d8f 1194 {
46f4442e 1195 key = NULL;
374ca955 1196 test = *(str+count);
46f4442e 1197 status = U_ZERO_ERROR;
374ca955 1198
46f4442e
A
1199 do {
1200 /* Skip over language tags. This API only returns language codes. */
1201 skipped += (key != NULL);
1202 ures_getNextString(subRes, NULL, &key, &status);
1203 }
1204 while (key != NULL && strchr(key, '_'));
1205
1206 if(key == NULL)
1207 break;
1208 /* TODO: Consider removing sh, which is deprecated */
1209 if(strcmp(key,"root") == 0 || strcmp(key,"Fallback") == 0 || strcmp(key,"sh") == 0) {
1210 ures_getNextString(subRes, NULL, &key, &status);
1211 skipped++;
1212 }
73c04bcf 1213#if U_CHARSET_FAMILY==U_ASCII_FAMILY
46f4442e
A
1214 /* This code only works on ASCII machines where the keys are stored in ASCII order */
1215 if(strcmp(test,key)) {
1216 /* The first difference usually implies the place where things get out of sync */
1217 log_err("FAIL Language diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
b75a7d8f 1218 }
374ca955
A
1219#endif
1220
1221 if(!strcmp(test,"in"))
1222 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
1223 if(!strcmp(test,"iw"))
1224 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
1225 if(!strcmp(test,"ji"))
1226 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
1227 if(!strcmp(test,"jw"))
1228 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
1229 if(!strcmp(test,"sh"))
1230 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
1231 }
1232
46f4442e 1233 expect -= skipped; /* Ignore the skipped resources from structLocale */
b75a7d8f
A
1234
1235 if(count!=expect) {
374ca955 1236 log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count, expect);
b75a7d8f
A
1237 }
1238
46f4442e 1239 subRes = ures_getByKey(res, "Countries", subRes, &status);
b75a7d8f 1240 log_verbose("Testing ISO Countries");
46f4442e
A
1241 skipped = 0;
1242 expect = ures_getSize(subRes) - 1; /* Skip ZZ */
374ca955 1243 for(count = 0; *(str1+count) != 0; count++)
b75a7d8f 1244 {
46f4442e 1245 key = NULL;
374ca955 1246 test = *(str1+count);
46f4442e
A
1247 do {
1248 /* Skip over numeric UN tags. This API only returns ISO-3166 codes. */
1249 skipped += (key != NULL);
1250 ures_getNextString(subRes, NULL, &key, &status);
1251 }
1252 while (key != NULL && strlen(key) != 2);
1253
1254 if(key == NULL)
1255 break;
1256 /* TODO: Consider removing CS, which is deprecated */
1257 while(strcmp(key,"QO") == 0 || strcmp(key,"QU") == 0 || strcmp(key,"CS") == 0) {
1258 ures_getNextString(subRes, NULL, &key, &status);
1259 skipped++;
1260 }
1261#if U_CHARSET_FAMILY==U_ASCII_FAMILY
1262 /* This code only works on ASCII machines where the keys are stored in ASCII order */
1263 if(strcmp(test,key)) {
1264 /* The first difference usually implies the place where things get out of sync */
1265 log_err("FAIL Country diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
1266 }
1267#endif
374ca955
A
1268 if(!strcmp(test,"FX"))
1269 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
46f4442e
A
1270 if(!strcmp(test,"YU"))
1271 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
374ca955
A
1272 if(!strcmp(test,"ZR"))
1273 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
b75a7d8f 1274 }
46f4442e
A
1275
1276 ures_getNextString(subRes, NULL, &key, &status);
1277 if (strcmp(key, "ZZ") != 0) {
1278 log_err("ZZ was expected to be the last entry in structLocale, but got %s\n", key);
1279 }
1280#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
1281 /* On EBCDIC machines, the numbers are sorted last. Account for those in the skipped value too. */
1282 key = NULL;
1283 do {
1284 /* Skip over numeric UN tags. uloc_getISOCountries only returns ISO-3166 codes. */
1285 skipped += (key != NULL);
1286 ures_getNextString(subRes, NULL, &key, &status);
1287 }
1288 while (U_SUCCESS(status) && key != NULL && strlen(key) != 2);
1289#endif
1290 expect -= skipped; /* Ignore the skipped resources from structLocale */
b75a7d8f
A
1291 if(count!=expect)
1292 {
1293 log_err("There is an error in getISOCountries, got %d, expected %d \n", count, expect);
1294 }
46f4442e
A
1295 ures_close(subRes);
1296 ures_close(res);
b75a7d8f 1297}
51004dcb 1298#endif
b75a7d8f
A
1299
1300static void setUpDataTable()
1301{
1302 int32_t i,j;
1303 dataTable = (UChar***)(calloc(sizeof(UChar**),LOCALE_INFO_SIZE));
1304
374ca955 1305 for (i = 0; i < LOCALE_INFO_SIZE; i++) {
b75a7d8f 1306 dataTable[i] = (UChar**)(calloc(sizeof(UChar*),LOCALE_SIZE));
374ca955 1307 for (j = 0; j < LOCALE_SIZE; j++){
b75a7d8f
A
1308 dataTable[i][j] = CharsToUChars(rawData2[i][j]);
1309 }
1310 }
1311}
1312
1313static void cleanUpDataTable()
1314{
1315 int32_t i,j;
1316 if(dataTable != NULL) {
1317 for (i=0; i<LOCALE_INFO_SIZE; i++) {
1318 for(j = 0; j < LOCALE_SIZE; j++) {
1319 free(dataTable[i][j]);
1320 }
1321 free(dataTable[i]);
1322 }
1323 free(dataTable);
1324 }
1325 dataTable = NULL;
1326}
1327
1328/**
1329 * @bug 4011756 4011380
1330 */
1331static void TestISO3Fallback()
1332{
1333 const char* test="xx_YY";
1334
1335 const char * result;
1336
1337 result = uloc_getISO3Language(test);
1338
1339 /* Conform to C API usage */
1340
1341 if (!result || (result[0] != 0))
1342 log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
1343
1344 result = uloc_getISO3Country(test);
1345
1346 if (!result || (result[0] != 0))
1347 log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
1348}
1349
1350/**
1351 * @bug 4118587
1352 */
1353static void TestSimpleDisplayNames()
1354{
1355 /*
1356 This test is different from TestDisplayNames because TestDisplayNames checks
1357 fallback behavior, combination of language and country names to form locale
1358 names, and other stuff like that. This test just checks specific language
1359 and country codes to make sure we have the correct names for them.
1360 */
46f4442e 1361 char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za", "419" };
51004dcb 1362 const char* languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
46f4442e
A
1363 "Zhuang", "419" };
1364 const char* inLocale [] = { "en_US", "zh_Hant"};
b75a7d8f
A
1365 UErrorCode status=U_ZERO_ERROR;
1366
1367 int32_t i;
46f4442e
A
1368 int32_t localeIndex = 0;
1369 for (i = 0; i < 7; i++) {
b75a7d8f
A
1370 UChar *testLang=0;
1371 UChar *expectedLang=0;
1372 int size=0;
46f4442e
A
1373
1374 if (i == 6) {
1375 localeIndex = 1; /* Use the second locale for the rest of the test. */
1376 }
1377
1378 size=uloc_getDisplayLanguage(languageCodes[i], inLocale[localeIndex], NULL, size, &status);
b75a7d8f
A
1379 if(status==U_BUFFER_OVERFLOW_ERROR) {
1380 status=U_ZERO_ERROR;
1381 testLang=(UChar*)malloc(sizeof(UChar) * (size + 1));
46f4442e 1382 uloc_getDisplayLanguage(languageCodes[i], inLocale[localeIndex], testLang, size + 1, &status);
b75a7d8f
A
1383 }
1384 expectedLang=(UChar*)malloc(sizeof(UChar) * (strlen(languageNames[i])+1));
1385 u_uastrcpy(expectedLang, languageNames[i]);
1386 if (u_strcmp(testLang, expectedLang) != 0)
1387 log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
1388 languageCodes[i], languageNames[i], austrdup(testLang));
1389 free(testLang);
1390 free(expectedLang);
1391 }
1392
1393}
1394
1395/**
1396 * @bug 4118595
1397 */
1398static void TestUninstalledISO3Names()
1399{
1400 /* This test checks to make sure getISO3Language and getISO3Country work right
1401 even for locales that are not installed. */
46f4442e 1402 static const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn",
b75a7d8f 1403 "ss", "tw", "zu" };
46f4442e 1404 static const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run",
b75a7d8f 1405 "ssw", "twi", "zul" };
46f4442e 1406 static const char iso2Countries [][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
b75a7d8f 1407 "ss_SB", "tw_TC", "zu_ZW" };
46f4442e 1408 static const char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
b75a7d8f
A
1409 "SLB", "TCA", "ZWE" };
1410 int32_t i;
1411
1412 for (i = 0; i < 8; i++) {
1413 UErrorCode err = U_ZERO_ERROR;
1414 const char *test;
1415 test = uloc_getISO3Language(iso2Languages[i]);
1416 if(strcmp(test, iso3Languages[i]) !=0 || U_FAILURE(err))
1417 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1418 iso2Languages[i], iso3Languages[i], test, myErrorName(err));
1419 }
1420 for (i = 0; i < 8; i++) {
1421 UErrorCode err = U_ZERO_ERROR;
1422 const char *test;
1423 test = uloc_getISO3Country(iso2Countries[i]);
1424 if(strcmp(test, iso3Countries[i]) !=0 || U_FAILURE(err))
1425 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1426 iso2Countries[i], iso3Countries[i], test, myErrorName(err));
1427 }
1428}
1429
1430
1431static void TestVariantParsing()
1432{
46f4442e
A
1433 static const char* en_US_custom="en_US_De Anza_Cupertino_California_United States_Earth";
1434 static const char* dispName="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
1435 static const char* dispVar="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
1436 static const char* shortVariant="fr_FR_foo";
1437 static const char* bogusVariant="fr_FR__foo";
1438 static const char* bogusVariant2="fr_FR_foo_";
1439 static const char* bogusVariant3="fr_FR__foo_";
b75a7d8f
A
1440
1441
1442 UChar displayVar[100];
1443 UChar displayName[100];
1444 UErrorCode status=U_ZERO_ERROR;
1445 UChar* got=0;
1446 int32_t size=0;
1447 size=uloc_getDisplayVariant(en_US_custom, "en_US", NULL, size, &status);
1448 if(status==U_BUFFER_OVERFLOW_ERROR) {
1449 status=U_ZERO_ERROR;
1450 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1451 uloc_getDisplayVariant(en_US_custom, "en_US", got, size + 1, &status);
1452 }
1453 else {
1454 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1455 }
1456 u_uastrcpy(displayVar, dispVar);
1457 if(u_strcmp(got,displayVar)!=0) {
1458 log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar, austrdup(got));
1459 }
1460 size=0;
1461 size=uloc_getDisplayName(en_US_custom, "en_US", NULL, size, &status);
1462 if(status==U_BUFFER_OVERFLOW_ERROR) {
1463 status=U_ZERO_ERROR;
1464 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1465 uloc_getDisplayName(en_US_custom, "en_US", got, size + 1, &status);
1466 }
1467 else {
1468 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1469 }
1470 u_uastrcpy(displayName, dispName);
1471 if(u_strcmp(got,displayName)!=0) {
729e4ab9
A
1472 if (status == U_USING_DEFAULT_WARNING) {
1473 log_data_err("FAIL: getDisplayName() got %s. Perhaps you are missing data?\n", u_errorName(status));
1474 } else {
1475 log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName, austrdup(got));
1476 }
b75a7d8f
A
1477 }
1478
1479 size=0;
1480 status=U_ZERO_ERROR;
1481 size=uloc_getDisplayVariant(shortVariant, NULL, NULL, size, &status);
1482 if(status==U_BUFFER_OVERFLOW_ERROR) {
1483 status=U_ZERO_ERROR;
1484 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1485 uloc_getDisplayVariant(shortVariant, NULL, got, size + 1, &status);
1486 }
1487 else {
1488 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1489 }
1490 if(strcmp(austrdup(got),"FOO")!=0) {
1491 log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got));
1492 }
1493 size=0;
1494 status=U_ZERO_ERROR;
1495 size=uloc_getDisplayVariant(bogusVariant, NULL, NULL, size, &status);
1496 if(status==U_BUFFER_OVERFLOW_ERROR) {
1497 status=U_ZERO_ERROR;
1498 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1499 uloc_getDisplayVariant(bogusVariant, NULL, got, size + 1, &status);
1500 }
1501 else {
1502 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1503 }
1504 if(strcmp(austrdup(got),"_FOO")!=0) {
1505 log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got));
1506 }
1507 size=0;
1508 status=U_ZERO_ERROR;
1509 size=uloc_getDisplayVariant(bogusVariant2, NULL, NULL, size, &status);
1510 if(status==U_BUFFER_OVERFLOW_ERROR) {
1511 status=U_ZERO_ERROR;
1512 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1513 uloc_getDisplayVariant(bogusVariant2, NULL, got, size + 1, &status);
1514 }
1515 else {
1516 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1517 }
1518 if(strcmp(austrdup(got),"FOO_")!=0) {
1519 log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got));
1520 }
1521 size=0;
1522 status=U_ZERO_ERROR;
1523 size=uloc_getDisplayVariant(bogusVariant3, NULL, NULL, size, &status);
1524 if(status==U_BUFFER_OVERFLOW_ERROR) {
1525 status=U_ZERO_ERROR;
1526 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1527 uloc_getDisplayVariant(bogusVariant3, NULL, got, size + 1, &status);
1528 }
1529 else {
1530 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1531 }
1532 if(strcmp(austrdup(got),"_FOO_")!=0) {
1533 log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got));
1534 }
1535 free(got);
1536}
1537
1538
1539static void TestObsoleteNames(void)
1540{
1541 int32_t i;
1542 UErrorCode status = U_ZERO_ERROR;
1543 char buff[256];
1544
46f4442e 1545 static const struct
b75a7d8f
A
1546 {
1547 char locale[9];
46f4442e
A
1548 char lang3[4];
1549 char lang[4];
1550 char ctry3[4];
1551 char ctry[4];
b75a7d8f
A
1552 } tests[] =
1553 {
1554 { "eng_USA", "eng", "en", "USA", "US" },
1555 { "kok", "kok", "kok", "", "" },
1556 { "in", "ind", "in", "", "" },
1557 { "id", "ind", "id", "", "" }, /* NO aliasing */
1558 { "sh", "srp", "sh", "", "" },
46f4442e 1559 { "zz_CS", "", "zz", "SCG", "CS" },
b75a7d8f
A
1560 { "zz_FX", "", "zz", "FXX", "FX" },
1561 { "zz_RO", "", "zz", "ROU", "RO" },
1562 { "zz_TP", "", "zz", "TMP", "TP" },
1563 { "zz_TL", "", "zz", "TLS", "TL" },
1564 { "zz_ZR", "", "zz", "ZAR", "ZR" },
1565 { "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
1566 { "zz_ROM", "", "zz", "ROU", "RO" },
1567 { "zz_ROU", "", "zz", "ROU", "RO" },
1568 { "zz_ZAR", "", "zz", "ZAR", "ZR" },
1569 { "zz_TMP", "", "zz", "TMP", "TP" },
1570 { "zz_TLS", "", "zz", "TLS", "TL" },
46f4442e 1571 { "zz_YUG", "", "zz", "YUG", "YU" },
b75a7d8f
A
1572 { "mlt_PSE", "mlt", "mt", "PSE", "PS" },
1573 { "iw", "heb", "iw", "", "" },
1574 { "ji", "yid", "ji", "", "" },
1575 { "jw", "jaw", "jw", "", "" },
1576 { "sh", "srp", "sh", "", "" },
1577 { "", "", "", "", "" }
1578 };
1579
1580 for(i=0;tests[i].locale[0];i++)
1581 {
1582 const char *locale;
1583
1584 locale = tests[i].locale;
1585 log_verbose("** %s:\n", locale);
1586
1587 status = U_ZERO_ERROR;
1588 if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1589 {
1590 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1591 locale, uloc_getISO3Language(locale), tests[i].lang3);
1592 }
1593 else
1594 {
1595 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1596 uloc_getISO3Language(locale) );
1597 }
1598
1599 status = U_ZERO_ERROR;
1600 uloc_getLanguage(locale, buff, 256, &status);
1601 if(U_FAILURE(status))
1602 {
1603 log_err("FAIL: error getting language from %s\n", locale);
1604 }
1605 else
1606 {
1607 if(strcmp(buff,tests[i].lang))
1608 {
1609 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1610 locale, buff, tests[i].lang);
1611 }
1612 else
1613 {
1614 log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale, buff);
1615 }
1616 }
1617 if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1618 {
1619 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1620 locale, uloc_getISO3Language(locale), tests[i].lang3);
1621 }
1622 else
1623 {
1624 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1625 uloc_getISO3Language(locale) );
1626 }
1627
1628 if(strcmp(tests[i].ctry3,uloc_getISO3Country(locale)))
1629 {
1630 log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1631 locale, uloc_getISO3Country(locale), tests[i].ctry3);
1632 }
1633 else
1634 {
1635 log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1636 uloc_getISO3Country(locale) );
1637 }
1638
1639 status = U_ZERO_ERROR;
1640 uloc_getCountry(locale, buff, 256, &status);
1641 if(U_FAILURE(status))
1642 {
1643 log_err("FAIL: error getting country from %s\n", locale);
1644 }
1645 else
1646 {
1647 if(strcmp(buff,tests[i].ctry))
1648 {
1649 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1650 locale, buff, tests[i].ctry);
1651 }
1652 else
1653 {
1654 log_verbose(" uloc_getCountry(%s)==\t%s\n", locale, buff);
1655 }
1656 }
1657 }
1658
374ca955
A
1659 if (uloc_getLCID("iw_IL") != uloc_getLCID("he_IL")) {
1660 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw_IL"), uloc_getLCID("he_IL"));
1661 }
1662
1663 if (uloc_getLCID("iw") != uloc_getLCID("he")) {
1664 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw"), uloc_getLCID("he"));
1665 }
1666
b75a7d8f
A
1667#if 0
1668
1669 i = uloc_getLanguage("kok",NULL,0,&icu_err);
1670 if(U_FAILURE(icu_err))
1671 {
1672 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err));
1673 }
1674
1675 icu_err = U_ZERO_ERROR;
1676 uloc_getLanguage("kok",r1_buff,12,&icu_err);
1677 if(U_FAILURE(icu_err))
1678 {
1679 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err));
1680 }
1681
1682 r1_addr = (char *)uloc_getISO3Language("kok");
1683
1684 icu_err = U_ZERO_ERROR;
1685 if (strcmp(r1_buff,"kok") != 0)
1686 {
1687 log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff);
1688 line--;
1689 }
1690 r1_addr = (char *)uloc_getISO3Language("in");
1691 i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1692 if (strcmp(r1_buff,"id") != 0)
1693 {
1694 printf("uloc_getLanguage error (%s)\n",r1_buff);
1695 line--;
1696 }
1697 r1_addr = (char *)uloc_getISO3Language("sh");
1698 i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1699 if (strcmp(r1_buff,"sr") != 0)
1700 {
1701 printf("uloc_getLanguage error (%s)\n",r1_buff);
1702 line--;
1703 }
1704
1705 r1_addr = (char *)uloc_getISO3Country("zz_ZR");
1706 strcpy(p1_buff,"zz_");
1707 strcat(p1_buff,r1_addr);
1708 i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1709 if (strcmp(r1_buff,"ZR") != 0)
1710 {
1711 printf("uloc_getCountry error (%s)\n",r1_buff);
1712 line--;
1713 }
1714 r1_addr = (char *)uloc_getISO3Country("zz_FX");
1715 strcpy(p1_buff,"zz_");
1716 strcat(p1_buff,r1_addr);
1717 i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1718 if (strcmp(r1_buff,"FX") != 0)
1719 {
1720 printf("uloc_getCountry error (%s)\n",r1_buff);
1721 line--;
1722 }
1723
1724#endif
1725
1726}
1727
374ca955
A
1728static void TestKeywordVariants(void)
1729{
46f4442e 1730 static const struct {
374ca955 1731 const char *localeID;
2ca993e8
A
1732 const char *expectedLocaleID; /* uloc_getName */
1733 const char *expectedLocaleIDNoKeywords; /* uloc_getBaseName */
1734 const char *expectedCanonicalID; /* uloc_canonicalize */
374ca955
A
1735 const char *expectedKeywords[10];
1736 int32_t numKeywords;
1737 UErrorCode expectedStatus; /* from uloc_openKeywords */
1738 } testCases[] = {
1739 {
1740 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1741 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1742 "de_DE",
1743 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1744 {"calendar", "collation", "currency"},
1745 3,
1746 U_ZERO_ERROR
1747 },
1748 {
1749 "de_DE@euro",
1750 "de_DE@euro",
2ca993e8 1751 "de_DE@euro", /* we probably should strip off the POSIX style variant @euro see #11690 */
3d1f044b 1752 "de_DE_EURO",
374ca955
A
1753 {"","","","","","",""},
1754 0,
1755 U_INVALID_FORMAT_ERROR /* must have '=' after '@' */
1756 },
1757 {
2ca993e8
A
1758 "de_DE@euro;collation=phonebook", /* The POSIX style variant @euro cannot be combined with key=value? */
1759 "de_DE", /* getName returns de_DE - should be INVALID_FORMAT_ERROR? */
1760 "de_DE", /* getBaseName returns de_DE - should be INVALID_FORMAT_ERROR? see #11690 */
1761 "de_DE", /* canonicalize returns de_DE - should be INVALID_FORMAT_ERROR? */
374ca955
A
1762 {"","","","","","",""},
1763 0,
1764 U_INVALID_FORMAT_ERROR
2ca993e8
A
1765 },
1766 {
1767 "de_DE@collation=",
1768 0, /* expected getName to fail */
1769 "de_DE", /* getBaseName returns de_DE - should be INVALID_FORMAT_ERROR? see #11690 */
1770 0, /* expected canonicalize to fail */
1771 {"","","","","","",""},
1772 0,
1773 U_INVALID_FORMAT_ERROR /* must have '=' after '@' */
374ca955
A
1774 }
1775 };
1776 UErrorCode status = U_ZERO_ERROR;
1777
1778 int32_t i = 0, j = 0;
1779 int32_t resultLen = 0;
1780 char buffer[256];
1781 UEnumeration *keywords;
1782 int32_t keyCount = 0;
1783 const char *keyword = NULL;
1784 int32_t keywordLen = 0;
1785
2ca993e8 1786 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
374ca955
A
1787 status = U_ZERO_ERROR;
1788 *buffer = 0;
1789 keywords = uloc_openKeywords(testCases[i].localeID, &status);
1790
1791 if(status != testCases[i].expectedStatus) {
1792 log_err("Expected to uloc_openKeywords(\"%s\") => status %s. Got %s instead\n",
1793 testCases[i].localeID,
1794 u_errorName(testCases[i].expectedStatus), u_errorName(status));
1795 }
1796 status = U_ZERO_ERROR;
1797 if(keywords) {
1798 if((keyCount = uenum_count(keywords, &status)) != testCases[i].numKeywords) {
1799 log_err("Expected to get %i keywords, got %i\n", testCases[i].numKeywords, keyCount);
b75a7d8f 1800 }
374ca955
A
1801 if(keyCount) {
1802 j = 0;
1803 while((keyword = uenum_next(keywords, &keywordLen, &status))) {
1804 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1805 log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
b75a7d8f 1806 }
374ca955 1807 j++;
b75a7d8f 1808 }
73c04bcf
A
1809 j = 0;
1810 uenum_reset(keywords, &status);
1811 while((keyword = uenum_next(keywords, &keywordLen, &status))) {
1812 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1813 log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1814 }
1815 j++;
1816 }
b75a7d8f 1817 }
374ca955 1818 uenum_close(keywords);
b75a7d8f 1819 }
2ca993e8
A
1820
1821 status = U_ZERO_ERROR;
374ca955 1822 resultLen = uloc_getName(testCases[i].localeID, buffer, 256, &status);
3d1f044b 1823 U_ASSERT(resultLen < 256);
2ca993e8
A
1824 if (U_SUCCESS(status)) {
1825 if (testCases[i].expectedLocaleID == 0) {
1826 log_err("Expected uloc_getName(\"%s\") to fail; got \"%s\"\n",
1827 testCases[i].localeID, buffer);
1828 } else if (uprv_strcmp(testCases[i].expectedLocaleID, buffer) != 0) {
1829 log_err("Expected uloc_getName(\"%s\") => \"%s\"; got \"%s\"\n",
1830 testCases[i].localeID, testCases[i].expectedLocaleID, buffer);
1831 }
1832 } else {
1833 if (testCases[i].expectedLocaleID != 0) {
1834 log_err("Expected uloc_getName(\"%s\") => \"%s\"; but returned error: %s\n",
1835 testCases[i].localeID, testCases[i].expectedLocaleID, buffer, u_errorName(status));
1836 }
b75a7d8f 1837 }
2ca993e8
A
1838
1839 status = U_ZERO_ERROR;
1840 resultLen = uloc_getBaseName(testCases[i].localeID, buffer, 256, &status);
3d1f044b 1841 U_ASSERT(resultLen < 256);
2ca993e8
A
1842 if (U_SUCCESS(status)) {
1843 if (testCases[i].expectedLocaleIDNoKeywords == 0) {
1844 log_err("Expected uloc_getBaseName(\"%s\") to fail; got \"%s\"\n",
1845 testCases[i].localeID, buffer);
1846 } else if (uprv_strcmp(testCases[i].expectedLocaleIDNoKeywords, buffer) != 0) {
1847 log_err("Expected uloc_getBaseName(\"%s\") => \"%s\"; got \"%s\"\n",
1848 testCases[i].localeID, testCases[i].expectedLocaleIDNoKeywords, buffer);
1849 }
1850 } else {
1851 if (testCases[i].expectedLocaleIDNoKeywords != 0) {
1852 log_err("Expected uloc_getBaseName(\"%s\") => \"%s\"; but returned error: %s\n",
1853 testCases[i].localeID, testCases[i].expectedLocaleIDNoKeywords, buffer, u_errorName(status));
1854 }
1855 }
1856
1857 status = U_ZERO_ERROR;
374ca955 1858 resultLen = uloc_canonicalize(testCases[i].localeID, buffer, 256, &status);
3d1f044b 1859 U_ASSERT(resultLen < 256);
2ca993e8
A
1860 if (U_SUCCESS(status)) {
1861 if (testCases[i].expectedCanonicalID == 0) {
1862 log_err("Expected uloc_canonicalize(\"%s\") to fail; got \"%s\"\n",
1863 testCases[i].localeID, buffer);
1864 } else if (uprv_strcmp(testCases[i].expectedCanonicalID, buffer) != 0) {
1865 log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n",
1866 testCases[i].localeID, testCases[i].expectedCanonicalID, buffer);
1867 }
1868 } else {
1869 if (testCases[i].expectedCanonicalID != 0) {
1870 log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; but returned error: %s\n",
1871 testCases[i].localeID, testCases[i].expectedCanonicalID, buffer, u_errorName(status));
1872 }
1873 }
374ca955 1874 }
374ca955
A
1875}
1876
1877static void TestKeywordVariantParsing(void)
1878{
46f4442e 1879 static const struct {
374ca955
A
1880 const char *localeID;
1881 const char *keyword;
f3c0d7a5 1882 const char *expectedValue; /* NULL if failure is expected */
374ca955 1883 } testCases[] = {
f3c0d7a5 1884 { "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", NULL }, /* malformed key name */
374ca955
A
1885 { "de_DE", "collation", ""},
1886 { "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" },
1887 { "de_DE@currency = euro; CoLLaTion = PHONEBOOk", "collatiON", "PHONEBOOk" },
1888 };
1889
f3c0d7a5 1890 UErrorCode status;
374ca955
A
1891 int32_t i = 0;
1892 int32_t resultLen = 0;
1893 char buffer[256];
1894
2ca993e8 1895 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
374ca955 1896 *buffer = 0;
f3c0d7a5 1897 status = U_ZERO_ERROR;
374ca955 1898 resultLen = uloc_getKeywordValue(testCases[i].localeID, testCases[i].keyword, buffer, 256, &status);
57a6839d 1899 (void)resultLen; /* Suppress set but not used warning. */
f3c0d7a5
A
1900 if (testCases[i].expectedValue) {
1901 /* expect success */
1902 if (U_FAILURE(status)) {
1903 log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Instead got status %s\n",
1904 testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, u_errorName(status));
1905 } else if (uprv_strcmp(testCases[i].expectedValue, buffer) != 0) {
1906 log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Instead got \"%s\"\n",
1907 testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, buffer);
1908 }
1909 } else if (U_SUCCESS(status)) {
1910 /* expect failure */
1911 log_err("Expected failure but got success from \"%s\" for keyword \"%s\". Got \"%s\"\n",
1912 testCases[i].localeID, testCases[i].keyword, buffer);
1913
b75a7d8f 1914 }
b75a7d8f
A
1915 }
1916}
1917
46f4442e 1918static const struct {
374ca955
A
1919 const char *l; /* locale */
1920 const char *k; /* kw */
1921 const char *v; /* value */
1922 const char *x; /* expected */
1923} kwSetTestCases[] = {
1924#if 1
1925 { "en_US", "calendar", "japanese", "en_US@calendar=japanese" },
1926 { "en_US@", "calendar", "japanese", "en_US@calendar=japanese" },
1927 { "en_US@calendar=islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1928 { "en_US@calendar=slovakian", "calendar", "gregorian", "en_US@calendar=gregorian" }, /* don't know what this means, but it has the same # of chars as gregorian */
1929 { "en_US@calendar=gregorian", "calendar", "japanese", "en_US@calendar=japanese" },
1930 { "de", "Currency", "CHF", "de@currency=CHF" },
1931 { "de", "Currency", "CHF", "de@currency=CHF" },
1932
1933 { "en_US@collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1934 { "en_US@calendar=japanese", "collation", "phonebook", "en_US@calendar=japanese;collation=phonebook" },
1935 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1936 { "en_US@calendar=gregorian;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1937 { "en_US@calendar=slovakian;collation=phonebook", "calendar", "gregorian", "en_US@calendar=gregorian;collation=phonebook" }, /* don't know what this means, but it has the same # of chars as gregorian */
1938 { "en_US@calendar=slovakian;collation=videobook", "collation", "phonebook", "en_US@calendar=slovakian;collation=phonebook" }, /* don't know what this means, but it has the same # of chars as gregorian */
1939 { "en_US@calendar=islamic;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1940 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1941#endif
1942#if 1
1943 { "mt@a=0;b=1;c=2;d=3", "c","j", "mt@a=0;b=1;c=j;d=3" },
1944 { "mt@a=0;b=1;c=2;d=3", "x","j", "mt@a=0;b=1;c=2;d=3;x=j" },
1945 { "mt@a=0;b=1;c=2;d=3", "a","f", "mt@a=f;b=1;c=2;d=3" },
1946 { "mt@a=0;aa=1;aaa=3", "a","x", "mt@a=x;aa=1;aaa=3" },
1947 { "mt@a=0;aa=1;aaa=3", "aa","x", "mt@a=0;aa=x;aaa=3" },
1948 { "mt@a=0;aa=1;aaa=3", "aaa","x", "mt@a=0;aa=1;aaa=x" },
1949 { "mt@a=0;aa=1;aaa=3", "a","yy", "mt@a=yy;aa=1;aaa=3" },
1950 { "mt@a=0;aa=1;aaa=3", "aa","yy", "mt@a=0;aa=yy;aaa=3" },
1951 { "mt@a=0;aa=1;aaa=3", "aaa","yy", "mt@a=0;aa=1;aaa=yy" },
1952#endif
1953#if 1
1954 /* removal tests */
1955 /* 1. removal of item at end */
1956 { "de@collation=phonebook;currency=CHF", "currency", "", "de@collation=phonebook" },
1957 { "de@collation=phonebook;currency=CHF", "currency", NULL, "de@collation=phonebook" },
1958 /* 2. removal of item at beginning */
1959 { "de@collation=phonebook;currency=CHF", "collation", "", "de@currency=CHF" },
1960 { "de@collation=phonebook;currency=CHF", "collation", NULL, "de@currency=CHF" },
1961 /* 3. removal of an item not there */
1962 { "de@collation=phonebook;currency=CHF", "calendar", NULL, "de@collation=phonebook;currency=CHF" },
1963 /* 4. removal of only item */
1964 { "de@collation=phonebook", "collation", NULL, "de" },
1965#endif
f3c0d7a5
A
1966 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1967 /* cases with legal extra spacing */
1968 /*31*/{ "en_US@ calendar = islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1969 /*32*/{ "en_US@ calendar = gregorian ; collation = phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1970 /*33*/{ "en_US@ calendar = islamic", "currency", "CHF", "en_US@calendar=islamic;currency=CHF" },
1971 /*34*/{ "en_US@ currency = CHF", "calendar", "japanese", "en_US@calendar=japanese;currency=CHF" },
1972 /* cases in which setKeywordValue expected to fail (implied by NULL for expected); locale need not be canonical */
1973 /*35*/{ "en_US@calendar=gregorian;", "calendar", "japanese", NULL },
1974 /*36*/{ "en_US@calendar=gregorian;=", "calendar", "japanese", NULL },
1975 /*37*/{ "en_US@calendar=gregorian;currency=", "calendar", "japanese", NULL },
1976 /*38*/{ "en_US@=", "calendar", "japanese", NULL },
1977 /*39*/{ "en_US@=;", "calendar", "japanese", NULL },
1978 /*40*/{ "en_US@= ", "calendar", "japanese", NULL },
1979 /*41*/{ "en_US@ =", "calendar", "japanese", NULL },
1980 /*42*/{ "en_US@ = ", "calendar", "japanese", NULL },
1981 /*43*/{ "en_US@=;calendar=gregorian", "calendar", "japanese", NULL },
1982 /*44*/{ "en_US@= calen dar = gregorian", "calendar", "japanese", NULL },
1983 /*45*/{ "en_US@= calendar = greg orian", "calendar", "japanese", NULL },
1984 /*46*/{ "en_US@=;cal...endar=gregorian", "calendar", "japanese", NULL },
1985 /*47*/{ "en_US@=;calendar=greg...orian", "calendar", "japanese", NULL },
1986 /*48*/{ "en_US@calendar=gregorian", "cale ndar", "japanese", NULL },
1987 /*49*/{ "en_US@calendar=gregorian", "calendar", "japa..nese", NULL },
1988 /* cases in which getKeywordValue and setKeyword expected to fail (implied by NULL for value and expected) */
1989 /*50*/{ "en_US@=", "calendar", NULL, NULL },
1990 /*51*/{ "en_US@=;", "calendar", NULL, NULL },
1991 /*52*/{ "en_US@= ", "calendar", NULL, NULL },
1992 /*53*/{ "en_US@ =", "calendar", NULL, NULL },
1993 /*54*/{ "en_US@ = ", "calendar", NULL, NULL },
1994 /*55*/{ "en_US@=;calendar=gregorian", "calendar", NULL, NULL },
1995 /*56*/{ "en_US@= calen dar = gregorian", "calendar", NULL, NULL },
1996 /*57*/{ "en_US@= calendar = greg orian", "calendar", NULL, NULL },
1997 /*58*/{ "en_US@=;cal...endar=gregorian", "calendar", NULL, NULL },
1998 /*59*/{ "en_US@=;calendar=greg...orian", "calendar", NULL, NULL },
1999 /*60*/{ "en_US@calendar=gregorian", "cale ndar", NULL, NULL },
374ca955 2000};
b75a7d8f 2001
b75a7d8f 2002
374ca955 2003static void TestKeywordSet(void)
b75a7d8f 2004{
374ca955
A
2005 int32_t i = 0;
2006 int32_t resultLen = 0;
2007 char buffer[1024];
b75a7d8f 2008
374ca955 2009 char cbuffer[1024];
b75a7d8f 2010
2ca993e8 2011 for(i = 0; i < UPRV_LENGTHOF(kwSetTestCases); i++) {
f3c0d7a5
A
2012 UErrorCode status = U_ZERO_ERROR;
2013 memset(buffer,'%',1023);
2014 strcpy(buffer, kwSetTestCases[i].l);
b75a7d8f 2015
f3c0d7a5 2016 if (kwSetTestCases[i].x != NULL) {
374ca955
A
2017 uloc_canonicalize(kwSetTestCases[i].l, cbuffer, 1023, &status);
2018 if(strcmp(buffer,cbuffer)) {
2019 log_verbose("note: [%d] wasn't canonical, should be: '%s' not '%s'. Won't check for canonicity in output.\n", i, cbuffer, buffer);
b75a7d8f 2020 }
f3c0d7a5 2021 /* sanity check test case results for canonicity */
374ca955
A
2022 uloc_canonicalize(kwSetTestCases[i].x, cbuffer, 1023, &status);
2023 if(strcmp(kwSetTestCases[i].x,cbuffer)) {
2024 log_err("%s:%d: ERROR: kwSetTestCases[%d].x = '%s', should be %s (must be canonical)\n", __FILE__, __LINE__, i, kwSetTestCases[i].x, cbuffer);
b75a7d8f 2025 }
b75a7d8f 2026
f3c0d7a5 2027 status = U_ZERO_ERROR;
374ca955
A
2028 resultLen = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, 1023, &status);
2029 if(U_FAILURE(status)) {
f3c0d7a5
A
2030 log_err("Err on test case %d for setKeywordValue: got error %s\n", i, u_errorName(status));
2031 } else if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=resultLen)) {
2032 log_err("FAIL: #%d setKeywordValue: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
374ca955
A
2033 kwSetTestCases[i].v, buffer, resultLen, kwSetTestCases[i].x, strlen(buffer));
2034 } else {
2035 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,buffer);
b75a7d8f 2036 }
f3c0d7a5
A
2037
2038 if (kwSetTestCases[i].v != NULL && kwSetTestCases[i].v[0] != 0) {
2039 status = U_ZERO_ERROR;
2040 resultLen = uloc_getKeywordValue(kwSetTestCases[i].x, kwSetTestCases[i].k, buffer, 1023, &status);
2041 if(U_FAILURE(status)) {
2042 log_err("Err on test case %d for getKeywordValue: got error %s\n", i, u_errorName(status));
2043 } else if (resultLen != uprv_strlen(kwSetTestCases[i].v) || uprv_strcmp(buffer, kwSetTestCases[i].v) != 0) {
2044 log_err("FAIL: #%d getKeywordValue: got %s (%d) expected %s (%d)\n", i, buffer, resultLen,
2045 kwSetTestCases[i].v, uprv_strlen(kwSetTestCases[i].v));
2046 }
2047 }
2048 } else {
2049 /* test cases expected to result in error */
2050 status = U_ZERO_ERROR;
2051 resultLen = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, 1023, &status);
2052 if(U_SUCCESS(status)) {
2053 log_err("Err on test case %d for setKeywordValue: expected to fail but succeeded, got %s (%d)\n", i, buffer, resultLen);
2054 }
2055
2056 if (kwSetTestCases[i].v == NULL) {
2057 status = U_ZERO_ERROR;
2058 strcpy(cbuffer, kwSetTestCases[i].l);
2059 resultLen = uloc_getKeywordValue(cbuffer, kwSetTestCases[i].k, buffer, 1023, &status);
2060 if(U_SUCCESS(status)) {
2061 log_err("Err on test case %d for getKeywordValue: expected to fail but succeeded\n", i);
2062 }
2063 }
2064 }
b75a7d8f
A
2065 }
2066}
2067
374ca955
A
2068static void TestKeywordSetError(void)
2069{
2070 char buffer[1024];
2071 UErrorCode status;
2072 int32_t res;
2073 int32_t i;
2074 int32_t blen;
b75a7d8f 2075
374ca955
A
2076 /* 0-test whether an error condition modifies the buffer at all */
2077 blen=0;
2078 i=0;
2079 memset(buffer,'%',1023);
2080 status = U_ZERO_ERROR;
2081 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
2082 if(status != U_ILLEGAL_ARGUMENT_ERROR) {
2083 log_err("expected illegal err got %s\n", u_errorName(status));
2084 return;
2085 }
2086 /* if(res!=strlen(kwSetTestCases[i].x)) {
2087 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
2088 return;
2089 } */
2090 if(buffer[blen]!='%') {
2091 log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
2092 return;
2093 }
2094 log_verbose("0-buffer modify OK\n");
b75a7d8f 2095
374ca955
A
2096 for(i=0;i<=2;i++) {
2097 /* 1- test a short buffer with growing text */
73c04bcf 2098 blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
374ca955
A
2099 memset(buffer,'%',1023);
2100 strcpy(buffer,kwSetTestCases[i].l);
2101 status = U_ZERO_ERROR;
2102 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
2103 if(status != U_BUFFER_OVERFLOW_ERROR) {
2104 log_err("expected buffer overflow on buffer %d got %s, len %d (%s + [%s=%s])\n", blen, u_errorName(status), res, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v);
2105 return;
b75a7d8f 2106 }
374ca955
A
2107 if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
2108 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
2109 return;
b75a7d8f 2110 }
374ca955
A
2111 if(buffer[blen]!='%') {
2112 log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
2113 return;
b75a7d8f 2114 }
374ca955 2115 log_verbose("1/%d-buffer modify OK\n",i);
b75a7d8f
A
2116 }
2117
374ca955
A
2118 for(i=3;i<=4;i++) {
2119 /* 2- test a short buffer - text the same size or shrinking */
73c04bcf 2120 blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
374ca955
A
2121 memset(buffer,'%',1023);
2122 strcpy(buffer,kwSetTestCases[i].l);
2123 status = U_ZERO_ERROR;
2124 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
2125 if(status != U_ZERO_ERROR) {
2126 log_err("expected zero error got %s\n", u_errorName(status));
2127 return;
b75a7d8f 2128 }
374ca955
A
2129 if(buffer[blen+1]!='%') {
2130 log_err("Buffer byte %d was modified: now %c\n", blen+1, buffer[blen+1]);
2131 return;
b75a7d8f 2132 }
374ca955
A
2133 if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
2134 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
2135 return;
b75a7d8f 2136 }
374ca955
A
2137 if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=res)) {
2138 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
2139 kwSetTestCases[i].v, buffer, res, kwSetTestCases[i].x, strlen(buffer));
2140 } else {
2141 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,
2142 buffer);
2143 }
2144 log_verbose("2/%d-buffer modify OK\n",i);
b75a7d8f 2145 }
374ca955 2146}
b75a7d8f 2147
374ca955
A
2148static int32_t _canonicalize(int32_t selector, /* 0==getName, 1==canonicalize */
2149 const char* localeID,
2150 char* result,
2151 int32_t resultCapacity,
2152 UErrorCode* ec) {
2153 /* YOU can change this to use function pointers if you like */
2154 switch (selector) {
2155 case 0:
2156 return uloc_getName(localeID, result, resultCapacity, ec);
2157 case 1:
2158 return uloc_canonicalize(localeID, result, resultCapacity, ec);
2159 default:
2160 return -1;
2161 }
b75a7d8f
A
2162}
2163
374ca955 2164static void TestCanonicalization(void)
b75a7d8f 2165{
46f4442e 2166 static const struct {
374ca955
A
2167 const char *localeID; /* input */
2168 const char *getNameID; /* expected getName() result */
2169 const char *canonicalID; /* expected canonicalize() result */
2170 } testCases[] = {
3d1f044b
A
2171 { "ca_ES-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2172 "ca_ES_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2173 "ca_ES_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
374ca955
A
2174 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2175 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2176 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2177 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2178 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2179 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2180 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2181 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
3d1f044b 2182 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ_EURO" }, /* qz-qz uses private use iso codes */
51004dcb
A
2183 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
2184 { "de-1901", "de__1901", "de__1901" }, /* registered name */
2185 { "de-1906", "de__1906", "de__1906" }, /* registered name */
374ca955
A
2186
2187 /* posix behavior that used to be performed by getName */
2188 { "mr.utf8", "mr.utf8", "mr" },
2189 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2190 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2191 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2192 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2193 { "no-no-ny.utf8@B", "no_NO_NY.utf8@B", "no_NO_NY_B" /* not: "nn_NO" [alan ICU3.0] */ }, /* @ ignored unless variant is empty */
2194
2195 /* fleshing out canonicalization */
2196 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2197 { "en_Hant_IL_VALLEY_GIRL@ currency = EUR; calendar = Japanese ;", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
2198 /* already-canonical ids are not changed */
2199 { "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
374ca955
A
2200 /* norwegian is just too weird, if we handle things in their full generality */
2201 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2202
2203 /* test cases reflecting internal resource bundle usage */
2204 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2205 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2206 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
73c04bcf
A
2207 { "ja_JP", "ja_JP", "ja_JP" },
2208
2209 /* test case for "i-default" */
3d1f044b
A
2210 { "i-default", "en@x=i-default", "en@x=i-default" },
2211
2212 // Before ICU 64, ICU locale canonicalization had some additional mappings.
2213 // They were removed for ICU-20187 "drop support for long-obsolete locale ID variants".
2214 // The following now use standard canonicalization.
2215 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES_PREEURO" },
2216 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT_PREEURO" },
2217 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE_PREEURO" },
2218 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU_PREEURO" },
2219 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR_PREEURO" },
2220 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE_PREEURO" },
2221 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE_PREEURO" },
2222 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES_PREEURO" },
2223 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES_PREEURO" },
2224 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI_PREEURO" },
2225 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE_PREEURO" },
2226 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR_PREEURO" },
2227 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU_PREEURO" },
2228 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE_PREEURO" },
2229 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES_PREEURO" },
2230 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT_PREEURO" },
2231 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE_PREEURO" },
2232 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL_PREEURO" },
2233 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT_PREEURO" },
2234 { "de__PHONEBOOK", "de__PHONEBOOK", "de__PHONEBOOK" },
2235 { "en_GB_EURO", "en_GB_EURO", "en_GB_EURO" },
2236 { "en_GB@EURO", "en_GB@EURO", "en_GB_EURO" }, /* POSIX ID */
2237 { "es__TRADITIONAL", "es__TRADITIONAL", "es__TRADITIONAL" },
2238 { "hi__DIRECT", "hi__DIRECT", "hi__DIRECT" },
2239 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL" },
2240 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH_TRADITIONAL" },
2241 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW_STROKE" },
2242 { "zh__PINYIN", "zh__PINYIN", "zh__PINYIN" },
2243 { "zh_CN_STROKE", "zh_CN_STROKE", "zh_CN_STROKE" },
2244 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_SP_CYRL" }, /* .NET name */
2245 { "sr-SP-Latn", "sr_SP_LATN", "sr_SP_LATN" }, /* .NET name */
2246 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_YU_CYRILLIC" }, /* Linux name */
2247 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_UZ_CYRL" }, /* .NET name */
2248 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_UZ_LATN" }, /* .NET name */
2249 { "zh-CHS", "zh_CHS", "zh_CHS" }, /* .NET name */
2250 { "zh-CHT", "zh_CHT", "zh_CHT" }, /* .NET name This may change back to zh_Hant */
2251 /* PRE_EURO and EURO conversions don't affect other keywords */
2252 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES_PREEURO@calendar=Japanese" },
2253 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah" },
2254 /* currency keyword overrides PRE_EURO and EURO currency */
2255 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR" },
2256 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP" },
374ca955 2257 };
3d1f044b 2258
374ca955
A
2259 static const char* label[] = { "getName", "canonicalize" };
2260
2261 UErrorCode status = U_ZERO_ERROR;
2262 int32_t i, j, resultLen = 0, origResultLen;
2263 char buffer[256];
2264
2ca993e8 2265 for (i=0; i < UPRV_LENGTHOF(testCases); i++) {
374ca955
A
2266 for (j=0; j<2; ++j) {
2267 const char* expected = (j==0) ? testCases[i].getNameID : testCases[i].canonicalID;
2268 *buffer = 0;
2269 status = U_ZERO_ERROR;
73c04bcf
A
2270
2271 if (expected == NULL) {
2272 expected = uloc_getDefault();
2273 }
2274
374ca955
A
2275 /* log_verbose("testing %s -> %s\n", testCases[i], testCases[i].canonicalID); */
2276 origResultLen = _canonicalize(j, testCases[i].localeID, NULL, 0, &status);
2277 if (status != U_BUFFER_OVERFLOW_ERROR) {
2278 log_err("FAIL: uloc_%s(%s) => %s, expected U_BUFFER_OVERFLOW_ERROR\n",
2279 label[j], testCases[i].localeID, u_errorName(status));
2280 continue;
2281 }
2282 status = U_ZERO_ERROR;
2283 resultLen = _canonicalize(j, testCases[i].localeID, buffer, sizeof(buffer), &status);
2284 if (U_FAILURE(status)) {
2285 log_err("FAIL: uloc_%s(%s) => %s, expected U_ZERO_ERROR\n",
2286 label[j], testCases[i].localeID, u_errorName(status));
2287 continue;
2288 }
2289 if(uprv_strcmp(expected, buffer) != 0) {
2290 log_err("FAIL: uloc_%s(%s) => \"%s\", expected \"%s\"\n",
2291 label[j], testCases[i].localeID, buffer, expected);
2292 } else {
2293 log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
2294 label[j], testCases[i].localeID, buffer);
2295 }
2296 if (resultLen != (int32_t)strlen(buffer)) {
2297 log_err("FAIL: uloc_%s(%s) => len %d, expected len %d\n",
2298 label[j], testCases[i].localeID, resultLen, strlen(buffer));
2299 }
2300 if (origResultLen != resultLen) {
2301 log_err("FAIL: uloc_%s(%s) => preflight len %d != actual len %d\n",
2302 label[j], testCases[i].localeID, origResultLen, resultLen);
2303 }
b75a7d8f
A
2304 }
2305 }
2306}
2307
3d1f044b
A
2308static void TestCanonicalizationBuffer(void)
2309{
2310 UErrorCode status = U_ZERO_ERROR;
2311 char buffer[256];
2312
2313 // ULOC_FULLNAME_CAPACITY == 157 (uloc.h)
2314 static const char name[] =
2315 "zh@x"
2316 "=foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
2317 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
2318 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
2319 "-foo-barz"
2320 ;
2321 static const size_t len = sizeof(name) - 1; // Without NUL terminator.
2322
2323 int32_t reslen = uloc_canonicalize(name, buffer, (int32_t)len, &status);
2324
2325 if (U_FAILURE(status)) {
2326 log_err("FAIL: uloc_canonicalize(%s) => %s, expected !U_FAILURE()\n",
2327 name, u_errorName(status));
2328 return;
2329 }
2330
2331 if (reslen != len) {
2332 log_err("FAIL: uloc_canonicalize(%s) => \"%i\", expected \"%u\"\n",
2333 name, reslen, len);
2334 return;
2335 }
2336
2337 if (uprv_strncmp(name, buffer, len) != 0) {
2338 log_err("FAIL: uloc_canonicalize(%s) => \"%.*s\", expected \"%s\"\n",
2339 name, reslen, buffer, name);
2340 return;
2341 }
2342}
2343
374ca955
A
2344static void TestDisplayKeywords(void)
2345{
2346 int32_t i;
b75a7d8f 2347
374ca955
A
2348 static const struct {
2349 const char *localeID;
2350 const char *displayLocale;
2351 UChar displayKeyword[200];
2352 } testCases[] = {
2353 { "ca_ES@currency=ESP", "de_AT",
2354 {0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
2355 },
2356 { "ja_JP@calendar=japanese", "de",
2357 { 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
2358 },
2359 { "de_DE@collation=traditional", "de_DE",
2360 {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
2361 },
2362 };
2ca993e8 2363 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
374ca955
A
2364 UErrorCode status = U_ZERO_ERROR;
2365 const char* keyword =NULL;
2366 int32_t keywordLen = 0;
2367 int32_t keywordCount = 0;
2368 UChar *displayKeyword=NULL;
2369 int32_t displayKeywordLen = 0;
2370 UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
2371 for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
2372 if(U_FAILURE(status)){
2373 log_err("uloc_getKeywords failed for locale id: %s with error : %s \n", testCases[i].localeID, u_errorName(status));
2374 break;
2375 }
2376 /* the uenum_next returns NUL terminated string */
2377 keyword = uenum_next(keywordEnum, &keywordLen, &status);
2378 /* fetch the displayKeyword */
2379 displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
2380 if(status==U_BUFFER_OVERFLOW_ERROR){
2381 status = U_ZERO_ERROR;
2382 displayKeywordLen++; /* for null termination */
2383 displayKeyword = (UChar*) malloc(displayKeywordLen * U_SIZEOF_UCHAR);
2384 displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
2385 if(U_FAILURE(status)){
2386 log_err("uloc_getDisplayKeyword filed for keyword : %s in locale id: %s for display locale: %s \n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
2387 break;
2388 }
2389 if(u_strncmp(displayKeyword, testCases[i].displayKeyword, displayKeywordLen)!=0){
729e4ab9
A
2390 if (status == U_USING_DEFAULT_WARNING) {
2391 log_data_err("uloc_getDisplayKeyword did not get the expected value for keyword : %s in locale id: %s for display locale: %s . Got error: %s. Perhaps you are missing data?\n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
2392 } else {
2393 log_err("uloc_getDisplayKeyword did not get the expected value for keyword : %s in locale id: %s for display locale: %s \n", testCases[i].localeID, keyword, testCases[i].displayLocale);
2394 }
374ca955
A
2395 break;
2396 }
2397 }else{
2398 log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status));
2399 }
2400
2401 free(displayKeyword);
2402
2403 }
2404 uenum_close(keywordEnum);
b75a7d8f 2405 }
374ca955 2406}
b75a7d8f 2407
374ca955 2408static void TestDisplayKeywordValues(void){
46f4442e 2409 int32_t i;
374ca955 2410
46f4442e 2411 static const struct {
374ca955
A
2412 const char *localeID;
2413 const char *displayLocale;
2414 UChar displayKeywordValue[500];
2415 } testCases[] = {
2416 { "ca_ES@currency=ESP", "de_AT",
729e4ab9 2417 {0x0053, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0000}
374ca955
A
2418 },
2419 { "de_AT@currency=ATS", "fr_FR",
2420 {0x0073, 0x0063, 0x0068, 0x0069, 0x006c, 0x006c, 0x0069, 0x006e, 0x0067, 0x0020, 0x0061, 0x0075, 0x0074, 0x0072, 0x0069, 0x0063, 0x0068, 0x0069, 0x0065, 0x006e, 0x0000}
2421 },
b331163b
A
2422 { "de_DE@currency=DEM", "it",
2423 {0x006d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0074, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
374ca955
A
2424 },
2425 { "el_GR@currency=GRD", "en",
2426 {0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
2427 },
2428 { "eu_ES@currency=ESP", "it_IT",
b331163b 2429 {0x0070, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0073, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
374ca955
A
2430 },
2431 { "de@collation=phonebook", "es",
2432 {0x006F, 0x0072, 0x0064, 0x0065, 0x006E, 0x0020, 0x0064, 0x0065, 0x0020, 0x006C, 0x0069, 0x0073, 0x0074, 0x00ED, 0x006E, 0x0020, 0x0074, 0x0065, 0x006C, 0x0065, 0x0066, 0x00F3, 0x006E, 0x0069, 0x0063, 0x006F, 0x0000}
2433 },
2434
2435 { "de_DE@collation=phonebook", "es",
2436 {0x006F, 0x0072, 0x0064, 0x0065, 0x006E, 0x0020, 0x0064, 0x0065, 0x0020, 0x006C, 0x0069, 0x0073, 0x0074, 0x00ED, 0x006E, 0x0020, 0x0074, 0x0065, 0x006C, 0x0065, 0x0066, 0x00F3, 0x006E, 0x0069, 0x0063, 0x006F, 0x0000}
2437 },
2438 { "es_ES@collation=traditional","de",
2439 {0x0054, 0x0072, 0x0061, 0x0064, 0x0069, 0x0074, 0x0069, 0x006f, 0x006e, 0x0065, 0x006c, 0x006c, 0x0065, 0x0020, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0072, 0x0065, 0x0067, 0x0065, 0x006c, 0x006e, 0x0000}
2440 },
2441 { "ja_JP@calendar=japanese", "de",
2442 {0x004a, 0x0061, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
2443 },
2444 };
2ca993e8 2445 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
374ca955
A
2446 UErrorCode status = U_ZERO_ERROR;
2447 const char* keyword =NULL;
2448 int32_t keywordLen = 0;
2449 int32_t keywordCount = 0;
2450 UChar *displayKeywordValue = NULL;
2451 int32_t displayKeywordValueLen = 0;
2452 UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
2453 for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
2454 if(U_FAILURE(status)){
2455 log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", testCases[i].localeID, testCases[i].displayLocale, u_errorName(status));
2456 break;
2457 }
2458 /* the uenum_next returns NUL terminated string */
2459 keyword = uenum_next(keywordEnum, &keywordLen, &status);
2460
2461 /* fetch the displayKeywordValue */
2462 displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2463 if(status==U_BUFFER_OVERFLOW_ERROR){
2464 status = U_ZERO_ERROR;
2465 displayKeywordValueLen++; /* for null termination */
2466 displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
2467 displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2468 if(U_FAILURE(status)){
2469 log_err("uloc_getDisplayKeywordValue failed for keyword : %s in locale id: %s for display locale: %s with error : %s \n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
2470 break;
2471 }
2472 if(u_strncmp(displayKeywordValue, testCases[i].displayKeywordValue, displayKeywordValueLen)!=0){
729e4ab9
A
2473 if (status == U_USING_DEFAULT_WARNING) {
2474 log_data_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s with error : %s Perhaps you are missing data\n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
2475 } else {
2476 log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s with error : %s \n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
2477 }
374ca955
A
2478 break;
2479 }
2480 }else{
2481 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
2482 }
2483 free(displayKeywordValue);
2484 }
2485 uenum_close(keywordEnum);
2486 }
2487 {
2488 /* test a multiple keywords */
2489 UErrorCode status = U_ZERO_ERROR;
2490 const char* keyword =NULL;
2491 int32_t keywordLen = 0;
2492 int32_t keywordCount = 0;
2493 const char* localeID = "es@collation=phonebook;calendar=buddhist;currency=DEM";
2494 const char* displayLocale = "de";
46f4442e 2495 static const UChar expected[][50] = {
374ca955
A
2496 {0x0042, 0x0075, 0x0064, 0x0064, 0x0068, 0x0069, 0x0073, 0x0074, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000},
2497
51004dcb 2498 {0x0054, 0x0065, 0x006c, 0x0065, 0x0066, 0x006f, 0x006e, 0x0062, 0x0075, 0x0063, 0x0068, 0x002d, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
374ca955
A
2499 {0x0044, 0x0065, 0x0075, 0x0074, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x004d, 0x0061, 0x0072, 0x006b, 0x0000},
2500 };
2501
2502 UEnumeration* keywordEnum = uloc_openKeywords(localeID, &status);
2503
2504 for(keywordCount = 0; keywordCount < uenum_count(keywordEnum, &status) ; keywordCount++){
2505 UChar *displayKeywordValue = NULL;
2506 int32_t displayKeywordValueLen = 0;
2507 if(U_FAILURE(status)){
2508 log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", localeID, displayLocale, u_errorName(status));
2509 break;
2510 }
2511 /* the uenum_next returns NUL terminated string */
2512 keyword = uenum_next(keywordEnum, &keywordLen, &status);
2513
2514 /* fetch the displayKeywordValue */
2515 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2516 if(status==U_BUFFER_OVERFLOW_ERROR){
2517 status = U_ZERO_ERROR;
2518 displayKeywordValueLen++; /* for null termination */
2519 displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
2520 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2521 if(U_FAILURE(status)){
2522 log_err("uloc_getDisplayKeywordValue failed for keyword : %s in locale id: %s for display locale: %s with error : %s \n", localeID, keyword, displayLocale, u_errorName(status));
2523 break;
2524 }
2525 if(u_strncmp(displayKeywordValue, expected[keywordCount], displayKeywordValueLen)!=0){
729e4ab9
A
2526 if (status == U_USING_DEFAULT_WARNING) {
2527 log_data_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s got error: %s. Perhaps you are missing data?\n", localeID, keyword, displayLocale, u_errorName(status));
2528 } else {
2529 log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s \n", localeID, keyword, displayLocale);
2530 }
374ca955
A
2531 break;
2532 }
2533 }else{
2534 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
2535 }
2536 free(displayKeywordValue);
2537 }
2538 uenum_close(keywordEnum);
2539
2540 }
b75a7d8f 2541 {
374ca955
A
2542 /* Test non existent keywords */
2543 UErrorCode status = U_ZERO_ERROR;
2544 const char* localeID = "es";
2545 const char* displayLocale = "de";
2546 UChar *displayKeywordValue = NULL;
2547 int32_t displayKeywordValueLen = 0;
2548
2549 /* fetch the displayKeywordValue */
2550 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, "calendar", displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2551 if(U_FAILURE(status)) {
2552 log_err("uloc_getDisplaykeywordValue returned error status %s\n", u_errorName(status));
2553 } else if(displayKeywordValueLen != 0) {
2554 log_err("uloc_getDisplaykeywordValue returned %d should be 0 \n", displayKeywordValueLen);
b75a7d8f
A
2555 }
2556 }
374ca955 2557}
b75a7d8f 2558
b75a7d8f 2559
374ca955 2560static void TestGetBaseName(void) {
46f4442e 2561 static const struct {
374ca955
A
2562 const char *localeID;
2563 const char *baseName;
2564 } testCases[] = {
2565 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2566 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2567 { "ja@calendar = buddhist", "ja" }
2568 };
b75a7d8f 2569
374ca955
A
2570 int32_t i = 0, baseNameLen = 0;
2571 char baseName[256];
2572 UErrorCode status = U_ZERO_ERROR;
b75a7d8f 2573
2ca993e8 2574 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
374ca955 2575 baseNameLen = uloc_getBaseName(testCases[i].localeID, baseName, 256, &status);
57a6839d 2576 (void)baseNameLen; /* Suppress set but not used warning. */
374ca955
A
2577 if(strcmp(testCases[i].baseName, baseName)) {
2578 log_err("For locale \"%s\" expected baseName \"%s\", but got \"%s\"\n",
2579 testCases[i].localeID, testCases[i].baseName, baseName);
2580 return;
2581 }
b75a7d8f 2582 }
b75a7d8f
A
2583}
2584
729e4ab9
A
2585static void TestTrailingNull(void) {
2586 const char* localeId = "zh_Hans";
2587 UChar buffer[128]; /* sufficient for this test */
2588 int32_t len;
2589 UErrorCode status = U_ZERO_ERROR;
2590 int i;
2591
2592 len = uloc_getDisplayName(localeId, localeId, buffer, 128, &status);
2593 if (len > 128) {
2594 log_err("buffer too small");
2595 return;
2596 }
2597
2598 for (i = 0; i < len; ++i) {
2599 if (buffer[i] == 0) {
2600 log_err("name contained null");
2601 return;
2602 }
2603 }
2604}
b75a7d8f 2605
374ca955
A
2606/* Jitterbug 4115 */
2607static void TestDisplayNameWarning(void) {
2608 UChar name[256];
2609 int32_t size;
2610 UErrorCode status = U_ZERO_ERROR;
2611
2ca993e8 2612 size = uloc_getDisplayLanguage("qqq", "kl", name, UPRV_LENGTHOF(name), &status);
57a6839d 2613 (void)size; /* Suppress set but not used warning. */
374ca955
A
2614 if (status != U_USING_DEFAULT_WARNING) {
2615 log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2616 u_errorName(status));
2617 }
2618}
b75a7d8f 2619
b75a7d8f 2620
374ca955
A
2621/**
2622 * Compare two locale IDs. If they are equal, return 0. If `string'
2623 * starts with `prefix' plus an additional element, that is, string ==
2624 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2625 */
2626static UBool _loccmp(const char* string, const char* prefix) {
73c04bcf
A
2627 int32_t slen = (int32_t)uprv_strlen(string),
2628 plen = (int32_t)uprv_strlen(prefix);
374ca955
A
2629 int32_t c = uprv_strncmp(string, prefix, plen);
2630 /* 'root' is less than everything */
2631 if (uprv_strcmp(prefix, "root") == 0) {
2632 return (uprv_strcmp(string, "root") == 0) ? 0 : 1;
2633 }
2634 if (c) return -1; /* mismatch */
2635 if (slen == plen) return 0;
2636 if (string[plen] == '_') return 1;
2637 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2638}
b75a7d8f 2639
374ca955
A
2640static void _checklocs(const char* label,
2641 const char* req,
2642 const char* valid,
2643 const char* actual) {
2644 /* We want the valid to be strictly > the bogus requested locale,
2645 and the valid to be >= the actual. */
2646 if (_loccmp(req, valid) > 0 &&
2647 _loccmp(valid, actual) >= 0) {
2648 log_verbose("%s; req=%s, valid=%s, actual=%s\n",
2649 label, req, valid, actual);
2650 } else {
2651 log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
2652 label, req, valid, actual);
b75a7d8f
A
2653 }
2654}
2655
374ca955
A
2656static void TestGetLocale(void) {
2657 UErrorCode ec = U_ZERO_ERROR;
2658 UParseError pe;
2659 UChar EMPTY[1] = {0};
b75a7d8f 2660
374ca955
A
2661 /* === udat === */
2662#if !UCONFIG_NO_FORMATTING
2663 {
2664 UDateFormat *obj;
2665 const char *req = "en_US_REDWOODSHORES", *valid, *actual;
2666 obj = udat_open(UDAT_DEFAULT, UDAT_DEFAULT,
2667 req,
2668 NULL, 0,
2669 NULL, 0, &ec);
2670 if (U_FAILURE(ec)) {
729e4ab9 2671 log_data_err("udat_open failed.Error %s\n", u_errorName(ec));
374ca955
A
2672 return;
2673 }
2674 valid = udat_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2675 actual = udat_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2676 if (U_FAILURE(ec)) {
2677 log_err("udat_getLocaleByType() failed\n");
2678 return;
2679 }
2680 _checklocs("udat", req, valid, actual);
2681 udat_close(obj);
b75a7d8f 2682 }
374ca955 2683#endif
b75a7d8f 2684
374ca955
A
2685 /* === ucal === */
2686#if !UCONFIG_NO_FORMATTING
2687 {
2688 UCalendar *obj;
2689 const char *req = "fr_FR_PROVENCAL", *valid, *actual;
2690 obj = ucal_open(NULL, 0,
2691 req,
2692 UCAL_GREGORIAN,
2693 &ec);
2694 if (U_FAILURE(ec)) {
2695 log_err("ucal_open failed with error: %s\n", u_errorName(ec));
2696 return;
2697 }
2698 valid = ucal_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2699 actual = ucal_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2700 if (U_FAILURE(ec)) {
2701 log_err("ucal_getLocaleByType() failed\n");
2702 return;
2703 }
2704 _checklocs("ucal", req, valid, actual);
2705 ucal_close(obj);
b75a7d8f 2706 }
374ca955 2707#endif
b75a7d8f 2708
374ca955
A
2709 /* === unum === */
2710#if !UCONFIG_NO_FORMATTING
2711 {
2712 UNumberFormat *obj;
2713 const char *req = "zh_Hant_TW_TAINAN", *valid, *actual;
2714 obj = unum_open(UNUM_DECIMAL,
2715 NULL, 0,
2716 req,
2717 &pe, &ec);
2718 if (U_FAILURE(ec)) {
2719 log_err("unum_open failed\n");
2720 return;
2721 }
2722 valid = unum_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2723 actual = unum_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2724 if (U_FAILURE(ec)) {
2725 log_err("unum_getLocaleByType() failed\n");
2726 return;
2727 }
2728 _checklocs("unum", req, valid, actual);
2729 unum_close(obj);
2730 }
2731#endif
b75a7d8f 2732
374ca955 2733 /* === umsg === */
73c04bcf
A
2734#if 0
2735 /* commented out by weiv 01/12/2005. umsg_getLocaleByType is to be removed */
374ca955
A
2736#if !UCONFIG_NO_FORMATTING
2737 {
2738 UMessageFormat *obj;
2739 const char *req = "ja_JP_TAKAYAMA", *valid, *actual;
2740 UBool test;
2741 obj = umsg_open(EMPTY, 0,
2742 req,
2743 &pe, &ec);
2744 if (U_FAILURE(ec)) {
2745 log_err("umsg_open failed\n");
2746 return;
2747 }
2748 valid = umsg_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2749 actual = umsg_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2750 if (U_FAILURE(ec)) {
2751 log_err("umsg_getLocaleByType() failed\n");
2752 return;
2753 }
2754 /* We want the valid to be strictly > the bogus requested locale,
2755 and the valid to be >= the actual. */
2756 /* TODO MessageFormat is currently just storing the locale it is given.
2757 As a result, it will return whatever it was given, even if the
2758 locale is invalid. */
2759 test = (_cmpversion("3.2") <= 0) ?
2760 /* Here is the weakened test for 3.0: */
2761 (_loccmp(req, valid) >= 0) :
2762 /* Here is what the test line SHOULD be: */
2763 (_loccmp(req, valid) > 0);
2764
2765 if (test &&
2766 _loccmp(valid, actual) >= 0) {
2767 log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
2768 } else {
2769 log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
2770 }
2771 umsg_close(obj);
2772 }
73c04bcf 2773#endif
374ca955 2774#endif
b75a7d8f 2775
374ca955
A
2776 /* === ubrk === */
2777#if !UCONFIG_NO_BREAK_ITERATION
2778 {
2779 UBreakIterator *obj;
2780 const char *req = "ar_KW_ABDALI", *valid, *actual;
2781 obj = ubrk_open(UBRK_WORD,
2782 req,
2783 EMPTY,
2784 0,
2785 &ec);
2786 if (U_FAILURE(ec)) {
73c04bcf 2787 log_err("ubrk_open failed. Error: %s \n", u_errorName(ec));
374ca955
A
2788 return;
2789 }
2790 valid = ubrk_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2791 actual = ubrk_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2792 if (U_FAILURE(ec)) {
2793 log_err("ubrk_getLocaleByType() failed\n");
2794 return;
2795 }
2796 _checklocs("ubrk", req, valid, actual);
2797 ubrk_close(obj);
2798 }
2799#endif
b75a7d8f 2800
374ca955
A
2801 /* === ucol === */
2802#if !UCONFIG_NO_COLLATION
2803 {
2804 UCollator *obj;
2805 const char *req = "es_AR_BUENOSAIRES", *valid, *actual;
2806 obj = ucol_open(req, &ec);
2807 if (U_FAILURE(ec)) {
729e4ab9 2808 log_err("ucol_open failed - %s\n", u_errorName(ec));
374ca955
A
2809 return;
2810 }
2811 valid = ucol_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2812 actual = ucol_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2813 if (U_FAILURE(ec)) {
2814 log_err("ucol_getLocaleByType() failed\n");
2815 return;
2816 }
2817 _checklocs("ucol", req, valid, actual);
2818 ucol_close(obj);
2819 }
2820#endif
2821}
51004dcb
A
2822static void TestEnglishExemplarCharacters(void) {
2823 UErrorCode status = U_ZERO_ERROR;
2824 int i;
2825 USet *exSet = NULL;
2826 UChar testChars[] = {
2827 0x61, /* standard */
2828 0xE1, /* auxiliary */
2829 0x41, /* index */
2830 0x2D /* punctuation */
2831 };
2832 ULocaleData *uld = ulocdata_open("en", &status);
2833 if (U_FAILURE(status)) {
2834 log_data_err("ulocdata_open() failed : %s - (Are you missing data?)\n", u_errorName(status));
2835 return;
2836 }
2837
2838 for (i = 0; i < ULOCDATA_ES_COUNT; i++) {
2839 exSet = ulocdata_getExemplarSet(uld, exSet, 0, (ULocaleDataExemplarSetType)i, &status);
2840 if (U_FAILURE(status)) {
2841 log_err_status(status, "ulocdata_getExemplarSet() for type %d failed\n", i);
2842 status = U_ZERO_ERROR;
2843 continue;
2844 }
2845 if (!uset_contains(exSet, (UChar32)testChars[i])) {
2846 log_err("Character U+%04X is not included in exemplar type %d\n", testChars[i], i);
2847 }
2848 }
2849
2850 uset_close(exSet);
2851 ulocdata_close(uld);
2852}
b75a7d8f 2853
374ca955
A
2854static void TestNonexistentLanguageExemplars(void) {
2855 /* JB 4068 - Nonexistent language */
2856 UErrorCode ec = U_ZERO_ERROR;
73c04bcf 2857 ULocaleData *uld = ulocdata_open("qqq",&ec);
374ca955 2858 if (ec != U_USING_DEFAULT_WARNING) {
729e4ab9 2859 log_err_status(ec, "Exemplar set for \"qqq\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
374ca955 2860 u_errorName(ec));
b75a7d8f 2861 }
73c04bcf
A
2862 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2863 ulocdata_close(uld);
2864}
2865
46f4442e
A
2866static void TestLocDataErrorCodeChaining(void) {
2867 UErrorCode ec = U_USELESS_COLLATOR_ERROR;
2868 ulocdata_open(NULL, &ec);
2869 ulocdata_getExemplarSet(NULL, NULL, 0, ULOCDATA_ES_STANDARD, &ec);
2870 ulocdata_getDelimiter(NULL, ULOCDATA_DELIMITER_COUNT, NULL, -1, &ec);
2871 ulocdata_getMeasurementSystem(NULL, &ec);
2872 ulocdata_getPaperSize(NULL, NULL, NULL, &ec);
2873 if (ec != U_USELESS_COLLATOR_ERROR) {
2874 log_err("ulocdata API changed the error code to %s\n", u_errorName(ec));
2875 }
2876}
2877
2ca993e8
A
2878typedef struct {
2879 const char* locale;
2880 UMeasurementSystem measureSys;
2881} LocToMeasureSys;
2882
2883static const LocToMeasureSys locToMeasures[] = {
2884 { "fr_FR", UMS_SI },
2885 { "en", UMS_US },
2886 { "en_GB", UMS_UK },
2887 { "fr_FR@rg=GBZZZZ", UMS_UK },
2888 { "en@rg=frzzzz", UMS_SI },
2889 { "en_GB@rg=USZZZZ", UMS_US },
2890 { NULL, (UMeasurementSystem)0 } /* terminator */
2891};
2892
2893static void TestLocDataWithRgTag(void) {
2894 const LocToMeasureSys* locToMeasurePtr = locToMeasures;
2895 for (; locToMeasurePtr->locale != NULL; locToMeasurePtr++) {
2896 UErrorCode status = U_ZERO_ERROR;
2897 UMeasurementSystem measureSys = ulocdata_getMeasurementSystem(locToMeasurePtr->locale, &status);
2898 if (U_FAILURE(status)) {
2899 log_data_err("ulocdata_getMeasurementSystem(\"%s\", ...) failed: %s - Are you missing data?\n",
2900 locToMeasurePtr->locale, u_errorName(status));
2901 } else if (measureSys != locToMeasurePtr->measureSys) {
2902 log_err("ulocdata_getMeasurementSystem(\"%s\", ...), expected %d, got %d\n",
2903 locToMeasurePtr->locale, (int) locToMeasurePtr->measureSys, (int)measureSys);
2904 }
2905 }
2906}
2907
73c04bcf
A
2908static void TestLanguageExemplarsFallbacks(void) {
2909 /* Test that en_US fallsback, but en doesn't fallback. */
2910 UErrorCode ec = U_ZERO_ERROR;
2911 ULocaleData *uld = ulocdata_open("en_US",&ec);
2912 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2913 if (ec != U_USING_FALLBACK_WARNING) {
729e4ab9 2914 log_err_status(ec, "Exemplar set for \"en_US\", expecting U_USING_FALLBACK_WARNING, but got %s\n",
73c04bcf
A
2915 u_errorName(ec));
2916 }
2917 ulocdata_close(uld);
2918 ec = U_ZERO_ERROR;
2919 uld = ulocdata_open("en",&ec);
2920 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2921 if (ec != U_ZERO_ERROR) {
729e4ab9 2922 log_err_status(ec, "Exemplar set for \"en\", expecting U_ZERO_ERROR, but got %s\n",
73c04bcf
A
2923 u_errorName(ec));
2924 }
2925 ulocdata_close(uld);
374ca955 2926}
b75a7d8f 2927
729e4ab9
A
2928static const char *acceptResult(UAcceptResult uar) {
2929 return udbg_enumName(UDBG_UAcceptResult, uar);
2930}
2931
374ca955 2932static void TestAcceptLanguage(void) {
46f4442e
A
2933 UErrorCode status = U_ZERO_ERROR;
2934 UAcceptResult outResult;
2935 UEnumeration *available;
2936 char tmp[200];
2937 int i;
2938 int32_t rc = 0;
2939
2940 struct {
729e4ab9
A
2941 int32_t httpSet; /**< Which of http[] should be used? */
2942 const char *icuSet; /**< ? */
2943 const char *expect; /**< The expected locale result */
2944 UAcceptResult res; /**< The expected error code */
f3c0d7a5 2945 UErrorCode expectStatus; /**< expected status */
46f4442e 2946 } tests[] = {
f3c0d7a5
A
2947 /*0*/{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
2948 /*1*/{ 1, NULL, "en", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
2949 /*2*/{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR},
2950 /*3*/{ 3, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR},
2951 /*4*/{ 4, NULL, "es", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
2952 /*5*/{ 5, NULL, "en", ULOC_ACCEPT_VALID, U_ZERO_ERROR}, /* XF */
2953 /*6*/{ 6, NULL, "ja", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR}, /* XF */
2954 /*7*/{ 7, NULL, "zh", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR}, /* XF */
2955 /*8*/{ 8, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR }, /* */
2956 /*9*/{ 9, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR }, /* */
2957 /*10*/{10, NULL, "", ULOC_ACCEPT_FAILED, U_BUFFER_OVERFLOW_ERROR }, /* */
2958 /*11*/{11, NULL, "", ULOC_ACCEPT_FAILED, U_BUFFER_OVERFLOW_ERROR }, /* */
46f4442e 2959 };
2ca993e8 2960 const int32_t numTests = UPRV_LENGTHOF(tests);
46f4442e
A
2961 static const char *http[] = {
2962 /*0*/ "mt-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, th-th-traditional;q=.01",
2963 /*1*/ "ja;q=0.5, en;q=0.8, tlh",
2964 /*2*/ "en-wf, de-lx;q=0.8",
2965 /*3*/ "mga-ie;q=0.9, tlh",
2966 /*4*/ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2967 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2968 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2969 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2970 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2971 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2972 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
729e4ab9 2973 "es",
729e4ab9
A
2974 /*5*/ "zh-xx;q=0.9, en;q=0.6",
2975 /*6*/ "ja-JA",
2976 /*7*/ "zh-xx;q=0.9",
f3c0d7a5
A
2977 /*08*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2978 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2979 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2980 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // 156
2981 /*09*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2982 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2983 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2984 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", // 157 (this hits U_STRING_NOT_TERMINATED_WARNING )
2985 /*10*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2986 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2987 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2988 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABC", // 158
2989 /*11*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2990 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2991 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2992 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // 163 bytes
46f4442e 2993 };
374ca955 2994
46f4442e
A
2995 for(i=0;i<numTests;i++) {
2996 outResult = -3;
2997 status=U_ZERO_ERROR;
729e4ab9
A
2998 log_verbose("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2999 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, acceptResult(tests[i].res));
46f4442e
A
3000
3001 available = ures_openAvailableLocales(tests[i].icuSet, &status);
3002 tmp[0]=0;
3003 rc = uloc_acceptLanguageFromHTTP(tmp, 199, &outResult, http[tests[i].httpSet], available, &status);
57a6839d 3004 (void)rc; /* Suppress set but not used warning. */
46f4442e 3005 uenum_close(available);
729e4ab9 3006 log_verbose(" got %s, %s [%s]\n", tmp[0]?tmp:"(EMPTY)", acceptResult(outResult), u_errorName(status));
f3c0d7a5
A
3007 if(status != tests[i].expectStatus) {
3008 log_err_status(status, "FAIL: expected status %s but got %s\n", u_errorName(tests[i].expectStatus), u_errorName(status));
3009 } else if(U_SUCCESS(tests[i].expectStatus)) {
3010 /* don't check content if expected failure */
3011 if(outResult != tests[i].res) {
729e4ab9
A
3012 log_err_status(status, "FAIL: #%d: expected outResult of %s but got %s\n", i,
3013 acceptResult( tests[i].res),
3014 acceptResult( outResult));
3015 log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
3016 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect,acceptResult(tests[i].res));
f3c0d7a5
A
3017 }
3018 if((outResult>0)&&uprv_strcmp(tmp, tests[i].expect)) {
3019 log_err_status(status, "FAIL: #%d: expected %s but got %s\n", i, tests[i].expect, tmp);
3020 log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
3021 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, acceptResult(tests[i].res));
3022 }
46f4442e 3023 }
374ca955 3024 }
b75a7d8f 3025}
73c04bcf
A
3026
3027static const char* LOCALE_ALIAS[][2] = {
3028 {"in", "id"},
3029 {"in_ID", "id_ID"},
3030 {"iw", "he"},
3031 {"iw_IL", "he_IL"},
3032 {"ji", "yi"},
3033 {"en_BU", "en_MM"},
3034 {"en_DY", "en_BJ"},
3035 {"en_HV", "en_BF"},
3036 {"en_NH", "en_VU"},
3037 {"en_RH", "en_ZW"},
3038 {"en_TP", "en_TL"},
3039 {"en_ZR", "en_CD"}
3040};
3041static UBool isLocaleAvailable(UResourceBundle* resIndex, const char* loc){
3042 UErrorCode status = U_ZERO_ERROR;
3043 int32_t len = 0;
3044 ures_getStringByKey(resIndex, loc,&len, &status);
3045 if(U_FAILURE(status)){
3046 return FALSE;
3047 }
3048 return TRUE;
3049}
3050
3051static void TestCalendar() {
3052#if !UCONFIG_NO_FORMATTING
3053 int i;
3054 UErrorCode status = U_ZERO_ERROR;
3055 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
3056 if(U_FAILURE(status)){
729e4ab9 3057 log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
73c04bcf
A
3058 return;
3059 }
b331163b 3060 for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
73c04bcf
A
3061 const char* oldLoc = LOCALE_ALIAS[i][0];
3062 const char* newLoc = LOCALE_ALIAS[i][1];
3063 UCalendar* c1 = NULL;
3064 UCalendar* c2 = NULL;
3065
3066 /*Test function "getLocale(ULocale.VALID_LOCALE)"*/
3067 const char* l1 = ucal_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
3068 const char* l2 = ucal_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
3069
3070 if(!isLocaleAvailable(resIndex, newLoc)){
3071 continue;
3072 }
3073 c1 = ucal_open(NULL, -1, oldLoc, UCAL_GREGORIAN, &status);
3074 c2 = ucal_open(NULL, -1, newLoc, UCAL_GREGORIAN, &status);
3075
3076 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0 || status!=U_ZERO_ERROR) {
3077 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
3078 }
3079 log_verbose("ucal_getLocaleByType old:%s new:%s\n", l1, l2);
3080 ucal_close(c1);
3081 ucal_close(c2);
3082 }
3083 ures_close(resIndex);
3084#endif
3085}
3086
3087static void TestDateFormat() {
3088#if !UCONFIG_NO_FORMATTING
3089 int i;
3090 UErrorCode status = U_ZERO_ERROR;
3091 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
3092 if(U_FAILURE(status)){
729e4ab9 3093 log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
73c04bcf
A
3094 return;
3095 }
b331163b 3096 for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
73c04bcf
A
3097 const char* oldLoc = LOCALE_ALIAS[i][0];
3098 const char* newLoc = LOCALE_ALIAS[i][1];
3099 UDateFormat* df1 = NULL;
3100 UDateFormat* df2 = NULL;
3101 const char* l1 = NULL;
3102 const char* l2 = NULL;
3103
3104 if(!isLocaleAvailable(resIndex, newLoc)){
3105 continue;
3106 }
3107 df1 = udat_open(UDAT_FULL, UDAT_FULL,oldLoc, NULL, 0, NULL, -1, &status);
3108 df2 = udat_open(UDAT_FULL, UDAT_FULL,newLoc, NULL, 0, NULL, -1, &status);
3109 if(U_FAILURE(status)){
3110 log_err("Creation of date format failed %s\n", u_errorName(status));
3111 return;
3112 }
3113 /*Test function "getLocale"*/
3114 l1 = udat_getLocaleByType(df1, ULOC_VALID_LOCALE, &status);
3115 l2 = udat_getLocaleByType(df2, ULOC_VALID_LOCALE, &status);
3116 if(U_FAILURE(status)){
3117 log_err("Fetching the locale by type failed. %s\n", u_errorName(status));
3118 }
3119 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
3120 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
3121 }
3122 log_verbose("udat_getLocaleByType old:%s new:%s\n", l1, l2);
3123 udat_close(df1);
3124 udat_close(df2);
3125 }
3126 ures_close(resIndex);
3127#endif
3128}
3129
3130static void TestCollation() {
3131#if !UCONFIG_NO_COLLATION
3132 int i;
3133 UErrorCode status = U_ZERO_ERROR;
3134 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
3135 if(U_FAILURE(status)){
729e4ab9 3136 log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
73c04bcf
A
3137 return;
3138 }
b331163b 3139 for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
73c04bcf
A
3140 const char* oldLoc = LOCALE_ALIAS[i][0];
3141 const char* newLoc = LOCALE_ALIAS[i][1];
3142 UCollator* c1 = NULL;
3143 UCollator* c2 = NULL;
3144 const char* l1 = NULL;
3145 const char* l2 = NULL;
3146
3147 status = U_ZERO_ERROR;
3148 if(!isLocaleAvailable(resIndex, newLoc)){
3149 continue;
3150 }
3151 if(U_FAILURE(status)){
3152 log_err("Creation of collators failed %s\n", u_errorName(status));
3153 return;
3154 }
3155 c1 = ucol_open(oldLoc, &status);
3156 c2 = ucol_open(newLoc, &status);
3157 l1 = ucol_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
3158 l2 = ucol_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
3159 if(U_FAILURE(status)){
3160 log_err("Fetching the locale names failed failed %s\n", u_errorName(status));
3161 }
3162 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
3163 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
3164 }
3165 log_verbose("ucol_getLocaleByType old:%s new:%s\n", l1, l2);
3166 ucol_close(c1);
3167 ucol_close(c2);
3168 }
3169 ures_close(resIndex);
3170#endif
3171}
3172
46f4442e
A
3173typedef struct OrientationStructTag {
3174 const char* localeId;
3175 ULayoutType character;
3176 ULayoutType line;
3177} OrientationStruct;
3178
729e4ab9 3179static const char* ULayoutTypeToString(ULayoutType type)
46f4442e
A
3180{
3181 switch(type)
3182 {
3183 case ULOC_LAYOUT_LTR:
3184 return "ULOC_LAYOUT_LTR";
3185 break;
3186 case ULOC_LAYOUT_RTL:
3187 return "ULOC_LAYOUT_RTL";
3188 break;
3189 case ULOC_LAYOUT_TTB:
3190 return "ULOC_LAYOUT_TTB";
3191 break;
3192 case ULOC_LAYOUT_BTT:
3193 return "ULOC_LAYOUT_BTT";
3194 break;
3195 case ULOC_LAYOUT_UNKNOWN:
3196 break;
3197 }
3198
3199 return "Unknown enum value for ULayoutType!";
3200}
3201
3202static void TestOrientation()
3203{
3204 static const OrientationStruct toTest [] = {
3205 { "ar", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3206 { "aR", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3207 { "ar_Arab", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3208 { "fa", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3209 { "Fa", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3210 { "he", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3211 { "ps", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3212 { "ur", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3213 { "UR", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3d1f044b
A
3214 { "en", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3215 // Additional Apple tests for rdar://51447187
3216 { "sd", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3217 { "sd_Arab", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3218 { "sd_Deva", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3219 { "mni_Beng", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3220 { "mni_Mtei", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3221 { "sat_Deva", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3222 { "sat_Olck", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3223 { "ks", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3224 { "ks_Arab", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3225 { "ks_Aran", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3226 { "ks_Deva", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3227 { "pa", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3228 { "pa_Guru", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB },
3229 { "pa_Arab", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3230 { "pa_Aran", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3231 { "ur", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3232 { "ur_Arab", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
3233 { "ur_Aran", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
46f4442e
A
3234 };
3235
3236 size_t i = 0;
2ca993e8 3237 for (; i < UPRV_LENGTHOF(toTest); ++i) {
46f4442e
A
3238 UErrorCode statusCO = U_ZERO_ERROR;
3239 UErrorCode statusLO = U_ZERO_ERROR;
3240 const char* const localeId = toTest[i].localeId;
3241 const ULayoutType co = uloc_getCharacterOrientation(localeId, &statusCO);
3242 const ULayoutType expectedCO = toTest[i].character;
3243 const ULayoutType lo = uloc_getLineOrientation(localeId, &statusLO);
3244 const ULayoutType expectedLO = toTest[i].line;
3245 if (U_FAILURE(statusCO)) {
729e4ab9 3246 log_err_status(statusCO,
46f4442e
A
3247 " unexpected failure for uloc_getCharacterOrientation(), with localId \"%s\" and status %s\n",
3248 localeId,
3249 u_errorName(statusCO));
3250 }
3251 else if (co != expectedCO) {
3252 log_err(
3253 " unexpected result for uloc_getCharacterOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
3254 localeId,
3255 ULayoutTypeToString(expectedCO),
3256 ULayoutTypeToString(co));
3257 }
3258 if (U_FAILURE(statusLO)) {
729e4ab9 3259 log_err_status(statusLO,
46f4442e
A
3260 " unexpected failure for uloc_getLineOrientation(), with localId \"%s\" and status %s\n",
3261 localeId,
3262 u_errorName(statusLO));
3263 }
3264 else if (lo != expectedLO) {
3265 log_err(
3266 " unexpected result for uloc_getLineOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
3267 localeId,
3268 ULayoutTypeToString(expectedLO),
3269 ULayoutTypeToString(lo));
3270 }
3271 }
3272}
3273
73c04bcf
A
3274static void TestULocale() {
3275 int i;
3276 UErrorCode status = U_ZERO_ERROR;
3277 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
3278 if(U_FAILURE(status)){
729e4ab9 3279 log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
73c04bcf
A
3280 return;
3281 }
b331163b 3282 for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
73c04bcf
A
3283 const char* oldLoc = LOCALE_ALIAS[i][0];
3284 const char* newLoc = LOCALE_ALIAS[i][1];
3285 UChar name1[256], name2[256];
3286 char names1[256], names2[256];
3287 int32_t capacity = 256;
3288
3289 status = U_ZERO_ERROR;
3290 if(!isLocaleAvailable(resIndex, newLoc)){
3291 continue;
3292 }
3293 uloc_getDisplayName(oldLoc, ULOC_US, name1, capacity, &status);
3294 if(U_FAILURE(status)){
3295 log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc, u_errorName(status));
3296 }
3297
3298 uloc_getDisplayName(newLoc, ULOC_US, name2, capacity, &status);
3299 if(U_FAILURE(status)){
3300 log_err("uloc_getDisplayName(%s) failed %s\n", newLoc, u_errorName(status));
3301 }
3302
3303 if (u_strcmp(name1, name2)!=0) {
3304 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
3305 }
3306 u_austrcpy(names1, name1);
3307 u_austrcpy(names2, name2);
3308 log_verbose("uloc_getDisplayName old:%s new:%s\n", names1, names2);
3309 }
3310 ures_close(resIndex);
3311
3312}
3313
3314static void TestUResourceBundle() {
3315 const char* us1;
3316 const char* us2;
3317
3318 UResourceBundle* rb1 = NULL;
3319 UResourceBundle* rb2 = NULL;
3320 UErrorCode status = U_ZERO_ERROR;
3321 int i;
3322 UResourceBundle *resIndex = NULL;
3323 if(U_FAILURE(status)){
3324 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
3325 return;
3326 }
3327 resIndex = ures_open(NULL,"res_index", &status);
b331163b 3328 for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
73c04bcf
A
3329
3330 const char* oldLoc = LOCALE_ALIAS[i][0];
3331 const char* newLoc = LOCALE_ALIAS[i][1];
3332 if(!isLocaleAvailable(resIndex, newLoc)){
3333 continue;
3334 }
3335 rb1 = ures_open(NULL, oldLoc, &status);
46f4442e 3336 if (U_FAILURE(status)) {
73c04bcf
A
3337 log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
3338 }
3339
729e4ab9 3340 us1 = ures_getLocaleByType(rb1, ULOC_ACTUAL_LOCALE, &status);
73c04bcf
A
3341
3342 status = U_ZERO_ERROR;
3343 rb2 = ures_open(NULL, newLoc, &status);
46f4442e 3344 if (U_FAILURE(status)) {
73c04bcf
A
3345 log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
3346 }
729e4ab9 3347 us2 = ures_getLocaleByType(rb2, ULOC_ACTUAL_LOCALE, &status);
73c04bcf
A
3348
3349 if (strcmp(us1,newLoc)!=0 || strcmp(us1,us2)!=0 ) {
3350 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
3351 }
3352
3353 log_verbose("ures_getStringByKey old:%s new:%s\n", us1, us2);
3354 ures_close(rb1);
3355 rb1 = NULL;
3356 ures_close(rb2);
3357 rb2 = NULL;
3358 }
3359 ures_close(resIndex);
3360}
3361
3362static void TestDisplayName() {
3363
3364 UChar oldCountry[256] = {'\0'};
3365 UChar newCountry[256] = {'\0'};
3366 UChar oldLang[256] = {'\0'};
3367 UChar newLang[256] = {'\0'};
3368 char country[256] ={'\0'};
3369 char language[256] ={'\0'};
3370 int32_t capacity = 256;
3371 int i =0;
3372 int j=0;
b331163b 3373 for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
73c04bcf
A
3374 const char* oldLoc = LOCALE_ALIAS[i][0];
3375 const char* newLoc = LOCALE_ALIAS[i][1];
3376 UErrorCode status = U_ZERO_ERROR;
3377 int32_t available = uloc_countAvailable();
3378
3379 for(j=0; j<available; j++){
3380
3381 const char* dispLoc = uloc_getAvailable(j);
3382 int32_t oldCountryLen = uloc_getDisplayCountry(oldLoc,dispLoc, oldCountry, capacity, &status);
3383 int32_t newCountryLen = uloc_getDisplayCountry(newLoc, dispLoc, newCountry, capacity, &status);
3384 int32_t oldLangLen = uloc_getDisplayLanguage(oldLoc, dispLoc, oldLang, capacity, &status);
3385 int32_t newLangLen = uloc_getDisplayLanguage(newLoc, dispLoc, newLang, capacity, &status );
3386
3387 int32_t countryLen = uloc_getCountry(newLoc, country, capacity, &status);
3388 int32_t langLen = uloc_getLanguage(newLoc, language, capacity, &status);
3389 /* there is a display name for the current country ID */
3390 if(countryLen != newCountryLen ){
3391 if(u_strncmp(oldCountry,newCountry,oldCountryLen)!=0){
3392 log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc, dispLoc);
3393 }
3394 }
3395 /* there is a display name for the current lang ID */
3396 if(langLen!=newLangLen){
3397 if(u_strncmp(oldLang,newLang,oldLangLen)){
3398 log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc, dispLoc); }
3399 }
3400 }
3401 }
3402}
3403
3404static void TestGetLocaleForLCID() {
3405 int32_t i, length, lengthPre;
3406 const char* testLocale = 0;
3407 UErrorCode status = U_ZERO_ERROR;
73c04bcf
A
3408 char temp2[40], temp3[40];
3409 uint32_t lcid;
3410
3411 lcid = uloc_getLCID("en_US");
3412 if (lcid != 0x0409) {
3413 log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid);
3414 }
3415
3416 lengthPre = uloc_getLocaleForLCID(lcid, temp2, 4, &status);
3417 if (status != U_BUFFER_OVERFLOW_ERROR) {
3418 log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status));
3419 }
3420 else {
3421 status = U_ZERO_ERROR;
3422 }
3423
2ca993e8 3424 length = uloc_getLocaleForLCID(lcid, temp2, UPRV_LENGTHOF(temp2), &status);
73c04bcf
A
3425 if (U_FAILURE(status)) {
3426 log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status));
3427 status = U_ZERO_ERROR;
3428 }
3429
3430 if (length != lengthPre) {
3431 log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length, lengthPre);
3432 }
3433
2ca993e8 3434 length = uloc_getLocaleForLCID(0x12345, temp2, UPRV_LENGTHOF(temp2), &status);
73c04bcf
A
3435 if (U_SUCCESS(status)) {
3436 log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2, u_errorName(status));
3437 }
3438 status = U_ZERO_ERROR;
3439
3440 log_verbose("Testing getLocaleForLCID vs. locale data\n");
3441 for (i = 0; i < LOCALE_SIZE; i++) {
3442
3443 testLocale=rawData2[NAME][i];
3444
3445 log_verbose("Testing %s ......\n", testLocale);
3446
3447 sscanf(rawData2[LCID][i], "%x", &lcid);
2ca993e8 3448 length = uloc_getLocaleForLCID(lcid, temp2, UPRV_LENGTHOF(temp2), &status);
73c04bcf
A
3449 if (U_FAILURE(status)) {
3450 log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid, u_errorName(status));
3451 status = U_ZERO_ERROR;
3452 continue;
3453 }
3454
3455 if (length != uprv_strlen(temp2)) {
3456 log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length, lcid, uprv_strlen(temp2));
3457 }
3458
3459 /* Compare language, country, script */
2ca993e8 3460 length = uloc_getLanguage(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
73c04bcf
A
3461 if (U_FAILURE(status)) {
3462 log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
3463 status = U_ZERO_ERROR;
3464 }
3465 else if (uprv_strcmp(temp3, rawData2[LANG][i]) && !(uprv_strcmp(temp3, "nn") == 0 && uprv_strcmp(rawData2[VAR][i], "NY") == 0)) {
3466 log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[LANG][i], lcid, temp2);
3467 }
3468
2ca993e8 3469 length = uloc_getScript(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
73c04bcf
A
3470 if (U_FAILURE(status)) {
3471 log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
3472 status = U_ZERO_ERROR;
3473 }
3474 else if (uprv_strcmp(temp3, rawData2[SCRIPT][i])) {
3475 log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[SCRIPT][i], lcid, temp2);
3476 }
3477
2ca993e8 3478 length = uloc_getCountry(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
73c04bcf
A
3479 if (U_FAILURE(status)) {
3480 log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
3481 status = U_ZERO_ERROR;
3482 }
3483 else if (uprv_strlen(rawData2[CTRY][i]) && uprv_strcmp(temp3, rawData2[CTRY][i])) {
3484 log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[CTRY][i], lcid, temp2);
3485 }
3486 }
3487
3488}
3489
46f4442e
A
3490const char* const basic_maximize_data[][2] = {
3491 {
3492 "zu_Zzzz_Zz",
3493 "zu_Latn_ZA",
3494 }, {
3495 "ZU_Zz",
3496 "zu_Latn_ZA"
3497 }, {
3498 "zu_LATN",
3499 "zu_Latn_ZA"
3500 }, {
3501 "en_Zz",
3502 "en_Latn_US"
3503 }, {
3504 "en_us",
3505 "en_Latn_US"
3506 }, {
3507 "en_Kore",
3508 "en_Kore_US"
3509 }, {
3510 "en_Kore_Zz",
3511 "en_Kore_US"
3512 }, {
3513 "en_Kore_ZA",
3514 "en_Kore_ZA"
3515 }, {
3516 "en_Kore_ZA_POSIX",
3517 "en_Kore_ZA_POSIX"
3518 }, {
3519 "en_Gujr",
3520 "en_Gujr_US"
3521 }, {
3522 "en_ZA",
3523 "en_Latn_ZA"
3524 }, {
3525 "en_Gujr_Zz",
3526 "en_Gujr_US"
3527 }, {
3528 "en_Gujr_ZA",
3529 "en_Gujr_ZA"
3530 }, {
3531 "en_Gujr_ZA_POSIX",
3532 "en_Gujr_ZA_POSIX"
3533 }, {
3534 "en_US_POSIX_1901",
3535 "en_Latn_US_POSIX_1901"
3536 }, {
3537 "en_Latn__POSIX_1901",
3538 "en_Latn_US_POSIX_1901"
3539 }, {
3540 "en__POSIX_1901",
3541 "en_Latn_US_POSIX_1901"
3542 }, {
3543 "de__POSIX_1901",
3544 "de_Latn_DE_POSIX_1901"
3545 }, {
3546 "en_US_BOSTON",
3547 "en_Latn_US_BOSTON"
3548 }, {
3549 "th@calendar=buddhist",
3550 "th_Thai_TH@calendar=buddhist"
3551 }, {
3552 "ar_ZZ",
3553 "ar_Arab_EG"
3554 }, {
3555 "zh",
3556 "zh_Hans_CN"
3557 }, {
3558 "zh_TW",
3559 "zh_Hant_TW"
3560 }, {
3561 "zh_HK",
3562 "zh_Hant_HK"
3563 }, {
3564 "zh_Hant",
3565 "zh_Hant_TW"
3566 }, {
3567 "zh_Zzzz_CN",
3568 "zh_Hans_CN"
3569 }, {
3570 "und_US",
3571 "en_Latn_US"
3572 }, {
3573 "und_HK",
3574 "zh_Hant_HK"
3575 }, {
3576 "zzz",
3577 ""
729e4ab9
A
3578 }, {
3579 "de_u_co_phonebk",
3580 "de_Latn_DE_U_CO_PHONEBK"
3581 }, {
3582 "de_Latn_u_co_phonebk",
3583 "de_Latn_DE_U_CO_PHONEBK"
3584 }, {
3585 "de_Latn_DE_u_co_phonebk",
3586 "de_Latn_DE_U_CO_PHONEBK"
0f5d89e8
A
3587 }, {
3588 "_Arab@em=emoji",
3589 "ar_Arab_EG@em=emoji"
3590 }, {
3591 "_Latn@em=emoji",
3592 "en_Latn_US@em=emoji"
3593 }, {
3594 "_Latn_DE@em=emoji",
3595 "de_Latn_DE@em=emoji"
3596 }, {
3597 "_Zzzz_DE@em=emoji",
3598 "de_Latn_DE@em=emoji"
3599 }, {
3600 "_DE@em=emoji",
3601 "de_Latn_DE@em=emoji"
3d1f044b
A
3602 }, { // start Apple tests for <rdar://problem/47494884>
3603 "ur",
3604 "ur_Aran_PK"
3605 }, {
3606 "ks",
3607 "ks_Aran_IN"
3608 }, {
3609 "und_Aran_PK",
3610 "ur_Aran_PK"
3611 }, {
3612 "und_Aran_IN",
3613 "ks_Aran_IN"
3614 }, {
3615 "ur_PK",
3616 "ur_Aran_PK"
3617 }, {
3618 "ks_IN",
3619 "ks_Aran_IN"
3620 }, {
3621 "ur_Arab",
3622 "ur_Arab_PK"
3623 }, {
3624 "ks_Arab",
3625 "ks_Arab_IN"
c5116b9f
A
3626 }, { // start Apple tests for <rdar://problem/54153189>
3627 "mni",
3628 "mni_Beng_IN"
3629 }, {
3630 "mni_Beng",
3631 "mni_Beng_IN"
3632 }, {
3633 "mni_Mtei",
3634 "mni_Mtei_IN"
3635 }, {
3636 "sat",
3637 "sat_Olck_IN"
3638 }, {
3639 "sat_Olck",
3640 "sat_Olck_IN"
3641 }, {
3642 "sat_Deva",
3643 "sat_Deva_IN"
46f4442e
A
3644 }
3645};
3646
3647const char* const basic_minimize_data[][2] = {
3648 {
3649 "en_Latn_US",
3650 "en"
3651 }, {
3652 "en_Latn_US_POSIX_1901",
3653 "en__POSIX_1901"
3654 }, {
3655 "EN_Latn_US_POSIX_1901",
3656 "en__POSIX_1901"
3657 }, {
3658 "en_Zzzz_US_POSIX_1901",
3659 "en__POSIX_1901"
3660 }, {
3661 "de_Latn_DE_POSIX_1901",
3662 "de__POSIX_1901"
3663 }, {
3664 "und",
3665 ""
729e4ab9
A
3666 }, {
3667 "en_Latn_US@calendar=gregorian",
3668 "en@calendar=gregorian"
46f4442e
A
3669 }
3670};
3671
3672const char* const full_data[][3] = {
3673 {
3674 /* "FROM", */
3675 /* "ADD-LIKELY", */
3676 /* "REMOVE-LIKELY" */
3677 /* }, { */
3678 "aa",
3679 "aa_Latn_ET",
3680 "aa"
3681 }, {
3682 "af",
3683 "af_Latn_ZA",
3684 "af"
3685 }, {
3686 "ak",
3687 "ak_Latn_GH",
3688 "ak"
3689 }, {
3690 "am",
3691 "am_Ethi_ET",
3692 "am"
3693 }, {
3694 "ar",
3695 "ar_Arab_EG",
3696 "ar"
3697 }, {
3698 "as",
3699 "as_Beng_IN",
3700 "as"
3701 }, {
3702 "az",
3703 "az_Latn_AZ",
3704 "az"
3705 }, {
3706 "be",
3707 "be_Cyrl_BY",
3708 "be"
3709 }, {
3710 "bg",
3711 "bg_Cyrl_BG",
3712 "bg"
3713 }, {
3714 "bn",
3715 "bn_Beng_BD",
3716 "bn"
3717 }, {
3718 "bo",
3719 "bo_Tibt_CN",
3720 "bo"
3721 }, {
3722 "bs",
3723 "bs_Latn_BA",
3724 "bs"
3725 }, {
3726 "ca",
3727 "ca_Latn_ES",
3728 "ca"
3729 }, {
3730 "ch",
3731 "ch_Latn_GU",
3732 "ch"
3733 }, {
3734 "chk",
3735 "chk_Latn_FM",
3736 "chk"
3737 }, {
3738 "cs",
3739 "cs_Latn_CZ",
3740 "cs"
3741 }, {
3742 "cy",
3743 "cy_Latn_GB",
3744 "cy"
3745 }, {
3746 "da",
3747 "da_Latn_DK",
3748 "da"
3749 }, {
3750 "de",
3751 "de_Latn_DE",
3752 "de"
3753 }, {
3754 "dv",
3755 "dv_Thaa_MV",
3756 "dv"
3757 }, {
3758 "dz",
3759 "dz_Tibt_BT",
3760 "dz"
3761 }, {
3762 "ee",
3763 "ee_Latn_GH",
3764 "ee"
3765 }, {
3766 "el",
3767 "el_Grek_GR",
3768 "el"
3769 }, {
3770 "en",
3771 "en_Latn_US",
3772 "en"
3773 }, {
3774 "es",
3775 "es_Latn_ES",
3776 "es"
3777 }, {
3778 "et",
3779 "et_Latn_EE",
3780 "et"
3781 }, {
3782 "eu",
3783 "eu_Latn_ES",
3784 "eu"
3785 }, {
3786 "fa",
3787 "fa_Arab_IR",
3788 "fa"
3789 }, {
3790 "fi",
3791 "fi_Latn_FI",
3792 "fi"
3793 }, {
3794 "fil",
3795 "fil_Latn_PH",
3796 "fil"
46f4442e
A
3797 }, {
3798 "fo",
3799 "fo_Latn_FO",
3800 "fo"
3801 }, {
3802 "fr",
3803 "fr_Latn_FR",
3804 "fr"
3805 }, {
3806 "fur",
3807 "fur_Latn_IT",
3808 "fur"
3809 }, {
3810 "ga",
3811 "ga_Latn_IE",
3812 "ga"
3813 }, {
3814 "gaa",
3815 "gaa_Latn_GH",
3816 "gaa"
3817 }, {
3818 "gl",
3819 "gl_Latn_ES",
3820 "gl"
3821 }, {
3822 "gn",
3823 "gn_Latn_PY",
3824 "gn"
3825 }, {
3826 "gu",
3827 "gu_Gujr_IN",
3828 "gu"
3829 }, {
3830 "ha",
3831 "ha_Latn_NG",
3832 "ha"
3833 }, {
3834 "haw",
3835 "haw_Latn_US",
3836 "haw"
3837 }, {
3838 "he",
3839 "he_Hebr_IL",
3840 "he"
3841 }, {
3842 "hi",
3843 "hi_Deva_IN",
3844 "hi"
3845 }, {
3846 "hr",
3847 "hr_Latn_HR",
3848 "hr"
3849 }, {
3850 "ht",
3851 "ht_Latn_HT",
3852 "ht"
3853 }, {
3854 "hu",
3855 "hu_Latn_HU",
3856 "hu"
3857 }, {
3858 "hy",
3859 "hy_Armn_AM",
3860 "hy"
3861 }, {
3862 "id",
3863 "id_Latn_ID",
3864 "id"
3865 }, {
3866 "ig",
3867 "ig_Latn_NG",
3868 "ig"
3869 }, {
3870 "ii",
729e4ab9 3871 "ii_Yiii_CN",
46f4442e
A
3872 "ii"
3873 }, {
3874 "is",
3875 "is_Latn_IS",
3876 "is"
3877 }, {
3878 "it",
3879 "it_Latn_IT",
3880 "it"
46f4442e
A
3881 }, {
3882 "ja",
3883 "ja_Jpan_JP",
3884 "ja"
3885 }, {
3886 "ka",
3887 "ka_Geor_GE",
3888 "ka"
3889 }, {
3890 "kaj",
3891 "kaj_Latn_NG",
3892 "kaj"
3893 }, {
3894 "kam",
3895 "kam_Latn_KE",
3896 "kam"
3897 }, {
3898 "kk",
3899 "kk_Cyrl_KZ",
3900 "kk"
3901 }, {
3902 "kl",
3903 "kl_Latn_GL",
3904 "kl"
3905 }, {
3906 "km",
3907 "km_Khmr_KH",
3908 "km"
3909 }, {
3910 "kn",
3911 "kn_Knda_IN",
3912 "kn"
3913 }, {
3914 "ko",
3915 "ko_Kore_KR",
3916 "ko"
3917 }, {
3918 "kok",
3919 "kok_Deva_IN",
3920 "kok"
3921 }, {
3922 "kpe",
3923 "kpe_Latn_LR",
3924 "kpe"
3925 }, {
3926 "ku",
4388f060 3927 "ku_Latn_TR",
46f4442e
A
3928 "ku"
3929 }, {
3930 "ky",
3931 "ky_Cyrl_KG",
3932 "ky"
3933 }, {
3934 "la",
3935 "la_Latn_VA",
3936 "la"
3937 }, {
3938 "ln",
3939 "ln_Latn_CD",
3940 "ln"
3941 }, {
3942 "lo",
3943 "lo_Laoo_LA",
3944 "lo"
3945 }, {
3946 "lt",
3947 "lt_Latn_LT",
3948 "lt"
3949 }, {
3950 "lv",
3951 "lv_Latn_LV",
3952 "lv"
3953 }, {
3954 "mg",
3955 "mg_Latn_MG",
3956 "mg"
3957 }, {
3958 "mh",
3959 "mh_Latn_MH",
3960 "mh"
3961 }, {
3962 "mk",
3963 "mk_Cyrl_MK",
3964 "mk"
3965 }, {
3966 "ml",
3967 "ml_Mlym_IN",
3968 "ml"
3969 }, {
3970 "mn",
3971 "mn_Cyrl_MN",
3972 "mn"
3973 }, {
3974 "mr",
3975 "mr_Deva_IN",
3976 "mr"
3977 }, {
3978 "ms",
3979 "ms_Latn_MY",
3980 "ms"
3981 }, {
3982 "mt",
3983 "mt_Latn_MT",
3984 "mt"
3985 }, {
3986 "my",
3987 "my_Mymr_MM",
3988 "my"
3989 }, {
3990 "na",
3991 "na_Latn_NR",
3992 "na"
3993 }, {
3994 "ne",
3995 "ne_Deva_NP",
3996 "ne"
3997 }, {
3998 "niu",
3999 "niu_Latn_NU",
4000 "niu"
4001 }, {
4002 "nl",
4003 "nl_Latn_NL",
4004 "nl"
4005 }, {
4006 "nn",
4007 "nn_Latn_NO",
4008 "nn"
4009 }, {
4010 "nr",
4011 "nr_Latn_ZA",
4012 "nr"
4013 }, {
4014 "nso",
4015 "nso_Latn_ZA",
4016 "nso"
4017 }, {
4018 "ny",
4019 "ny_Latn_MW",
4020 "ny"
4021 }, {
4022 "om",
4023 "om_Latn_ET",
4024 "om"
4025 }, {
4026 "or",
4027 "or_Orya_IN",
4028 "or"
4029 }, {
4030 "pa",
4031 "pa_Guru_IN",
4032 "pa"
4033 }, {
4034 "pa_Arab",
4035 "pa_Arab_PK",
3d1f044b
A
4036 "pa_Arab"
4037 }, {
4038 "pa_Aran",
4039 "pa_Aran_PK",
46f4442e
A
4040 "pa_PK"
4041 }, {
4042 "pa_PK",
3d1f044b 4043 "pa_Aran_PK", // <rdar://problem/50687287>
46f4442e
A
4044 "pa_PK"
4045 }, {
4046 "pap",
57a6839d 4047 "pap_Latn_AW",
46f4442e
A
4048 "pap"
4049 }, {
4050 "pau",
4051 "pau_Latn_PW",
4052 "pau"
4053 }, {
4054 "pl",
4055 "pl_Latn_PL",
4056 "pl"
4057 }, {
4058 "ps",
4059 "ps_Arab_AF",
4060 "ps"
4061 }, {
4062 "pt",
4063 "pt_Latn_BR",
4064 "pt"
4065 }, {
4066 "rn",
4067 "rn_Latn_BI",
4068 "rn"
4069 }, {
4070 "ro",
4071 "ro_Latn_RO",
4072 "ro"
4073 }, {
4074 "ru",
4075 "ru_Cyrl_RU",
4076 "ru"
4077 }, {
4078 "rw",
4079 "rw_Latn_RW",
4080 "rw"
4081 }, {
4082 "sa",
4083 "sa_Deva_IN",
4084 "sa"
4085 }, {
4086 "se",
4087 "se_Latn_NO",
4088 "se"
4089 }, {
4090 "sg",
4091 "sg_Latn_CF",
4092 "sg"
4093 }, {
4094 "si",
4095 "si_Sinh_LK",
4096 "si"
4097 }, {
4098 "sid",
4099 "sid_Latn_ET",
4100 "sid"
4101 }, {
4102 "sk",
4103 "sk_Latn_SK",
4104 "sk"
4105 }, {
4106 "sl",
4107 "sl_Latn_SI",
4108 "sl"
4109 }, {
4110 "sm",
4111 "sm_Latn_WS",
4112 "sm"
4113 }, {
4114 "so",
4115 "so_Latn_SO",
4116 "so"
4117 }, {
4118 "sq",
4119 "sq_Latn_AL",
4120 "sq"
4121 }, {
4122 "sr",
4123 "sr_Cyrl_RS",
4124 "sr"
4125 }, {
4126 "ss",
4127 "ss_Latn_ZA",
4128 "ss"
4129 }, {
4130 "st",
4131 "st_Latn_ZA",
4132 "st"
4133 }, {
4134 "sv",
4135 "sv_Latn_SE",
4136 "sv"
4137 }, {
4138 "sw",
4139 "sw_Latn_TZ",
4140 "sw"
4141 }, {
4142 "ta",
4143 "ta_Taml_IN",
4144 "ta"
4145 }, {
4146 "te",
4147 "te_Telu_IN",
4148 "te"
4149 }, {
4150 "tet",
4151 "tet_Latn_TL",
4152 "tet"
4153 }, {
4154 "tg",
4155 "tg_Cyrl_TJ",
4156 "tg"
4157 }, {
4158 "th",
4159 "th_Thai_TH",
4160 "th"
4161 }, {
4162 "ti",
4163 "ti_Ethi_ET",
4164 "ti"
4165 }, {
4166 "tig",
4167 "tig_Ethi_ER",
4168 "tig"
4169 }, {
4170 "tk",
4171 "tk_Latn_TM",
4172 "tk"
4173 }, {
4174 "tkl",
4175 "tkl_Latn_TK",
4176 "tkl"
4177 }, {
4178 "tn",
4179 "tn_Latn_ZA",
4180 "tn"
4181 }, {
4182 "to",
4183 "to_Latn_TO",
4184 "to"
4185 }, {
4186 "tpi",
4187 "tpi_Latn_PG",
4188 "tpi"
4189 }, {
4190 "tr",
4191 "tr_Latn_TR",
4192 "tr"
4193 }, {
4194 "ts",
4195 "ts_Latn_ZA",
4196 "ts"
4197 }, {
4198 "tt",
4199 "tt_Cyrl_RU",
4200 "tt"
4201 }, {
4202 "tvl",
4203 "tvl_Latn_TV",
4204 "tvl"
4205 }, {
4206 "ty",
4207 "ty_Latn_PF",
4208 "ty"
4209 }, {
4210 "uk",
4211 "uk_Cyrl_UA",
4212 "uk"
4213 }, {
4214 "und",
4215 "en_Latn_US",
4216 "en"
4217 }, {
4218 "und_AD",
4219 "ca_Latn_AD",
4220 "ca_AD"
4221 }, {
4222 "und_AE",
4223 "ar_Arab_AE",
4224 "ar_AE"
4225 }, {
4226 "und_AF",
4227 "fa_Arab_AF",
4228 "fa_AF"
4229 }, {
4230 "und_AL",
4231 "sq_Latn_AL",
4232 "sq"
4233 }, {
4234 "und_AM",
4235 "hy_Armn_AM",
4236 "hy"
46f4442e
A
4237 }, {
4238 "und_AO",
4239 "pt_Latn_AO",
4240 "pt_AO"
4241 }, {
4242 "und_AR",
4243 "es_Latn_AR",
4244 "es_AR"
4245 }, {
4246 "und_AS",
4247 "sm_Latn_AS",
4248 "sm_AS"
4249 }, {
4250 "und_AT",
4251 "de_Latn_AT",
4252 "de_AT"
4253 }, {
4254 "und_AW",
4255 "nl_Latn_AW",
4256 "nl_AW"
4257 }, {
4258 "und_AX",
4259 "sv_Latn_AX",
4260 "sv_AX"
4261 }, {
4262 "und_AZ",
4263 "az_Latn_AZ",
4264 "az"
4265 }, {
4266 "und_Arab",
4267 "ar_Arab_EG",
4268 "ar"
4269 }, {
4270 "und_Arab_IN",
4271 "ur_Arab_IN",
3d1f044b 4272 "ur_Arab_IN" // Apple <rdar://problem/47494884>
46f4442e
A
4273 }, {
4274 "und_Arab_PK",
4275 "ur_Arab_PK",
3d1f044b 4276 "ur_Arab", // Apple <rdar://problem/47494884>
46f4442e
A
4277 }, {
4278 "und_Arab_SN",
4279 "ar_Arab_SN",
4280 "ar_SN"
4281 }, {
4282 "und_Armn",
4283 "hy_Armn_AM",
4284 "hy"
4285 }, {
4286 "und_BA",
4287 "bs_Latn_BA",
4288 "bs"
4289 }, {
4290 "und_BD",
4291 "bn_Beng_BD",
4292 "bn"
4293 }, {
4294 "und_BE",
4295 "nl_Latn_BE",
4296 "nl_BE"
4297 }, {
4298 "und_BF",
4299 "fr_Latn_BF",
4300 "fr_BF"
4301 }, {
4302 "und_BG",
4303 "bg_Cyrl_BG",
4304 "bg"
4305 }, {
4306 "und_BH",
4307 "ar_Arab_BH",
4308 "ar_BH"
4309 }, {
4310 "und_BI",
4311 "rn_Latn_BI",
4312 "rn"
4313 }, {
4314 "und_BJ",
4315 "fr_Latn_BJ",
4316 "fr_BJ"
4317 }, {
4318 "und_BN",
4319 "ms_Latn_BN",
4320 "ms_BN"
4321 }, {
4322 "und_BO",
4323 "es_Latn_BO",
4324 "es_BO"
4325 }, {
4326 "und_BR",
4327 "pt_Latn_BR",
4328 "pt"
4329 }, {
4330 "und_BT",
4331 "dz_Tibt_BT",
4332 "dz"
4333 }, {
4334 "und_BY",
4335 "be_Cyrl_BY",
4336 "be"
4337 }, {
4338 "und_Beng",
4339 "bn_Beng_BD",
4340 "bn"
4341 }, {
4342 "und_Beng_IN",
4343 "bn_Beng_IN",
4344 "bn_IN"
4345 }, {
4346 "und_CD",
729e4ab9
A
4347 "sw_Latn_CD",
4348 "sw_CD"
46f4442e
A
4349 }, {
4350 "und_CF",
729e4ab9
A
4351 "fr_Latn_CF",
4352 "fr_CF"
46f4442e
A
4353 }, {
4354 "und_CG",
729e4ab9
A
4355 "fr_Latn_CG",
4356 "fr_CG"
46f4442e
A
4357 }, {
4358 "und_CH",
4359 "de_Latn_CH",
4360 "de_CH"
4361 }, {
4362 "und_CI",
4363 "fr_Latn_CI",
4364 "fr_CI"
4365 }, {
4366 "und_CL",
4367 "es_Latn_CL",
4368 "es_CL"
4369 }, {
4370 "und_CM",
4371 "fr_Latn_CM",
4372 "fr_CM"
4373 }, {
4374 "und_CN",
4375 "zh_Hans_CN",
4376 "zh"
4377 }, {
4378 "und_CO",
4379 "es_Latn_CO",
4380 "es_CO"
4381 }, {
4382 "und_CR",
4383 "es_Latn_CR",
4384 "es_CR"
4385 }, {
4386 "und_CU",
4387 "es_Latn_CU",
4388 "es_CU"
4389 }, {
4390 "und_CV",
4391 "pt_Latn_CV",
4392 "pt_CV"
4393 }, {
4394 "und_CY",
4395 "el_Grek_CY",
4396 "el_CY"
4397 }, {
4398 "und_CZ",
4399 "cs_Latn_CZ",
4400 "cs"
4401 }, {
729e4ab9
A
4402 "und_Cher",
4403 "chr_Cher_US",
4404 "chr"
46f4442e
A
4405 }, {
4406 "und_Cyrl",
4407 "ru_Cyrl_RU",
4408 "ru"
4409 }, {
4410 "und_Cyrl_KZ",
4411 "ru_Cyrl_KZ",
4412 "ru_KZ"
4413 }, {
4414 "und_DE",
4415 "de_Latn_DE",
4416 "de"
4417 }, {
4418 "und_DJ",
4419 "aa_Latn_DJ",
4420 "aa_DJ"
4421 }, {
4422 "und_DK",
4423 "da_Latn_DK",
4424 "da"
4425 }, {
4426 "und_DO",
4427 "es_Latn_DO",
4428 "es_DO"
4429 }, {
4430 "und_DZ",
4431 "ar_Arab_DZ",
4432 "ar_DZ"
4433 }, {
4434 "und_Deva",
4435 "hi_Deva_IN",
4436 "hi"
4437 }, {
4438 "und_EC",
4439 "es_Latn_EC",
4440 "es_EC"
4441 }, {
4442 "und_EE",
4443 "et_Latn_EE",
4444 "et"
4445 }, {
4446 "und_EG",
4447 "ar_Arab_EG",
4448 "ar"
4449 }, {
4450 "und_EH",
4451 "ar_Arab_EH",
4452 "ar_EH"
4453 }, {
4454 "und_ER",
4455 "ti_Ethi_ER",
4456 "ti_ER"
4457 }, {
4458 "und_ES",
4459 "es_Latn_ES",
4460 "es"
4461 }, {
4462 "und_ET",
51004dcb
A
4463 "am_Ethi_ET",
4464 "am"
46f4442e
A
4465 }, {
4466 "und_Ethi",
4467 "am_Ethi_ET",
4468 "am"
4469 }, {
4470 "und_Ethi_ER",
4471 "am_Ethi_ER",
4472 "am_ER"
4473 }, {
4474 "und_FI",
4475 "fi_Latn_FI",
4476 "fi"
46f4442e
A
4477 }, {
4478 "und_FM",
b331163b
A
4479 "en_Latn_FM",
4480 "en_FM"
46f4442e
A
4481 }, {
4482 "und_FO",
4483 "fo_Latn_FO",
4484 "fo"
4485 }, {
4486 "und_FR",
4487 "fr_Latn_FR",
4488 "fr"
4489 }, {
4490 "und_GA",
4491 "fr_Latn_GA",
4492 "fr_GA"
4493 }, {
4494 "und_GE",
4495 "ka_Geor_GE",
4496 "ka"
4497 }, {
4498 "und_GF",
4499 "fr_Latn_GF",
4500 "fr_GF"
4501 }, {
4502 "und_GL",
4503 "kl_Latn_GL",
4504 "kl"
4505 }, {
4506 "und_GN",
4507 "fr_Latn_GN",
4508 "fr_GN"
4509 }, {
4510 "und_GP",
4511 "fr_Latn_GP",
4512 "fr_GP"
4513 }, {
4514 "und_GQ",
729e4ab9
A
4515 "es_Latn_GQ",
4516 "es_GQ"
46f4442e
A
4517 }, {
4518 "und_GR",
4519 "el_Grek_GR",
4520 "el"
4521 }, {
4522 "und_GT",
4523 "es_Latn_GT",
4524 "es_GT"
4525 }, {
4526 "und_GU",
729e4ab9
A
4527 "en_Latn_GU",
4528 "en_GU"
46f4442e
A
4529 }, {
4530 "und_GW",
4531 "pt_Latn_GW",
4532 "pt_GW"
4533 }, {
4534 "und_Geor",
4535 "ka_Geor_GE",
4536 "ka"
4537 }, {
4538 "und_Grek",
4539 "el_Grek_GR",
4540 "el"
4541 }, {
4542 "und_Gujr",
4543 "gu_Gujr_IN",
4544 "gu"
4545 }, {
4546 "und_Guru",
4547 "pa_Guru_IN",
4548 "pa"
4549 }, {
4550 "und_HK",
4551 "zh_Hant_HK",
4552 "zh_HK"
4553 }, {
4554 "und_HN",
4555 "es_Latn_HN",
4556 "es_HN"
4557 }, {
4558 "und_HR",
4559 "hr_Latn_HR",
4560 "hr"
4561 }, {
4562 "und_HT",
4563 "ht_Latn_HT",
4564 "ht"
4565 }, {
4566 "und_HU",
4567 "hu_Latn_HU",
4568 "hu"
4569 }, {
4570 "und_Hani",
57a6839d
A
4571 "zh_Hani_CN",
4572 "zh_Hani"
46f4442e
A
4573 }, {
4574 "und_Hans",
4575 "zh_Hans_CN",
4576 "zh"
4577 }, {
4578 "und_Hant",
4579 "zh_Hant_TW",
4580 "zh_TW"
4581 }, {
4582 "und_Hebr",
4583 "he_Hebr_IL",
4584 "he"
4585 }, {
4586 "und_IL",
4587 "he_Hebr_IL",
4588 "he"
4589 }, {
4590 "und_IN",
4591 "hi_Deva_IN",
4592 "hi"
4593 }, {
4594 "und_IQ",
4595 "ar_Arab_IQ",
4596 "ar_IQ"
4597 }, {
4598 "und_IR",
4599 "fa_Arab_IR",
4600 "fa"
4601 }, {
4602 "und_IS",
4603 "is_Latn_IS",
4604 "is"
4605 }, {
4606 "und_IT",
4607 "it_Latn_IT",
4608 "it"
4609 }, {
4610 "und_JO",
4611 "ar_Arab_JO",
4612 "ar_JO"
4613 }, {
4614 "und_JP",
4615 "ja_Jpan_JP",
4616 "ja"
4617 }, {
4618 "und_Jpan",
4619 "ja_Jpan_JP",
4620 "ja"
4621 }, {
4622 "und_KG",
4623 "ky_Cyrl_KG",
4624 "ky"
4625 }, {
4626 "und_KH",
4627 "km_Khmr_KH",
4628 "km"
4629 }, {
4630 "und_KM",
4631 "ar_Arab_KM",
4632 "ar_KM"
4633 }, {
4634 "und_KP",
4635 "ko_Kore_KP",
4636 "ko_KP"
4637 }, {
4638 "und_KR",
4639 "ko_Kore_KR",
4640 "ko"
4641 }, {
4642 "und_KW",
4643 "ar_Arab_KW",
4644 "ar_KW"
4645 }, {
4646 "und_KZ",
4647 "ru_Cyrl_KZ",
4648 "ru_KZ"
4649 }, {
4650 "und_Khmr",
4651 "km_Khmr_KH",
4652 "km"
4653 }, {
4654 "und_Knda",
4655 "kn_Knda_IN",
4656 "kn"
4657 }, {
4658 "und_Kore",
4659 "ko_Kore_KR",
4660 "ko"
4661 }, {
4662 "und_LA",
4663 "lo_Laoo_LA",
4664 "lo"
4665 }, {
4666 "und_LB",
4667 "ar_Arab_LB",
4668 "ar_LB"
4669 }, {
4670 "und_LI",
4671 "de_Latn_LI",
4672 "de_LI"
4673 }, {
4674 "und_LK",
4675 "si_Sinh_LK",
4676 "si"
4677 }, {
4678 "und_LS",
4679 "st_Latn_LS",
4680 "st_LS"
4681 }, {
4682 "und_LT",
4683 "lt_Latn_LT",
4684 "lt"
4685 }, {
4686 "und_LU",
4687 "fr_Latn_LU",
4688 "fr_LU"
4689 }, {
4690 "und_LV",
4691 "lv_Latn_LV",
4692 "lv"
4693 }, {
4694 "und_LY",
4695 "ar_Arab_LY",
4696 "ar_LY"
4697 }, {
4698 "und_Laoo",
4699 "lo_Laoo_LA",
4700 "lo"
4701 }, {
4702 "und_Latn_ES",
4703 "es_Latn_ES",
4704 "es"
4705 }, {
4706 "und_Latn_ET",
729e4ab9
A
4707 "en_Latn_ET",
4708 "en_ET"
46f4442e
A
4709 }, {
4710 "und_Latn_GB",
4711 "en_Latn_GB",
4712 "en_GB"
4713 }, {
4714 "und_Latn_GH",
4715 "ak_Latn_GH",
4716 "ak"
4717 }, {
4718 "und_Latn_ID",
4719 "id_Latn_ID",
4720 "id"
4721 }, {
4722 "und_Latn_IT",
4723 "it_Latn_IT",
4724 "it"
4725 }, {
4726 "und_Latn_NG",
729e4ab9
A
4727 "en_Latn_NG",
4728 "en_NG"
46f4442e
A
4729 }, {
4730 "und_Latn_TR",
4731 "tr_Latn_TR",
4732 "tr"
4733 }, {
4734 "und_Latn_ZA",
4735 "en_Latn_ZA",
4736 "en_ZA"
4737 }, {
4738 "und_MA",
4739 "ar_Arab_MA",
4740 "ar_MA"
4741 }, {
4742 "und_MC",
4743 "fr_Latn_MC",
4744 "fr_MC"
4745 }, {
4746 "und_MD",
4747 "ro_Latn_MD",
4748 "ro_MD"
4749 }, {
4750 "und_ME",
729e4ab9 4751 "sr_Latn_ME",
46f4442e
A
4752 "sr_ME"
4753 }, {
4754 "und_MG",
4755 "mg_Latn_MG",
4756 "mg"
4757 }, {
4758 "und_MH",
729e4ab9
A
4759 "en_Latn_MH",
4760 "en_MH"
46f4442e
A
4761 }, {
4762 "und_MK",
4763 "mk_Cyrl_MK",
4764 "mk"
4765 }, {
4766 "und_ML",
729e4ab9
A
4767 "bm_Latn_ML",
4768 "bm"
46f4442e
A
4769 }, {
4770 "und_MM",
4771 "my_Mymr_MM",
4772 "my"
4773 }, {
4774 "und_MN",
4775 "mn_Cyrl_MN",
4776 "mn"
4777 }, {
4778 "und_MO",
4779 "zh_Hant_MO",
4780 "zh_MO"
4781 }, {
4782 "und_MQ",
4783 "fr_Latn_MQ",
4784 "fr_MQ"
4785 }, {
4786 "und_MR",
4787 "ar_Arab_MR",
4788 "ar_MR"
4789 }, {
4790 "und_MT",
4791 "mt_Latn_MT",
4792 "mt"
4793 }, {
4794 "und_MV",
4795 "dv_Thaa_MV",
4796 "dv"
4797 }, {
4798 "und_MW",
729e4ab9
A
4799 "en_Latn_MW",
4800 "en_MW"
46f4442e
A
4801 }, {
4802 "und_MX",
4803 "es_Latn_MX",
4804 "es_MX"
4805 }, {
4806 "und_MY",
4807 "ms_Latn_MY",
4808 "ms"
4809 }, {
4810 "und_MZ",
4811 "pt_Latn_MZ",
4812 "pt_MZ"
4813 }, {
4814 "und_Mlym",
4815 "ml_Mlym_IN",
4816 "ml"
4817 }, {
4818 "und_Mymr",
4819 "my_Mymr_MM",
4820 "my"
4821 }, {
4822 "und_NC",
4823 "fr_Latn_NC",
4824 "fr_NC"
4825 }, {
4826 "und_NE",
4827 "ha_Latn_NE",
4828 "ha_NE"
4829 }, {
4830 "und_NG",
729e4ab9
A
4831 "en_Latn_NG",
4832 "en_NG"
46f4442e
A
4833 }, {
4834 "und_NI",
4835 "es_Latn_NI",
4836 "es_NI"
4837 }, {
4838 "und_NL",
4839 "nl_Latn_NL",
4840 "nl"
4841 }, {
4842 "und_NO",
4843 "nb_Latn_NO",
4844 "nb"
4845 }, {
4846 "und_NP",
4847 "ne_Deva_NP",
4848 "ne"
4849 }, {
4850 "und_NR",
729e4ab9
A
4851 "en_Latn_NR",
4852 "en_NR"
46f4442e
A
4853 }, {
4854 "und_NU",
729e4ab9
A
4855 "en_Latn_NU",
4856 "en_NU"
46f4442e
A
4857 }, {
4858 "und_OM",
4859 "ar_Arab_OM",
4860 "ar_OM"
4861 }, {
4862 "und_Orya",
4863 "or_Orya_IN",
4864 "or"
4865 }, {
4866 "und_PA",
4867 "es_Latn_PA",
4868 "es_PA"
4869 }, {
4870 "und_PE",
4871 "es_Latn_PE",
4872 "es_PE"
4873 }, {
4874 "und_PF",
729e4ab9
A
4875 "fr_Latn_PF",
4876 "fr_PF"
46f4442e
A
4877 }, {
4878 "und_PG",
4879 "tpi_Latn_PG",
4880 "tpi"
4881 }, {
4882 "und_PH",
4883 "fil_Latn_PH",
4884 "fil"
4885 }, {
4886 "und_PL",
4887 "pl_Latn_PL",
4888 "pl"
4889 }, {
4890 "und_PM",
4891 "fr_Latn_PM",
4892 "fr_PM"
4893 }, {
4894 "und_PR",
4895 "es_Latn_PR",
4896 "es_PR"
4897 }, {
4898 "und_PS",
4899 "ar_Arab_PS",
4900 "ar_PS"
4901 }, {
4902 "und_PT",
4903 "pt_Latn_PT",
4904 "pt_PT"
4905 }, {
4906 "und_PW",
4907 "pau_Latn_PW",
4908 "pau"
4909 }, {
4910 "und_PY",
4911 "gn_Latn_PY",
4912 "gn"
4913 }, {
4914 "und_QA",
4915 "ar_Arab_QA",
4916 "ar_QA"
4917 }, {
4918 "und_RE",
4919 "fr_Latn_RE",
4920 "fr_RE"
4921 }, {
4922 "und_RO",
4923 "ro_Latn_RO",
4924 "ro"
4925 }, {
4926 "und_RS",
4927 "sr_Cyrl_RS",
4928 "sr"
4929 }, {
4930 "und_RU",
4931 "ru_Cyrl_RU",
4932 "ru"
4933 }, {
4934 "und_RW",
4935 "rw_Latn_RW",
4936 "rw"
4937 }, {
4938 "und_SA",
4939 "ar_Arab_SA",
4940 "ar_SA"
4941 }, {
4942 "und_SD",
4943 "ar_Arab_SD",
4944 "ar_SD"
4945 }, {
4946 "und_SE",
4947 "sv_Latn_SE",
4948 "sv"
4949 }, {
4950 "und_SG",
4951 "en_Latn_SG",
4952 "en_SG"
4953 }, {
4954 "und_SI",
4955 "sl_Latn_SI",
4956 "sl"
4957 }, {
4958 "und_SJ",
4959 "nb_Latn_SJ",
4960 "nb_SJ"
4961 }, {
4962 "und_SK",
4963 "sk_Latn_SK",
4964 "sk"
4965 }, {
4966 "und_SM",
4967 "it_Latn_SM",
4968 "it_SM"
4969 }, {
4970 "und_SN",
4971 "fr_Latn_SN",
4972 "fr_SN"
4973 }, {
4974 "und_SO",
4975 "so_Latn_SO",
4976 "so"
4977 }, {
4978 "und_SR",
4979 "nl_Latn_SR",
4980 "nl_SR"
4981 }, {
4982 "und_ST",
4983 "pt_Latn_ST",
4984 "pt_ST"
4985 }, {
4986 "und_SV",
4987 "es_Latn_SV",
4988 "es_SV"
4989 }, {
4990 "und_SY",
4991 "ar_Arab_SY",
4992 "ar_SY"
4993 }, {
4994 "und_Sinh",
4995 "si_Sinh_LK",
4996 "si"
4997 }, {
4998 "und_TD",
729e4ab9
A
4999 "fr_Latn_TD",
5000 "fr_TD"
46f4442e
A
5001 }, {
5002 "und_TG",
729e4ab9
A
5003 "fr_Latn_TG",
5004 "fr_TG"
46f4442e
A
5005 }, {
5006 "und_TH",
5007 "th_Thai_TH",
5008 "th"
5009 }, {
5010 "und_TJ",
5011 "tg_Cyrl_TJ",
5012 "tg"
5013 }, {
5014 "und_TK",
5015 "tkl_Latn_TK",
5016 "tkl"
5017 }, {
5018 "und_TL",
729e4ab9
A
5019 "pt_Latn_TL",
5020 "pt_TL"
46f4442e
A
5021 }, {
5022 "und_TM",
5023 "tk_Latn_TM",
5024 "tk"
5025 }, {
5026 "und_TN",
5027 "ar_Arab_TN",
5028 "ar_TN"
5029 }, {
5030 "und_TO",
5031 "to_Latn_TO",
5032 "to"
5033 }, {
5034 "und_TR",
5035 "tr_Latn_TR",
5036 "tr"
5037 }, {
5038 "und_TV",
5039 "tvl_Latn_TV",
5040 "tvl"
5041 }, {
5042 "und_TW",
5043 "zh_Hant_TW",
5044 "zh_TW"
5045 }, {
5046 "und_Taml",
5047 "ta_Taml_IN",
5048 "ta"
5049 }, {
5050 "und_Telu",
5051 "te_Telu_IN",
5052 "te"
5053 }, {
5054 "und_Thaa",
5055 "dv_Thaa_MV",
5056 "dv"
5057 }, {
5058 "und_Thai",
5059 "th_Thai_TH",
5060 "th"
5061 }, {
5062 "und_Tibt",
5063 "bo_Tibt_CN",
5064 "bo"
5065 }, {
5066 "und_UA",
5067 "uk_Cyrl_UA",
5068 "uk"
5069 }, {
5070 "und_UY",
5071 "es_Latn_UY",
5072 "es_UY"
5073 }, {
5074 "und_UZ",
57a6839d 5075 "uz_Latn_UZ",
46f4442e
A
5076 "uz"
5077 }, {
5078 "und_VA",
b331163b
A
5079 "it_Latn_VA",
5080 "it_VA"
46f4442e
A
5081 }, {
5082 "und_VE",
5083 "es_Latn_VE",
5084 "es_VE"
5085 }, {
5086 "und_VN",
5087 "vi_Latn_VN",
5088 "vi"
5089 }, {
5090 "und_VU",
4388f060
A
5091 "bi_Latn_VU",
5092 "bi"
46f4442e
A
5093 }, {
5094 "und_WF",
5095 "fr_Latn_WF",
5096 "fr_WF"
5097 }, {
5098 "und_WS",
5099 "sm_Latn_WS",
5100 "sm"
5101 }, {
5102 "und_YE",
5103 "ar_Arab_YE",
5104 "ar_YE"
5105 }, {
5106 "und_YT",
5107 "fr_Latn_YT",
5108 "fr_YT"
5109 }, {
5110 "und_Yiii",
729e4ab9
A
5111 "ii_Yiii_CN",
5112 "ii"
46f4442e
A
5113 }, {
5114 "ur",
3d1f044b 5115 "ur_Aran_PK", // Apple <rdar://problem/47494884>
46f4442e
A
5116 "ur"
5117 }, {
5118 "uz",
57a6839d 5119 "uz_Latn_UZ",
46f4442e
A
5120 "uz"
5121 }, {
5122 "uz_AF",
5123 "uz_Arab_AF",
5124 "uz_AF"
5125 }, {
5126 "uz_Arab",
5127 "uz_Arab_AF",
5128 "uz_AF"
5129 }, {
5130 "ve",
5131 "ve_Latn_ZA",
5132 "ve"
5133 }, {
5134 "vi",
5135 "vi_Latn_VN",
5136 "vi"
5137 }, {
5138 "wal",
5139 "wal_Ethi_ET",
5140 "wal"
5141 }, {
5142 "wo",
5143 "wo_Latn_SN",
5144 "wo"
5145 }, {
5146 "xh",
5147 "xh_Latn_ZA",
5148 "xh"
5149 }, {
5150 "yo",
5151 "yo_Latn_NG",
5152 "yo"
5153 }, {
5154 "zh",
5155 "zh_Hans_CN",
5156 "zh"
5157 }, {
5158 "zh_HK",
5159 "zh_Hant_HK",
5160 "zh_HK"
5161 }, {
5162 "zh_Hani",
57a6839d
A
5163 "zh_Hani_CN", /* changed due to cldrbug 6204, may be an error */
5164 "zh_Hani", /* changed due to cldrbug 6204, may be an error */
46f4442e
A
5165 }, {
5166 "zh_Hant",
5167 "zh_Hant_TW",
5168 "zh_TW"
5169 }, {
5170 "zh_MO",
5171 "zh_Hant_MO",
5172 "zh_MO"
5173 }, {
5174 "zh_TW",
5175 "zh_Hant_TW",
5176 "zh_TW"
5177 }, {
5178 "zu",
5179 "zu_Latn_ZA",
5180 "zu"
5181 }, {
5182 "und",
5183 "en_Latn_US",
5184 "en"
5185 }, {
5186 "und_ZZ",
5187 "en_Latn_US",
5188 "en"
5189 }, {
5190 "und_CN",
5191 "zh_Hans_CN",
5192 "zh"
5193 }, {
5194 "und_TW",
5195 "zh_Hant_TW",
5196 "zh_TW"
5197 }, {
5198 "und_HK",
5199 "zh_Hant_HK",
5200 "zh_HK"
5201 }, {
5202 "und_AQ",
51004dcb
A
5203 "und_Latn_AQ",
5204 "und_AQ"
46f4442e
A
5205 }, {
5206 "und_Zzzz",
5207 "en_Latn_US",
5208 "en"
5209 }, {
5210 "und_Zzzz_ZZ",
5211 "en_Latn_US",
5212 "en"
5213 }, {
5214 "und_Zzzz_CN",
5215 "zh_Hans_CN",
5216 "zh"
5217 }, {
5218 "und_Zzzz_TW",
5219 "zh_Hant_TW",
5220 "zh_TW"
5221 }, {
5222 "und_Zzzz_HK",
5223 "zh_Hant_HK",
5224 "zh_HK"
5225 }, {
5226 "und_Zzzz_AQ",
51004dcb
A
5227 "und_Latn_AQ",
5228 "und_AQ"
46f4442e
A
5229 }, {
5230 "und_Latn",
5231 "en_Latn_US",
5232 "en"
5233 }, {
5234 "und_Latn_ZZ",
5235 "en_Latn_US",
5236 "en"
5237 }, {
5238 "und_Latn_CN",
729e4ab9
A
5239 "za_Latn_CN",
5240 "za"
46f4442e
A
5241 }, {
5242 "und_Latn_TW",
51004dcb
A
5243 "trv_Latn_TW",
5244 "trv"
46f4442e
A
5245 }, {
5246 "und_Latn_HK",
5247 "zh_Latn_HK",
5248 "zh_Latn_HK"
5249 }, {
5250 "und_Latn_AQ",
51004dcb
A
5251 "und_Latn_AQ",
5252 "und_AQ"
46f4442e
A
5253 }, {
5254 "und_Hans",
5255 "zh_Hans_CN",
5256 "zh"
5257 }, {
5258 "und_Hans_ZZ",
5259 "zh_Hans_CN",
5260 "zh"
5261 }, {
5262 "und_Hans_CN",
5263 "zh_Hans_CN",
5264 "zh"
5265 }, {
5266 "und_Hans_TW",
5267 "zh_Hans_TW",
5268 "zh_Hans_TW"
5269 }, {
5270 "und_Hans_HK",
5271 "zh_Hans_HK",
5272 "zh_Hans_HK"
5273 }, {
5274 "und_Hans_AQ",
5275 "zh_Hans_AQ",
5276 "zh_AQ"
5277 }, {
5278 "und_Hant",
5279 "zh_Hant_TW",
5280 "zh_TW"
5281 }, {
5282 "und_Hant_ZZ",
5283 "zh_Hant_TW",
5284 "zh_TW"
5285 }, {
5286 "und_Hant_CN",
0f5d89e8
A
5287 "zh_Hant_CN",
5288 "zh_Hant_CN"
46f4442e
A
5289 }, {
5290 "und_Hant_TW",
5291 "zh_Hant_TW",
5292 "zh_TW"
5293 }, {
5294 "und_Hant_HK",
5295 "zh_Hant_HK",
5296 "zh_HK"
5297 }, {
5298 "und_Hant_AQ",
5299 "zh_Hant_AQ",
5300 "zh_Hant_AQ"
5301 }, {
5302 "und_Moon",
5303 "en_Moon_US",
5304 "en_Moon"
5305 }, {
5306 "und_Moon_ZZ",
5307 "en_Moon_US",
5308 "en_Moon"
5309 }, {
5310 "und_Moon_CN",
5311 "zh_Moon_CN",
5312 "zh_Moon"
5313 }, {
5314 "und_Moon_TW",
5315 "zh_Moon_TW",
5316 "zh_Moon_TW"
5317 }, {
5318 "und_Moon_HK",
5319 "zh_Moon_HK",
5320 "zh_Moon_HK"
5321 }, {
5322 "und_Moon_AQ",
51004dcb
A
5323 "und_Moon_AQ",
5324 "und_Moon_AQ"
46f4442e
A
5325 }, {
5326 "es",
5327 "es_Latn_ES",
5328 "es"
5329 }, {
5330 "es_ZZ",
5331 "es_Latn_ES",
5332 "es"
5333 }, {
5334 "es_CN",
5335 "es_Latn_CN",
5336 "es_CN"
5337 }, {
5338 "es_TW",
5339 "es_Latn_TW",
5340 "es_TW"
5341 }, {
5342 "es_HK",
5343 "es_Latn_HK",
5344 "es_HK"
5345 }, {
5346 "es_AQ",
5347 "es_Latn_AQ",
5348 "es_AQ"
5349 }, {
5350 "es_Zzzz",
5351 "es_Latn_ES",
5352 "es"
5353 }, {
5354 "es_Zzzz_ZZ",
5355 "es_Latn_ES",
5356 "es"
5357 }, {
5358 "es_Zzzz_CN",
5359 "es_Latn_CN",
5360 "es_CN"
5361 }, {
5362 "es_Zzzz_TW",
5363 "es_Latn_TW",
5364 "es_TW"
5365 }, {
5366 "es_Zzzz_HK",
5367 "es_Latn_HK",
5368 "es_HK"
5369 }, {
5370 "es_Zzzz_AQ",
5371 "es_Latn_AQ",
5372 "es_AQ"
5373 }, {
5374 "es_Latn",
5375 "es_Latn_ES",
5376 "es"
5377 }, {
5378 "es_Latn_ZZ",
5379 "es_Latn_ES",
5380 "es"
5381 }, {
5382 "es_Latn_CN",
5383 "es_Latn_CN",
5384 "es_CN"
5385 }, {
5386 "es_Latn_TW",
5387 "es_Latn_TW",
5388 "es_TW"
5389 }, {
5390 "es_Latn_HK",
5391 "es_Latn_HK",
5392 "es_HK"
5393 }, {
5394 "es_Latn_AQ",
5395 "es_Latn_AQ",
5396 "es_AQ"
5397 }, {
5398 "es_Hans",
5399 "es_Hans_ES",
5400 "es_Hans"
5401 }, {
5402 "es_Hans_ZZ",
5403 "es_Hans_ES",
5404 "es_Hans"
5405 }, {
5406 "es_Hans_CN",
5407 "es_Hans_CN",
5408 "es_Hans_CN"
5409 }, {
5410 "es_Hans_TW",
5411 "es_Hans_TW",
5412 "es_Hans_TW"
5413 }, {
5414 "es_Hans_HK",
5415 "es_Hans_HK",
5416 "es_Hans_HK"
5417 }, {
5418 "es_Hans_AQ",
5419 "es_Hans_AQ",
5420 "es_Hans_AQ"
5421 }, {
5422 "es_Hant",
5423 "es_Hant_ES",
5424 "es_Hant"
5425 }, {
5426 "es_Hant_ZZ",
5427 "es_Hant_ES",
5428 "es_Hant"
5429 }, {
5430 "es_Hant_CN",
5431 "es_Hant_CN",
5432 "es_Hant_CN"
5433 }, {
5434 "es_Hant_TW",
5435 "es_Hant_TW",
5436 "es_Hant_TW"
5437 }, {
5438 "es_Hant_HK",
5439 "es_Hant_HK",
5440 "es_Hant_HK"
5441 }, {
5442 "es_Hant_AQ",
5443 "es_Hant_AQ",
5444 "es_Hant_AQ"
5445 }, {
5446 "es_Moon",
5447 "es_Moon_ES",
5448 "es_Moon"
5449 }, {
5450 "es_Moon_ZZ",
5451 "es_Moon_ES",
5452 "es_Moon"
5453 }, {
5454 "es_Moon_CN",
5455 "es_Moon_CN",
5456 "es_Moon_CN"
5457 }, {
5458 "es_Moon_TW",
5459 "es_Moon_TW",
5460 "es_Moon_TW"
5461 }, {
5462 "es_Moon_HK",
5463 "es_Moon_HK",
5464 "es_Moon_HK"
5465 }, {
5466 "es_Moon_AQ",
5467 "es_Moon_AQ",
5468 "es_Moon_AQ"
5469 }, {
5470 "zh",
5471 "zh_Hans_CN",
5472 "zh"
5473 }, {
5474 "zh_ZZ",
5475 "zh_Hans_CN",
5476 "zh"
5477 }, {
5478 "zh_CN",
5479 "zh_Hans_CN",
5480 "zh"
5481 }, {
5482 "zh_TW",
5483 "zh_Hant_TW",
5484 "zh_TW"
5485 }, {
5486 "zh_HK",
5487 "zh_Hant_HK",
5488 "zh_HK"
5489 }, {
5490 "zh_AQ",
5491 "zh_Hans_AQ",
5492 "zh_AQ"
f3c0d7a5
A
5493 }, {
5494 "zh_MY",
5495 "zh_Hans_MY",
5496 "zh_MY"
46f4442e
A
5497 }, {
5498 "zh_Zzzz",
5499 "zh_Hans_CN",
5500 "zh"
5501 }, {
5502 "zh_Zzzz_ZZ",
5503 "zh_Hans_CN",
5504 "zh"
5505 }, {
5506 "zh_Zzzz_CN",
5507 "zh_Hans_CN",
5508 "zh"
5509 }, {
5510 "zh_Zzzz_TW",
5511 "zh_Hant_TW",
5512 "zh_TW"
5513 }, {
5514 "zh_Zzzz_HK",
5515 "zh_Hant_HK",
5516 "zh_HK"
5517 }, {
5518 "zh_Zzzz_AQ",
5519 "zh_Hans_AQ",
5520 "zh_AQ"
5521 }, {
5522 "zh_Latn",
5523 "zh_Latn_CN",
5524 "zh_Latn"
5525 }, {
5526 "zh_Latn_ZZ",
5527 "zh_Latn_CN",
5528 "zh_Latn"
5529 }, {
5530 "zh_Latn_CN",
5531 "zh_Latn_CN",
5532 "zh_Latn"
5533 }, {
5534 "zh_Latn_TW",
5535 "zh_Latn_TW",
5536 "zh_Latn_TW"
5537 }, {
5538 "zh_Latn_HK",
5539 "zh_Latn_HK",
5540 "zh_Latn_HK"
5541 }, {
5542 "zh_Latn_AQ",
5543 "zh_Latn_AQ",
5544 "zh_Latn_AQ"
5545 }, {
5546 "zh_Hans",
5547 "zh_Hans_CN",
5548 "zh"
5549 }, {
5550 "zh_Hans_ZZ",
5551 "zh_Hans_CN",
5552 "zh"
5553 }, {
5554 "zh_Hans_TW",
5555 "zh_Hans_TW",
5556 "zh_Hans_TW"
5557 }, {
5558 "zh_Hans_HK",
5559 "zh_Hans_HK",
5560 "zh_Hans_HK"
5561 }, {
5562 "zh_Hans_AQ",
5563 "zh_Hans_AQ",
5564 "zh_AQ"
5565 }, {
5566 "zh_Hant",
5567 "zh_Hant_TW",
5568 "zh_TW"
5569 }, {
5570 "zh_Hant_ZZ",
5571 "zh_Hant_TW",
5572 "zh_TW"
5573 }, {
5574 "zh_Hant_CN",
5575 "zh_Hant_CN",
5576 "zh_Hant_CN"
5577 }, {
5578 "zh_Hant_AQ",
5579 "zh_Hant_AQ",
5580 "zh_Hant_AQ"
5581 }, {
5582 "zh_Moon",
5583 "zh_Moon_CN",
5584 "zh_Moon"
5585 }, {
5586 "zh_Moon_ZZ",
5587 "zh_Moon_CN",
5588 "zh_Moon"
5589 }, {
5590 "zh_Moon_CN",
5591 "zh_Moon_CN",
5592 "zh_Moon"
5593 }, {
5594 "zh_Moon_TW",
5595 "zh_Moon_TW",
5596 "zh_Moon_TW"
5597 }, {
5598 "zh_Moon_HK",
5599 "zh_Moon_HK",
5600 "zh_Moon_HK"
5601 }, {
5602 "zh_Moon_AQ",
5603 "zh_Moon_AQ",
5604 "zh_Moon_AQ"
5605 }, {
5606 "art",
5607 "",
5608 ""
5609 }, {
5610 "art_ZZ",
5611 "",
5612 ""
5613 }, {
5614 "art_CN",
5615 "",
5616 ""
5617 }, {
5618 "art_TW",
5619 "",
5620 ""
5621 }, {
5622 "art_HK",
5623 "",
5624 ""
5625 }, {
5626 "art_AQ",
5627 "",
5628 ""
5629 }, {
5630 "art_Zzzz",
5631 "",
5632 ""
5633 }, {
5634 "art_Zzzz_ZZ",
5635 "",
5636 ""
5637 }, {
5638 "art_Zzzz_CN",
5639 "",
5640 ""
5641 }, {
5642 "art_Zzzz_TW",
5643 "",
5644 ""
5645 }, {
5646 "art_Zzzz_HK",
5647 "",
5648 ""
5649 }, {
5650 "art_Zzzz_AQ",
5651 "",
5652 ""
5653 }, {
5654 "art_Latn",
5655 "",
5656 ""
5657 }, {
5658 "art_Latn_ZZ",
5659 "",
5660 ""
5661 }, {
5662 "art_Latn_CN",
5663 "",
5664 ""
5665 }, {
5666 "art_Latn_TW",
5667 "",
5668 ""
5669 }, {
5670 "art_Latn_HK",
5671 "",
5672 ""
5673 }, {
5674 "art_Latn_AQ",
5675 "",
5676 ""
5677 }, {
5678 "art_Hans",
5679 "",
5680 ""
5681 }, {
5682 "art_Hans_ZZ",
5683 "",
5684 ""
5685 }, {
5686 "art_Hans_CN",
5687 "",
5688 ""
5689 }, {
5690 "art_Hans_TW",
5691 "",
5692 ""
5693 }, {
5694 "art_Hans_HK",
5695 "",
5696 ""
5697 }, {
5698 "art_Hans_AQ",
5699 "",
5700 ""
5701 }, {
5702 "art_Hant",
5703 "",
5704 ""
5705 }, {
5706 "art_Hant_ZZ",
5707 "",
5708 ""
5709 }, {
5710 "art_Hant_CN",
5711 "",
5712 ""
5713 }, {
5714 "art_Hant_TW",
5715 "",
5716 ""
5717 }, {
5718 "art_Hant_HK",
5719 "",
5720 ""
5721 }, {
5722 "art_Hant_AQ",
5723 "",
5724 ""
5725 }, {
5726 "art_Moon",
5727 "",
5728 ""
5729 }, {
5730 "art_Moon_ZZ",
5731 "",
5732 ""
5733 }, {
5734 "art_Moon_CN",
5735 "",
5736 ""
5737 }, {
5738 "art_Moon_TW",
5739 "",
5740 ""
5741 }, {
5742 "art_Moon_HK",
5743 "",
5744 ""
5745 }, {
5746 "art_Moon_AQ",
5747 "",
5748 ""
729e4ab9
A
5749 }, {
5750 "de@collation=phonebook",
5751 "de_Latn_DE@collation=phonebook",
5752 "de@collation=phonebook"
46f4442e
A
5753 }
5754};
5755
5756typedef struct errorDataTag {
5757 const char* tag;
5758 const char* expected;
5759 UErrorCode uerror;
5760 int32_t bufferSize;
5761} errorData;
5762
5763const errorData maximizeErrors[] = {
5764 {
5765 "enfueiujhytdf",
5766 NULL,
5767 U_ILLEGAL_ARGUMENT_ERROR,
5768 -1
5769 },
5770 {
5771 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5772 NULL,
5773 U_ILLEGAL_ARGUMENT_ERROR,
5774 -1
5775 },
5776 {
5777 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5778 NULL,
5779 U_ILLEGAL_ARGUMENT_ERROR,
5780 -1
5781 },
5782 {
5783 "en_Latn_US_POSIX@currency=EURO",
5784 "en_Latn_US_POSIX@currency=EURO",
5785 U_BUFFER_OVERFLOW_ERROR,
5786 29
5787 },
5788 {
5789 "en_Latn_US_POSIX@currency=EURO",
5790 "en_Latn_US_POSIX@currency=EURO",
5791 U_STRING_NOT_TERMINATED_WARNING,
5792 30
5793 }
5794};
5795
5796const errorData minimizeErrors[] = {
5797 {
5798 "enfueiujhytdf",
5799 NULL,
5800 U_ILLEGAL_ARGUMENT_ERROR,
5801 -1
5802 },
5803 {
5804 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5805 NULL,
5806 U_ILLEGAL_ARGUMENT_ERROR,
5807 -1
5808 },
5809 {
5810 "en_Latn_US_POSIX@currency=EURO",
5811 "en__POSIX@currency=EURO",
5812 U_BUFFER_OVERFLOW_ERROR,
5813 22
5814 },
5815 {
5816 "en_Latn_US_POSIX@currency=EURO",
5817 "en__POSIX@currency=EURO",
5818 U_STRING_NOT_TERMINATED_WARNING,
5819 23
5820 }
5821};
5822
5823static int32_t getExpectedReturnValue(const errorData* data)
5824{
5825 if (data->uerror == U_BUFFER_OVERFLOW_ERROR ||
5826 data->uerror == U_STRING_NOT_TERMINATED_WARNING)
5827 {
3d1f044b 5828 return (int32_t)strlen(data->expected);
46f4442e
A
5829 }
5830 else
5831 {
5832 return -1;
5833 }
5834}
5835
5836static int32_t getBufferSize(const errorData* data, int32_t actualSize)
5837{
5838 if (data->expected == NULL)
5839 {
5840 return actualSize;
5841 }
5842 else if (data->bufferSize < 0)
5843 {
3d1f044b 5844 return (int32_t)strlen(data->expected) + 1;
46f4442e
A
5845 }
5846 else
5847 {
5848 return data->bufferSize;
5849 }
5850}
5851
5852static void TestLikelySubtags()
5853{
5854 char buffer[ULOC_FULLNAME_CAPACITY + ULOC_KEYWORD_AND_VALUES_CAPACITY + 1];
5855 int32_t i = 0;
5856
2ca993e8 5857 for (; i < UPRV_LENGTHOF(basic_maximize_data); ++i)
46f4442e
A
5858 {
5859 UErrorCode status = U_ZERO_ERROR;
5860 const char* const minimal = basic_maximize_data[i][0];
5861 const char* const maximal = basic_maximize_data[i][1];
5862
729e4ab9 5863 /* const int32_t length = */
46f4442e
A
5864 uloc_addLikelySubtags(
5865 minimal,
5866 buffer,
5867 sizeof(buffer),
5868 &status);
5869 if (U_FAILURE(status)) {
729e4ab9 5870 log_err_status(status, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status %s\n", minimal, u_errorName(status));
46f4442e
A
5871 status = U_ZERO_ERROR;
5872 }
5873 else if (uprv_strlen(maximal) == 0) {
5874 if (uprv_stricmp(minimal, buffer) != 0) {
5875 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
5876 }
5877 }
5878 else if (uprv_stricmp(maximal, buffer) != 0) {
5879 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %s\n", maximal, minimal, buffer);
5880 }
5881 }
5882
2ca993e8 5883 for (i = 0; i < UPRV_LENGTHOF(basic_minimize_data); ++i) {
46f4442e
A
5884
5885 UErrorCode status = U_ZERO_ERROR;
5886 const char* const maximal = basic_minimize_data[i][0];
5887 const char* const minimal = basic_minimize_data[i][1];
5888
729e4ab9 5889 /* const int32_t length = */
46f4442e
A
5890 uloc_minimizeSubtags(
5891 maximal,
5892 buffer,
5893 sizeof(buffer),
5894 &status);
5895
5896 if (U_FAILURE(status)) {
729e4ab9 5897 log_err_status(status, " unexpected failure of uloc_MinimizeSubtags(), maximal \"%s\" status %s\n", maximal, u_errorName(status));
46f4442e
A
5898 status = U_ZERO_ERROR;
5899 }
5900 else if (uprv_strlen(minimal) == 0) {
5901 if (uprv_stricmp(maximal, buffer) != 0) {
5902 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal, maximal, buffer);
5903 }
5904 }
5905 else if (uprv_stricmp(minimal, buffer) != 0) {
5906 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal, maximal, buffer);
5907 }
5908 }
5909
2ca993e8 5910 for (i = 0; i < UPRV_LENGTHOF(full_data); ++i) {
46f4442e
A
5911
5912 UErrorCode status = U_ZERO_ERROR;
5913 const char* const minimal = full_data[i][0];
5914 const char* const maximal = full_data[i][1];
5915
729e4ab9 5916 /* const int32_t length = */
46f4442e
A
5917 uloc_addLikelySubtags(
5918 minimal,
5919 buffer,
5920 sizeof(buffer),
5921 &status);
5922 if (U_FAILURE(status)) {
729e4ab9 5923 log_err_status(status, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status \"%s\"\n", minimal, u_errorName(status));
46f4442e
A
5924 status = U_ZERO_ERROR;
5925 }
5926 else if (uprv_strlen(maximal) == 0) {
5927 if (uprv_stricmp(minimal, buffer) != 0) {
5928 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
5929 }
5930 }
5931 else if (uprv_stricmp(maximal, buffer) != 0) {
5932 log_err(" maximal doesn't match expected \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
5933 }
5934 }
5935
2ca993e8 5936 for (i = 0; i < UPRV_LENGTHOF(full_data); ++i) {
46f4442e
A
5937
5938 UErrorCode status = U_ZERO_ERROR;
5939 const char* const maximal = full_data[i][1];
5940 const char* const minimal = full_data[i][2];
5941
5942 if (strlen(maximal) > 0) {
5943
729e4ab9 5944 /* const int32_t length = */
46f4442e
A
5945 uloc_minimizeSubtags(
5946 maximal,
5947 buffer,
5948 sizeof(buffer),
5949 &status);
5950
5951 if (U_FAILURE(status)) {
729e4ab9 5952 log_err_status(status, " unexpected failure of uloc_minimizeSubtags(), maximal \"%s\" status %s\n", maximal, u_errorName(status));
46f4442e
A
5953 status = U_ZERO_ERROR;
5954 }
5955 else if (uprv_strlen(minimal) == 0) {
5956 if (uprv_stricmp(maximal, buffer) != 0) {
5957 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal, maximal, buffer);
5958 }
5959 }
5960 else if (uprv_stricmp(minimal, buffer) != 0) {
5961 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal, maximal, buffer);
5962 }
5963 }
5964 }
5965
2ca993e8 5966 for (i = 0; i < UPRV_LENGTHOF(maximizeErrors); ++i) {
46f4442e
A
5967
5968 UErrorCode status = U_ZERO_ERROR;
5969 const char* const minimal = maximizeErrors[i].tag;
5970 const char* const maximal = maximizeErrors[i].expected;
5971 const UErrorCode expectedStatus = maximizeErrors[i].uerror;
5972 const int32_t expectedLength = getExpectedReturnValue(&maximizeErrors[i]);
5973 const int32_t bufferSize = getBufferSize(&maximizeErrors[i], sizeof(buffer));
5974
5975 const int32_t length =
5976 uloc_addLikelySubtags(
5977 minimal,
5978 buffer,
5979 bufferSize,
5980 &status);
5981
5982 if (status == U_ZERO_ERROR) {
5983 log_err(" unexpected U_ZERO_ERROR for uloc_addLikelySubtags(), minimal \"%s\" expected status %s\n", minimal, u_errorName(expectedStatus));
5984 status = U_ZERO_ERROR;
5985 }
5986 else if (status != expectedStatus) {
729e4ab9 5987 log_err_status(status, " unexpected status for uloc_addLikelySubtags(), minimal \"%s\" expected status %s, but got %s\n", minimal, u_errorName(expectedStatus), u_errorName(status));
46f4442e
A
5988 }
5989 else if (length != expectedLength) {
5990 log_err(" unexpected length for uloc_addLikelySubtags(), minimal \"%s\" expected length %d, but got %d\n", minimal, expectedLength, length);
5991 }
5992 else if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
5993 if (uprv_strnicmp(maximal, buffer, bufferSize) != 0) {
5994 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %*s\n",
5995 maximal, minimal, (int)sizeof(buffer), buffer);
5996 }
5997 }
5998 }
5999
2ca993e8 6000 for (i = 0; i < UPRV_LENGTHOF(minimizeErrors); ++i) {
46f4442e
A
6001
6002 UErrorCode status = U_ZERO_ERROR;
6003 const char* const maximal = minimizeErrors[i].tag;
6004 const char* const minimal = minimizeErrors[i].expected;
6005 const UErrorCode expectedStatus = minimizeErrors[i].uerror;
6006 const int32_t expectedLength = getExpectedReturnValue(&minimizeErrors[i]);
6007 const int32_t bufferSize = getBufferSize(&minimizeErrors[i], sizeof(buffer));
6008
6009 const int32_t length =
6010 uloc_minimizeSubtags(
6011 maximal,
6012 buffer,
6013 bufferSize,
6014 &status);
6015
6016 if (status == U_ZERO_ERROR) {
6017 log_err(" unexpected U_ZERO_ERROR for uloc_minimizeSubtags(), maximal \"%s\" expected status %s\n", maximal, u_errorName(expectedStatus));
6018 status = U_ZERO_ERROR;
6019 }
6020 else if (status != expectedStatus) {
729e4ab9 6021 log_err_status(status, " unexpected status for uloc_minimizeSubtags(), maximal \"%s\" expected status %s, but got %s\n", maximal, u_errorName(expectedStatus), u_errorName(status));
46f4442e
A
6022 }
6023 else if (length != expectedLength) {
6024 log_err(" unexpected length for uloc_minimizeSubtags(), maximal \"%s\" expected length %d, but got %d\n", maximal, expectedLength, length);
6025 }
6026 else if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
6027 if (uprv_strnicmp(minimal, buffer, bufferSize) != 0) {
6028 log_err(" minimal doesn't match expected \"%s\" in uloc_minimizeSubtags(), minimal \"%s\" = \"%*s\"\n",
6029 minimal, maximal, (int)sizeof(buffer), buffer);
6030 }
6031 }
6032 }
6033}
729e4ab9
A
6034
6035const char* const locale_to_langtag[][3] = {
729e4ab9
A
6036 {"", "und", "und"},
6037 {"en", "en", "en"},
6038 {"en_US", "en-US", "en-US"},
6039 {"iw_IL", "he-IL", "he-IL"},
6040 {"sr_Latn_SR", "sr-Latn-SR", "sr-Latn-SR"},
6041 {"en__POSIX", "en-u-va-posix", "en-u-va-posix"},
6042 {"en_POSIX", "en-u-va-posix", "en-u-va-posix"},
4388f060
A
6043 {"en_US_POSIX_VAR", "en-US-posix-x-lvariant-var", NULL}, /* variant POSIX_VAR is processed as regular variant */
6044 {"en_US_VAR_POSIX", "en-US-x-lvariant-var-posix", NULL}, /* variant VAR_POSIX is processed as regular variant */
6045 {"en_US_POSIX@va=posix2", "en-US-u-va-posix2", "en-US-u-va-posix2"}, /* if keyword va=xxx already exists, variant POSIX is simply dropped */
729e4ab9
A
6046 {"en_US_POSIX@ca=japanese", "en-US-u-ca-japanese-va-posix", "en-US-u-ca-japanese-va-posix"},
6047 {"und_555", "und-555", "und-555"},
6048 {"123", "und", NULL},
6049 {"%$#&", "und", NULL},
6050 {"_Latn", "und-Latn", "und-Latn"},
6051 {"_DE", "und-DE", "und-DE"},
6052 {"und_FR", "und-FR", "und-FR"},
4388f060 6053 {"th_TH_TH", "th-TH-x-lvariant-th", NULL},
729e4ab9
A
6054 {"bogus", "bogus", "bogus"},
6055 {"foooobarrr", "und", NULL},
4388f060 6056 {"aa_BB_CYRL", "aa-BB-x-lvariant-cyrl", NULL},
729e4ab9
A
6057 {"en_US_1234", "en-US-1234", "en-US-1234"},
6058 {"en_US_VARIANTA_VARIANTB", "en-US-varianta-variantb", "en-US-varianta-variantb"},
4388f060
A
6059 {"ja__9876_5432", "ja-9876-5432", "ja-9876-5432"},
6060 {"zh_Hant__VAR", "zh-Hant-x-lvariant-var", NULL},
729e4ab9
A
6061 {"es__BADVARIANT_GOODVAR", "es-goodvar", NULL},
6062 {"en@calendar=gregorian", "en-u-ca-gregory", "en-u-ca-gregory"},
6063 {"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
6064 {"th@numbers=thai;z=extz;x=priv-use;a=exta", "th-a-exta-u-nu-thai-z-extz-x-priv-use", "th-a-exta-u-nu-thai-z-extz-x-priv-use"},
6065 {"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
6066 {"en@timezone=US/Eastern", "en-u-tz-usnyc", "en-u-tz-usnyc"},
6067 {"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL},
b331163b 6068 {"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-cu-usd-eur-ks-identic", NULL},
729e4ab9 6069 {"en_US_POSIX", "en-US-u-va-posix", "en-US-u-va-posix"},
b331163b 6070 {"en_US_POSIX@calendar=japanese;currency=EUR","en-US-u-ca-japanese-cu-eur-va-posix", "en-US-u-ca-japanese-cu-eur-va-posix"},
729e4ab9
A
6071 {"@x=elmer", "x-elmer", "x-elmer"},
6072 {"en@x=elmer", "en-x-elmer", "en-x-elmer"},
6073 {"@x=elmer;a=exta", "und-a-exta-x-elmer", "und-a-exta-x-elmer"},
4388f060 6074 {"en_US@attribute=attr1-attr2;calendar=gregorian", "en-US-u-attr1-attr2-ca-gregory", "en-US-u-attr1-attr2-ca-gregory"},
f3c0d7a5
A
6075 /* #12671 */
6076 {"en@a=bar;attribute=baz", "en-a-bar-u-baz", "en-a-bar-u-baz"},
6077 {"en@a=bar;attribute=baz;x=u-foo", "en-a-bar-u-baz-x-u-foo", "en-a-bar-u-baz-x-u-foo"},
6078 {"en@attribute=baz", "en-u-baz", "en-u-baz"},
6079 {"en@attribute=baz;calendar=islamic-civil", "en-u-baz-ca-islamic-civil", "en-u-baz-ca-islamic-civil"},
6080 {"en@a=bar;calendar=islamic-civil;x=u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo"},
6081 {"en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", "en-a-bar-u-baz-ca-islamic-civil-x-u-foo", "en-a-bar-u-baz-ca-islamic-civil-x-u-foo"},
3d1f044b
A
6082 {"en@9=efg;a=baz", "en-9-efg-a-baz", "en-9-efg-a-baz"},
6083
6084 // Before ICU 64, ICU locale canonicalization had some additional mappings.
6085 // They were removed for ICU-20187 "drop support for long-obsolete locale ID variants".
6086 // The following now uses standard canonicalization.
6087 {"az_AZ_CYRL", "az-AZ-x-lvariant-cyrl", NULL},
6088
729e4ab9
A
6089 {NULL, NULL, NULL}
6090};
6091
6092static void TestToLanguageTag(void) {
6093 char langtag[256];
6094 int32_t i;
6095 UErrorCode status;
6096 int32_t len;
6097 const char *inloc;
6098 const char *expected;
6099
6100 for (i = 0; locale_to_langtag[i][0] != NULL; i++) {
6101 inloc = locale_to_langtag[i][0];
6102
6103 /* testing non-strict mode */
6104 status = U_ZERO_ERROR;
6105 langtag[0] = 0;
6106 expected = locale_to_langtag[i][1];
6107
6108 len = uloc_toLanguageTag(inloc, langtag, sizeof(langtag), FALSE, &status);
57a6839d 6109 (void)len; /* Suppress set but not used warning. */
729e4ab9
A
6110 if (U_FAILURE(status)) {
6111 if (expected != NULL) {
6112 log_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s\n",
6113 inloc, u_errorName(status));
6114 }
6115 } else {
6116 if (expected == NULL) {
6117 log_err("Error should be returned by uloc_toLanguageTag for locale id [%s], but [%s] is returned without errors\n",
6118 inloc, langtag);
6119 } else if (uprv_strcmp(langtag, expected) != 0) {
6120 log_data_err("uloc_toLanguageTag returned language tag [%s] for input locale [%s] - expected: [%s]. Are you missing data?\n",
6121 langtag, inloc, expected);
6122 }
6123 }
6124
6125 /* testing strict mode */
6126 status = U_ZERO_ERROR;
6127 langtag[0] = 0;
6128 expected = locale_to_langtag[i][2];
6129
6130 len = uloc_toLanguageTag(inloc, langtag, sizeof(langtag), TRUE, &status);
6131 if (U_FAILURE(status)) {
6132 if (expected != NULL) {
6133 log_data_err("Error returned by uloc_toLanguageTag {strict} for locale id [%s] - error: %s Are you missing data?\n",
6134 inloc, u_errorName(status));
6135 }
6136 } else {
6137 if (expected == NULL) {
6138 log_err("Error should be returned by uloc_toLanguageTag {strict} for locale id [%s], but [%s] is returned without errors\n",
6139 inloc, langtag);
6140 } else if (uprv_strcmp(langtag, expected) != 0) {
6141 log_err("uloc_toLanguageTag {strict} returned language tag [%s] for input locale [%s] - expected: [%s]\n",
6142 langtag, inloc, expected);
6143 }
6144 }
6145 }
6146}
6147
3d1f044b
A
6148static void TestBug20132(void) {
6149 char langtag[256];
6150 UErrorCode status;
6151 int32_t len;
6152
6153 static const char inloc[] = "en-C";
6154 static const char expected[] = "en-x-lvariant-c";
6155 const int32_t expected_len = (int32_t)uprv_strlen(expected);
6156
6157 /* Before ICU-20132 was fixed, calling uloc_toLanguageTag() with a too small
6158 * buffer would not immediately return the buffer size actually needed, but
6159 * instead require several iterations before getting the correct size. */
6160
6161 status = U_ZERO_ERROR;
6162 len = uloc_toLanguageTag(inloc, langtag, 1, FALSE, &status);
6163
6164 if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
6165 log_data_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s Are you missing data?\n",
6166 inloc, u_errorName(status));
6167 }
6168
6169 if (len != expected_len) {
6170 log_err("Bad length returned by uloc_toLanguageTag for locale id [%s]: %i != %i\n", inloc, len, expected_len);
6171 }
6172
6173 status = U_ZERO_ERROR;
6174 len = uloc_toLanguageTag(inloc, langtag, expected_len, FALSE, &status);
6175
6176 if (U_FAILURE(status)) {
6177 log_data_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s Are you missing data?\n",
6178 inloc, u_errorName(status));
6179 }
6180
6181 if (len != expected_len) {
6182 log_err("Bad length returned by uloc_toLanguageTag for locale id [%s]: %i != %i\n", inloc, len, expected_len);
6183 } else if (uprv_strncmp(langtag, expected, expected_len) != 0) {
6184 log_data_err("uloc_toLanguageTag returned language tag [%.*s] for input locale [%s] - expected: [%s]. Are you missing data?\n",
6185 len, langtag, inloc, expected);
6186 }
6187}
6188
51004dcb 6189#define FULL_LENGTH -1
729e4ab9
A
6190static const struct {
6191 const char *bcpID;
6192 const char *locID;
6193 int32_t len;
6194} langtag_to_locale[] = {
51004dcb
A
6195 {"en", "en", FULL_LENGTH},
6196 {"en-us", "en_US", FULL_LENGTH},
6197 {"und-US", "_US", FULL_LENGTH},
6198 {"und-latn", "_Latn", FULL_LENGTH},
6199 {"en-US-posix", "en_US_POSIX", FULL_LENGTH},
729e4ab9 6200 {"de-de_euro", "de", 2},
51004dcb 6201 {"kok-IN", "kok_IN", FULL_LENGTH},
729e4ab9
A
6202 {"123", "", 0},
6203 {"en_us", "", 0},
6204 {"en-latn-x", "en_Latn", 7},
51004dcb
A
6205 {"art-lojban", "jbo", FULL_LENGTH},
6206 {"zh-hakka", "hak", FULL_LENGTH},
6207 {"zh-cmn-CH", "cmn_CH", FULL_LENGTH},
3d1f044b 6208 {"zh-cmn-CH-u-co-pinyin", "cmn_CH@collation=pinyin", FULL_LENGTH},
51004dcb
A
6209 {"xxx-yy", "xxx_YY", FULL_LENGTH},
6210 {"fr-234", "fr_234", FULL_LENGTH},
6211 {"i-default", "en@x=i-default", FULL_LENGTH},
729e4ab9
A
6212 {"i-test", "", 0},
6213 {"ja-jp-jp", "ja_JP", 5},
51004dcb 6214 {"bogus", "bogus", FULL_LENGTH},
729e4ab9 6215 {"boguslang", "", 0},
51004dcb
A
6216 {"EN-lATN-us", "en_Latn_US", FULL_LENGTH},
6217 {"und-variant-1234", "__VARIANT_1234", FULL_LENGTH},
729e4ab9 6218 {"und-varzero-var1-vartwo", "__VARZERO", 11},
51004dcb
A
6219 {"en-u-ca-gregory", "en@calendar=gregorian", FULL_LENGTH},
6220 {"en-U-cu-USD", "en@currency=usd", FULL_LENGTH},
6221 {"en-US-u-va-posix", "en_US_POSIX", FULL_LENGTH},
6222 {"en-us-u-ca-gregory-va-posix", "en_US_POSIX@calendar=gregorian", FULL_LENGTH},
6223 {"en-us-posix-u-va-posix", "en_US_POSIX@va=posix", FULL_LENGTH},
6224 {"en-us-u-va-posix2", "en_US@va=posix2", FULL_LENGTH},
6225 {"en-us-vari1-u-va-posix", "en_US_VARI1@va=posix", FULL_LENGTH},
6226 {"ar-x-1-2-3", "ar@x=1-2-3", FULL_LENGTH},
6227 {"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", FULL_LENGTH},
6228 {"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", FULL_LENGTH},
6229 {"ja-u-cu-jpy-ca-jp", "ja@calendar=yes;currency=jpy;jp=yes", FULL_LENGTH},
6230 {"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", FULL_LENGTH},
6231 {"und-a-abc-def", "und@a=abc-def", FULL_LENGTH},
6232 {"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", FULL_LENGTH},
6233 {"x-elmer", "@x=elmer", FULL_LENGTH},
6234 {"en-US-u-attr1-attr2-ca-gregory", "en_US@attribute=attr1-attr2;calendar=gregorian", FULL_LENGTH},
6235 {"sr-u-kn", "sr@colnumeric=yes", FULL_LENGTH},
6236 {"de-u-kn-co-phonebk", "de@collation=phonebook;colnumeric=yes", FULL_LENGTH},
6237 {"en-u-attr2-attr1-kn-kb", "en@attribute=attr1-attr2;colbackwards=yes;colnumeric=yes", FULL_LENGTH},
6238 {"ja-u-ijkl-efgh-abcd-ca-japanese-xx-yyy-zzz-kn", "ja@attribute=abcd-efgh-ijkl;calendar=japanese;colnumeric=yes;xx=yyy-zzz", FULL_LENGTH},
4388f060 6239 {"de-u-xc-xphonebk-co-phonebk-ca-buddhist-mo-very-lo-extensi-xd-that-de-should-vc-probably-xz-killthebuffer",
51004dcb 6240 "de@calendar=buddhist;collation=phonebook;de=should;lo=extensi;mo=very;vc=probably;xc=xphonebk;xd=that;xz=yes", 91},
3d1f044b
A
6241 {"de-1901-1901", "de__1901", 7},
6242 {"de-DE-1901-1901", "de_DE_1901", 10},
6243 {"en-a-bbb-a-ccc", "en@a=bbb", 8},
f3c0d7a5
A
6244 /* #12761 */
6245 {"en-a-bar-u-baz", "en@a=bar;attribute=baz", FULL_LENGTH},
6246 {"en-a-bar-u-baz-x-u-foo", "en@a=bar;attribute=baz;x=u-foo", FULL_LENGTH},
6247 {"en-u-baz", "en@attribute=baz", FULL_LENGTH},
6248 {"en-u-baz-ca-islamic-civil", "en@attribute=baz;calendar=islamic-civil", FULL_LENGTH},
6249 {"en-a-bar-u-ca-islamic-civil-x-u-foo", "en@a=bar;calendar=islamic-civil;x=u-foo", FULL_LENGTH},
6250 {"en-a-bar-u-baz-ca-islamic-civil-x-u-foo", "en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", FULL_LENGTH},
0f5d89e8
A
6251 {"und-Arab-u-em-emoji", "_Arab@em=emoji", FULL_LENGTH},
6252 {"und-Latn-u-em-emoji", "_Latn@em=emoji", FULL_LENGTH},
6253 {"und-Latn-DE-u-em-emoji", "_Latn_DE@em=emoji", FULL_LENGTH},
6254 {"und-Zzzz-DE-u-em-emoji", "_Zzzz_DE@em=emoji", FULL_LENGTH},
6255 {"und-DE-u-em-emoji", "_DE@em=emoji", FULL_LENGTH},
3d1f044b
A
6256 // #20098
6257 {"hant-cmn-cn", "hant", 4},
6258 {"zh-cmn-TW", "cmn_TW", FULL_LENGTH},
6259 {"zh-x_t-ab", "zh", 2},
6260 {"zh-hans-cn-u-ca-x_t-u", "zh_Hans_CN@calendar=yes", 15},
6261 /* #20140 dupe keys in U-extension */
6262 {"zh-u-ca-chinese-ca-gregory", "zh@calendar=chinese", FULL_LENGTH},
6263 {"zh-u-ca-gregory-co-pinyin-ca-chinese", "zh@calendar=gregorian;collation=pinyin", FULL_LENGTH},
6264 {"de-latn-DE-1901-u-co-phonebk-co-pinyin-ca-gregory", "de_Latn_DE_1901@calendar=gregorian;collation=phonebook", FULL_LENGTH},
6265 {"th-u-kf-nu-thai-kf-false", "th@colcasefirst=yes;numbers=thai", FULL_LENGTH},
6266 /* #9562 IANA language tag data update */
6267 {"en-gb-oed", "en_GB_OXENDICT", FULL_LENGTH},
6268 {"i-navajo", "nv", FULL_LENGTH},
6269 {"i-navajo-a-foo", "nv@a=foo", FULL_LENGTH},
6270 {"i-navajo-latn-us", "nv_Latn_US", FULL_LENGTH},
6271 {"sgn-br", "bzs", FULL_LENGTH},
6272 {"sgn-br-u-co-phonebk", "bzs@collation=phonebook", FULL_LENGTH},
6273 {"ja-latn-hepburn-heploc", "ja_Latn__ALALC97", FULL_LENGTH},
6274 {"ja-latn-hepburn-heploc-u-ca-japanese", "ja_Latn__ALALC97@calendar=japanese", FULL_LENGTH},
6275 {"en-a-bcde-0-fgh", "en@0=fgh;a=bcde", FULL_LENGTH},
729e4ab9
A
6276};
6277
6278static void TestForLanguageTag(void) {
6279 char locale[256];
6280 int32_t i;
6281 UErrorCode status;
6282 int32_t parsedLen;
51004dcb 6283 int32_t expParsedLen;
729e4ab9 6284
3d1f044b 6285 for (i = 0; i < UPRV_LENGTHOF(langtag_to_locale); i++) {
729e4ab9 6286 status = U_ZERO_ERROR;
51004dcb
A
6287 locale[0] = 0;
6288 expParsedLen = langtag_to_locale[i].len;
6289 if (expParsedLen == FULL_LENGTH) {
3d1f044b 6290 expParsedLen = (int32_t)uprv_strlen(langtag_to_locale[i].bcpID);
51004dcb 6291 }
729e4ab9
A
6292 uloc_forLanguageTag(langtag_to_locale[i].bcpID, locale, sizeof(locale), &parsedLen, &status);
6293 if (U_FAILURE(status)) {
6294 log_err_status(status, "Error returned by uloc_forLanguageTag for language tag [%s] - error: %s\n",
6295 langtag_to_locale[i].bcpID, u_errorName(status));
6296 } else {
6297 if (uprv_strcmp(langtag_to_locale[i].locID, locale) != 0) {
b331163b 6298 log_data_err("uloc_forLanguageTag returned locale [%s] for input language tag [%s] - expected: [%s]\n",
729e4ab9
A
6299 locale, langtag_to_locale[i].bcpID, langtag_to_locale[i].locID);
6300 }
51004dcb 6301 if (parsedLen != expParsedLen) {
729e4ab9 6302 log_err("uloc_forLanguageTag parsed length of %d for input language tag [%s] - expected parsed length: %d\n",
51004dcb 6303 parsedLen, langtag_to_locale[i].bcpID, expParsedLen);
729e4ab9
A
6304 }
6305 }
6306 }
6307}
6308
3d1f044b
A
6309/* See https://unicode-org.atlassian.net/browse/ICU-20149 .
6310 * Depending on the resolution of that bug, this test may have
6311 * to be revised.
6312 */
6313static void TestInvalidLanguageTag(void) {
6314 static const char* invalid_lang_tags[] = {
6315 "zh-u-foo-foo-co-pinyin", /* duplicate attribute in U extension */
6316 "zh-cmn-hans-u-foo-foo-co-pinyin", /* duplicate attribute in U extension */
6317#if 0
6318 /*
6319 * These do not lead to an error. Instead, parsing stops at the 1st
6320 * invalid subtag.
6321 */
6322 "de-DE-1901-1901", /* duplicate variant */
6323 "en-a-bbb-a-ccc", /* duplicate extension */
6324#endif
6325 NULL
6326 };
6327 char locale[256];
6328 for (const char** tag = invalid_lang_tags; *tag != NULL; tag++) {
6329 UErrorCode status = U_ZERO_ERROR;
6330 uloc_forLanguageTag(*tag, locale, sizeof(locale), NULL, &status);
6331 if (status != U_ILLEGAL_ARGUMENT_ERROR) {
6332 log_err("Error returned by uloc_forLanguageTag for input language tag [%s] : %s - expected error: %s\n",
6333 *tag, u_errorName(status), u_errorName(U_ILLEGAL_ARGUMENT_ERROR));
6334 }
6335 }
6336}
6337
6338static const struct {
6339 const char *input;
6340 const char *canonical;
6341} langtag_to_canonical[] = {
6342 {"de-DD", "de-DE"},
6343 {"de-DD-u-co-phonebk", "de-DE-u-co-phonebk"},
6344 {"jw-id", "jv-ID"},
6345 {"jw-id-u-ca-islamic-civil", "jv-ID-u-ca-islamic-civil"},
6346 {"mo-md", "ro-MD"},
6347 {"my-bu-u-nu-mymr", "my-MM-u-nu-mymr"},
6348 {"yuu-ru", "yug-RU"},
6349};
6350
6351
6352static void TestLangAndRegionCanonicalize(void) {
6353 char locale[256];
6354 char canonical[256];
6355 int32_t i;
6356 UErrorCode status;
6357 for (i = 0; i < UPRV_LENGTHOF(langtag_to_canonical); i++) {
6358 status = U_ZERO_ERROR;
6359 const char* input = langtag_to_canonical[i].input;
6360 uloc_forLanguageTag(input, locale, sizeof(locale), NULL, &status);
6361 uloc_toLanguageTag(locale, canonical, sizeof(canonical), TRUE, &status);
6362 if (U_FAILURE(status)) {
6363 log_err_status(status, "Error returned by uloc_forLanguageTag or uloc_toLanguageTag "
6364 "for language tag [%s] - error: %s\n", input, u_errorName(status));
6365 } else {
6366 const char* expected_canonical = langtag_to_canonical[i].canonical;
6367 if (uprv_strcmp(expected_canonical, canonical) != 0) {
6368 log_data_err("input language tag [%s] is canonicalized to [%s] - expected: [%s]\n",
6369 input, canonical, expected_canonical);
6370 }
6371 }
6372 }
6373}
6374
b331163b
A
6375static void TestToUnicodeLocaleKey(void)
6376{
6377 /* $IN specifies the result should be the input pointer itself */
6378 static const char* DATA[][2] = {
6379 {"calendar", "ca"},
6380 {"CALEndar", "ca"}, /* difference casing */
6381 {"ca", "ca"}, /* bcp key itself */
6382 {"kv", "kv"}, /* no difference between legacy and bcp */
6383 {"foo", NULL}, /* unknown, bcp ill-formed */
6384 {"ZZ", "$IN"}, /* unknown, bcp well-formed - */
6385 {NULL, NULL}
6386 };
6387
6388 int32_t i;
6389 for (i = 0; DATA[i][0] != NULL; i++) {
6390 const char* keyword = DATA[i][0];
6391 const char* expected = DATA[i][1];
6392 const char* bcpKey = NULL;
6393
6394 bcpKey = uloc_toUnicodeLocaleKey(keyword);
6395 if (expected == NULL) {
6396 if (bcpKey != NULL) {
6397 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=NULL\n", keyword, bcpKey);
6398 }
6399 } else if (bcpKey == NULL) {
6400 log_data_err("toUnicodeLocaleKey: keyword=%s => NULL, expected=%s\n", keyword, expected);
6401 } else if (uprv_strcmp(expected, "$IN") == 0) {
6402 if (bcpKey != keyword) {
6403 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword, bcpKey, keyword);
6404 }
6405 } else if (uprv_strcmp(bcpKey, expected) != 0) {
6406 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s\n", keyword, bcpKey, expected);
6407 }
6408 }
6409}
6410
3d1f044b
A
6411static void TestBug20321UnicodeLocaleKey(void)
6412{
6413 // key = alphanum alpha ;
6414 static const char* invalid[] = {
6415 "a0",
6416 "00",
6417 "a@",
6418 "0@",
6419 "@a",
6420 "@a",
6421 "abc",
6422 "0bc",
6423 };
6424 for (int i = 0; i < UPRV_LENGTHOF(invalid); i++) {
6425 const char* bcpKey = NULL;
6426 bcpKey = uloc_toUnicodeLocaleKey(invalid[i]);
6427 if (bcpKey != NULL) {
6428 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=NULL\n", invalid[i], bcpKey);
6429 }
6430 }
6431 static const char* valid[] = {
6432 "aa",
6433 "0a",
6434 };
6435 for (int i = 0; i < UPRV_LENGTHOF(valid); i++) {
6436 const char* bcpKey = NULL;
6437 bcpKey = uloc_toUnicodeLocaleKey(valid[i]);
6438 if (bcpKey == NULL) {
6439 log_err("toUnicodeLocaleKey: keyword=%s => NULL, expected!=NULL\n", valid[i]);
6440 }
6441 }
6442}
6443
b331163b
A
6444static void TestToLegacyKey(void)
6445{
6446 /* $IN specifies the result should be the input pointer itself */
6447 static const char* DATA[][2] = {
6448 {"kb", "colbackwards"},
6449 {"kB", "colbackwards"}, /* different casing */
6450 {"Collation", "collation"}, /* keyword itself with different casing */
6451 {"kv", "kv"}, /* no difference between legacy and bcp */
6452 {"foo", "$IN"}, /* unknown, bcp ill-formed */
6453 {"ZZ", "$IN"}, /* unknown, bcp well-formed */
6454 {"e=mc2", NULL}, /* unknown, bcp/legacy ill-formed */
6455 {NULL, NULL}
6456 };
6457
6458 int32_t i;
6459 for (i = 0; DATA[i][0] != NULL; i++) {
6460 const char* keyword = DATA[i][0];
6461 const char* expected = DATA[i][1];
6462 const char* legacyKey = NULL;
6463
6464 legacyKey = uloc_toLegacyKey(keyword);
6465 if (expected == NULL) {
6466 if (legacyKey != NULL) {
6467 log_err("toLegacyKey: keyword=%s => %s, expected=NULL\n", keyword, legacyKey);
6468 }
6469 } else if (legacyKey == NULL) {
6470 log_err("toLegacyKey: keyword=%s => NULL, expected=%s\n", keyword, expected);
6471 } else if (uprv_strcmp(expected, "$IN") == 0) {
6472 if (legacyKey != keyword) {
6473 log_err("toLegacyKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword, legacyKey, keyword);
6474 }
6475 } else if (uprv_strcmp(legacyKey, expected) != 0) {
6476 log_data_err("toUnicodeLocaleKey: keyword=%s, %s, expected=%s\n", keyword, legacyKey, expected);
6477 }
6478 }
6479}
6480
6481static void TestToUnicodeLocaleType(void)
6482{
6483 /* $IN specifies the result should be the input pointer itself */
6484 static const char* DATA[][3] = {
6485 {"tz", "Asia/Kolkata", "inccu"},
6486 {"calendar", "gregorian", "gregory"},
6487 {"ca", "gregorian", "gregory"},
6488 {"ca", "Gregorian", "gregory"},
6489 {"ca", "buddhist", "buddhist"},
6490 {"Calendar", "Japanese", "japanese"},
6491 {"calendar", "Islamic-Civil", "islamic-civil"},
6492 {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */
6493 {"colalternate", "NON-IGNORABLE", "noignore"},
6494 {"colcaselevel", "yes", "true"},
2ca993e8 6495 {"rg", "GBzzzz", "$IN"},
b331163b
A
6496 {"tz", "america/new_york", "usnyc"},
6497 {"tz", "Asia/Kolkata", "inccu"},
6498 {"timezone", "navajo", "usden"},
6499 {"ca", "aaaa", "$IN"}, /* unknown type, well-formed type */
6500 {"ca", "gregory-japanese-islamic", "$IN"}, /* unknown type, well-formed type */
6501 {"zz", "gregorian", NULL}, /* unknown key, ill-formed type */
6502 {"co", "foo-", NULL}, /* unknown type, ill-formed type */
6503 {"variableTop", "00A0", "$IN"}, /* valid codepoints type */
6504 {"variableTop", "wxyz", "$IN"}, /* invalid codepoints type - return as is for now */
6505 {"kr", "space-punct", "space-punct"}, /* valid reordercode type */
6506 {"kr", "digit-spacepunct", NULL}, /* invalid (bcp ill-formed) reordercode type */
6507 {NULL, NULL, NULL}
6508 };
6509
6510 int32_t i;
6511 for (i = 0; DATA[i][0] != NULL; i++) {
6512 const char* keyword = DATA[i][0];
6513 const char* value = DATA[i][1];
6514 const char* expected = DATA[i][2];
6515 const char* bcpType = NULL;
6516
6517 bcpType = uloc_toUnicodeLocaleType(keyword, value);
6518 if (expected == NULL) {
6519 if (bcpType != NULL) {
6520 log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=NULL\n", keyword, value, bcpType);
6521 }
6522 } else if (bcpType == NULL) {
6523 log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => NULL, expected=%s\n", keyword, value, expected);
6524 } else if (uprv_strcmp(expected, "$IN") == 0) {
6525 if (bcpType != value) {
6526 log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword, value, bcpType, value);
6527 }
6528 } else if (uprv_strcmp(bcpType, expected) != 0) {
6529 log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s\n", keyword, value, bcpType, expected);
6530 }
6531 }
6532}
6533
6534static void TestToLegacyType(void)
6535{
6536 /* $IN specifies the result should be the input pointer itself */
6537 static const char* DATA[][3] = {
6538 {"calendar", "gregory", "gregorian"},
6539 {"ca", "gregory", "gregorian"},
6540 {"ca", "Gregory", "gregorian"},
6541 {"ca", "buddhist", "buddhist"},
6542 {"Calendar", "Japanese", "japanese"},
6543 {"calendar", "Islamic-Civil", "islamic-civil"},
6544 {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */
6545 {"colalternate", "noignore", "non-ignorable"},
6546 {"colcaselevel", "true", "yes"},
2ca993e8 6547 {"rg", "gbzzzz", "gbzzzz"},
b331163b
A
6548 {"tz", "usnyc", "America/New_York"},
6549 {"tz", "inccu", "Asia/Calcutta"},
6550 {"timezone", "usden", "America/Denver"},
6551 {"timezone", "usnavajo", "America/Denver"}, /* bcp type alias */
6552 {"colstrength", "quarternary", "quaternary"}, /* type alias */
6553 {"ca", "aaaa", "$IN"}, /* unknown type */
6554 {"calendar", "gregory-japanese-islamic", "$IN"}, /* unknown type, well-formed type */
6555 {"zz", "gregorian", "$IN"}, /* unknown key, bcp ill-formed type */
6556 {"ca", "gregorian-calendar", "$IN"}, /* known key, bcp ill-formed type */
6557 {"co", "e=mc2", NULL}, /* known key, ill-formed bcp/legacy type */
6558 {"variableTop", "00A0", "$IN"}, /* valid codepoints type */
6559 {"variableTop", "wxyz", "$IN"}, /* invalid codepoints type - return as is for now */
6560 {"kr", "space-punct", "space-punct"}, /* valid reordercode type */
6561 {"kr", "digit-spacepunct", "digit-spacepunct"}, /* invalid reordercode type, but ok for legacy syntax */
6562 {NULL, NULL, NULL}
6563 };
6564
6565 int32_t i;
6566 for (i = 0; DATA[i][0] != NULL; i++) {
6567 const char* keyword = DATA[i][0];
6568 const char* value = DATA[i][1];
6569 const char* expected = DATA[i][2];
6570 const char* legacyType = NULL;
6571
6572 legacyType = uloc_toLegacyType(keyword, value);
6573 if (expected == NULL) {
6574 if (legacyType != NULL) {
6575 log_err("toLegacyType: keyword=%s, value=%s => %s, expected=NULL\n", keyword, value, legacyType);
6576 }
6577 } else if (legacyType == NULL) {
6578 log_err("toLegacyType: keyword=%s, value=%s => NULL, expected=%s\n", keyword, value, expected);
6579 } else if (uprv_strcmp(expected, "$IN") == 0) {
6580 if (legacyType != value) {
6581 log_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword, value, legacyType, value);
6582 }
6583 } else if (uprv_strcmp(legacyType, expected) != 0) {
6584 log_data_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s\n", keyword, value, legacyType, expected);
f3c0d7a5
A
6585 } else {
6586 log_verbose("toLegacyType: keyword=%s, value=%s => %s\n", keyword, value, legacyType);
b331163b
A
6587 }
6588 }
6589}
6590
6591
6592
729e4ab9
A
6593static void test_unicode_define(const char *namech, char ch, const char *nameu, UChar uch)
6594{
6595 UChar asUch[1];
6596 asUch[0]=0;
6597 log_verbose("Testing whether %s[\\x%02x,'%c'] == %s[U+%04X]\n", namech, ch,(int)ch, nameu, (int) uch);
6598 u_charsToUChars(&ch, asUch, 1);
6599 if(asUch[0] != uch) {
6600 log_err("FAIL: %s[\\x%02x,'%c'] maps to U+%04X, but %s = U+%04X\n", namech, ch, (int)ch, (int)asUch[0], nameu, (int)uch);
6601 } else {
6602 log_verbose(" .. OK, == U+%04X\n", (int)asUch[0]);
6603 }
6604}
6605
6606#define TEST_UNICODE_DEFINE(x,y) test_unicode_define(#x, (char)(x), #y, (UChar)(y))
6607
6608static void TestUnicodeDefines(void) {
6609 TEST_UNICODE_DEFINE(ULOC_KEYWORD_SEPARATOR, ULOC_KEYWORD_SEPARATOR_UNICODE);
6610 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ASSIGN, ULOC_KEYWORD_ASSIGN_UNICODE);
6611 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ITEM_SEPARATOR, ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE);
6612}
08b89b0a 6613
b331163b
A
6614static void TestIsRightToLeft() {
6615 // API test only. More test cases in intltest/LocaleTest.
6616 if(uloc_isRightToLeft("root") || !uloc_isRightToLeft("EN-HEBR")) {
6617 log_err("uloc_isRightToLeft() failed");
6618 }
6619}
6620
f3c0d7a5
A
6621typedef struct {
6622 const char * badLocaleID;
6623 const char * displayLocale;
6624 const char * expectedName;
6625 UErrorCode expectedStatus;
6626} BadLocaleItem;
6627
6628static const BadLocaleItem badLocaleItems[] = {
6629 { "-9223372036854775808", "en", "9223372036854775808", U_USING_DEFAULT_WARNING },
6630 /* add more in the future */
6631 { NULL, NULL, NULL, U_ZERO_ERROR } /* terminator */
6632};
6633
6634enum { kUBufDispNameMax = 128, kBBufDispNameMax = 256 };
6635
6636static void TestBadLocaleIDs() {
6637 const BadLocaleItem* itemPtr;
6638 for (itemPtr = badLocaleItems; itemPtr->badLocaleID != NULL; itemPtr++) {
6639 UChar ubufExpect[kUBufDispNameMax], ubufGet[kUBufDispNameMax];
6640 UErrorCode status = U_ZERO_ERROR;
6641 int32_t ulenExpect = u_unescape(itemPtr->expectedName, ubufExpect, kUBufDispNameMax);
6642 int32_t ulenGet = uloc_getDisplayName(itemPtr->badLocaleID, itemPtr->displayLocale, ubufGet, kUBufDispNameMax, &status);
6643 if (status != itemPtr->expectedStatus ||
6644 (U_SUCCESS(status) && (ulenGet != ulenExpect || u_strncmp(ubufGet, ubufExpect, ulenExpect) != 0))) {
6645 char bbufExpect[kBBufDispNameMax], bbufGet[kBBufDispNameMax];
6646 u_austrncpy(bbufExpect, ubufExpect, ulenExpect);
6647 u_austrncpy(bbufGet, ubufGet, ulenGet);
6648 log_err("FAIL: For localeID %s, displayLocale %s, calling uloc_getDisplayName:\n"
6649 " expected status %-26s, name (len %2d): %s\n"
6650 " got status %-26s, name (len %2d): %s\n",
6651 itemPtr->badLocaleID, itemPtr->displayLocale,
6652 u_errorName(itemPtr->expectedStatus), ulenExpect, bbufExpect,
6653 u_errorName(status), ulenGet, bbufGet );
6654 }
6655 }
6656}
6657
3d1f044b
A
6658// Test case for ICU-20370.
6659// The issue shows as an Addresss Sanitizer failure.
6660static void TestBug20370() {
6661 const char *localeID = "x-privatebutreallylongtagfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobar";
6662 uint32_t lcid = uloc_getLCID(localeID);
6663 if (lcid != 0) {
6664 log_err("FAIL: Expected LCID value of 0 for invalid localeID input.");
6665 }
6666}
6667
2ca993e8
A
6668typedef enum UldnNameType {
6669 TEST_ULDN_LOCALE,
6670 TEST_ULDN_LANGUAGE,
6671 TEST_ULDN_SCRIPT,
6672 TEST_ULDN_REGION,
3d1f044b
A
6673 TEST_ULOC_LOCALE, // only valid with optStdMidLong
6674 TEST_ULOC_LANGUAGE, // only valid with optStdMidLong
6675 TEST_ULOC_SCRIPT, // only valid with optStdMidLong
6676 TEST_ULOC_REGION, // only valid with optStdMidLong
2ca993e8
A
6677} UldnNameType;
6678
6679typedef struct {
6680 const char * localeToName; // NULL to terminate a list of these
6681 UldnNameType nameType;
3d1f044b 6682 const UChar * expectResult;
2ca993e8
A
6683} UldnItem;
6684
6685typedef struct {
6686 const char * displayLocale;
6687 const UDisplayContext * displayOptions; // set of 3 UDisplayContext items
6688 const UldnItem * testItems;
6689 int32_t countItems;
6690} UldnLocAndOpts;
6691
6692static const UDisplayContext optStdMidLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
6693static const UDisplayContext optStdMidShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
6694static const UDisplayContext optDiaMidLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
6695static const UDisplayContext optDiaMidShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
6696
6697static const UDisplayContext optStdBegLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
6698static const UDisplayContext optStdBegShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
6699static const UDisplayContext optDiaBegLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
6700static const UDisplayContext optDiaBegShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
6701
6702static const UDisplayContext optStdLstLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_FULL};
6703static const UDisplayContext optStdLstShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_SHORT};
6704static const UDisplayContext optDiaLstLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_FULL};
6705static const UDisplayContext optDiaLstShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_SHORT};
6706
6707static const UldnItem en_StdMidLong[] = {
3d1f044b
A
6708 { "en_US", TEST_ULDN_LOCALE, u"English (US)" },
6709 { "en_US_POSIX", TEST_ULDN_LOCALE, u"English (US, Computer)" },
6710 { "en_US@calendar=chinese", TEST_ULDN_LOCALE, u"English (US, Chinese Calendar)" },
6711 { "en_CA", TEST_ULDN_LOCALE, u"English (Canada)" },
6712 { "pt", TEST_ULDN_LOCALE, u"Portuguese" },
6713 { "pt_BR", TEST_ULDN_LOCALE, u"Portuguese (Brazil)" },
6714 { "pt_PT", TEST_ULDN_LOCALE, u"Portuguese (Portugal)" },
6715 { "zh_Hans", TEST_ULDN_LOCALE, u"Chinese, Simplified" }, // Apple <rdar://problem/50750364>
6716 { "zh_Hans_CN", TEST_ULDN_LOCALE, u"Chinese, Simplified (China mainland)" }, // Apple <rdar://problem/50750364>
6717 { "zh_Hant", TEST_ULDN_LOCALE, u"Chinese, Traditional" }, // Apple <rdar://problem/50750364>
6718 { "zh_Hant_HK", TEST_ULDN_LOCALE, u"Chinese, Traditional (Hong Kong)" }, // Apple <rdar://problem/50750364>
6719 { "yue_Hans", TEST_ULDN_LOCALE, u"Cantonese, Simplified" }, // Apple <rdar://problem/50750364>
6720 { "yue_Hans_CN", TEST_ULDN_LOCALE, u"Cantonese, Simplified (China mainland)" }, // Apple <rdar://problem/50750364>
6721 { "yue_Hant", TEST_ULDN_LOCALE, u"Cantonese, Traditional" }, // Apple <rdar://problem/50750364>
6722 { "yue_Hant_HK", TEST_ULDN_LOCALE, u"Cantonese, Traditional (Hong Kong)" }, // Apple <rdar://problem/50750364>
6723 { "zh_Hans@calendar=chinese", TEST_ULDN_LOCALE, u"Chinese, Simplified (Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6724 { "zh_Hans_CN@calendar=chinese", TEST_ULDN_LOCALE, u"Chinese, Simplified (China mainland, Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6725 { "zh_Hant@calendar=chinese", TEST_ULDN_LOCALE, u"Chinese, Traditional (Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6726 { "zh_Hant_HK@calendar=chinese", TEST_ULDN_LOCALE, u"Chinese, Traditional (Hong Kong, Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6727 { "yue_Hans@calendar=chinese", TEST_ULDN_LOCALE, u"Cantonese, Simplified (Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6728 { "yue_Hans_CN@calendar=chinese", TEST_ULDN_LOCALE, u"Cantonese, Simplified (China mainland, Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6729 { "yue_Hant@calendar=chinese", TEST_ULDN_LOCALE, u"Cantonese, Traditional (Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6730 { "yue_Hant_HK@calendar=chinese", TEST_ULDN_LOCALE, u"Cantonese, Traditional (Hong Kong, Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6731 { "zh_HK", TEST_ULDN_LOCALE, u"Chinese (Hong Kong)" },
6732 { "Latn", TEST_ULDN_SCRIPT, u"Latin" },
6733 { "Hans", TEST_ULDN_SCRIPT, u"Simplified Han" },
6734 { "Hant", TEST_ULDN_SCRIPT, u"Traditional Han" },
6735 { "US", TEST_ULDN_REGION, u"United States" },
6736 { "CA", TEST_ULDN_REGION, u"Canada" },
6737 { "GB", TEST_ULDN_REGION, u"United Kingdom" },
6738 { "HK", TEST_ULDN_REGION, u"Hong Kong" },
6739 { "ps_Arab", TEST_ULDN_LOCALE, u"Pashto (Arabic)" },
6740 { "ps_Arab_AF", TEST_ULDN_LOCALE, u"Pashto (Arabic, Afghanistan)" },
6741 { "ks_Arab", TEST_ULDN_LOCALE, u"Kashmiri (Naskh)" }, // Apple <rdar://problem/50687287>
6742 { "ks_Aran", TEST_ULDN_LOCALE, u"Kashmiri (Nastaliq)" }, // Apple <rdar://problem/47494884>
6743 { "ks_Arab_IN", TEST_ULDN_LOCALE, u"Kashmiri (Naskh, India)" }, // Apple <rdar://problem/50687287>
6744 { "ks_Aran_IN", TEST_ULDN_LOCALE, u"Kashmiri (Nastaliq, India)" }, // Apple <rdar://problem/47494884>
6745 { "pa_Arab", TEST_ULDN_LOCALE, u"Punjabi (Naskh)" }, // Apple <rdar://problem/50687287>
6746 { "pa_Aran", TEST_ULDN_LOCALE, u"Punjabi (Nastaliq)" }, // Apple <rdar://problem/50687287>
6747 { "pa_Arab_PK", TEST_ULDN_LOCALE, u"Punjabi (Naskh, Pakistan)" }, // Apple <rdar://problem/50687287>
6748 { "pa_Aran_PK", TEST_ULDN_LOCALE, u"Punjabi (Nastaliq, Pakistan)" }, // Apple <rdar://problem/50687287>
6749 { "ur_Arab", TEST_ULDN_LOCALE, u"Urdu (Naskh)" }, // Apple <rdar://problem/50687287>
6750 { "ur_Aran", TEST_ULDN_LOCALE, u"Urdu (Nastaliq)" }, // Apple <rdar://problem/47494884>
6751 { "ur_Arab_PK", TEST_ULDN_LOCALE, u"Urdu (Naskh, Pakistan)" }, // Apple <rdar://problem/50687287>
6752 { "ur_Aran_PK", TEST_ULDN_LOCALE, u"Urdu (Nastaliq, Pakistan)" }, // Apple <rdar://problem/47494884>
6753 { "ps_Arab@calendar=islamic", TEST_ULDN_LOCALE, u"Pashto (Arabic, Islamic Calendar)" },
6754 { "ps_Arab_AF@calendar=islamic", TEST_ULDN_LOCALE, u"Pashto (Arabic, Afghanistan, Islamic Calendar)" },
6755 { "ks_Arab@calendar=islamic", TEST_ULDN_LOCALE, u"Kashmiri (Naskh, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6756 { "ks_Aran@calendar=islamic", TEST_ULDN_LOCALE, u"Kashmiri (Nastaliq, Islamic Calendar)" }, // Apple <rdar://problem/47494884>
6757 { "ks_Arab_IN@calendar=islamic", TEST_ULDN_LOCALE, u"Kashmiri (Naskh, India, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6758 { "ks_Aran_IN@calendar=islamic", TEST_ULDN_LOCALE, u"Kashmiri (Nastaliq, India, Islamic Calendar)" }, // Apple <rdar://problem/47494884>
6759 { "pa_Arab@calendar=islamic", TEST_ULDN_LOCALE, u"Punjabi (Naskh, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6760 { "pa_Aran@calendar=islamic", TEST_ULDN_LOCALE, u"Punjabi (Nastaliq, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6761 { "pa_Arab_PK@calendar=islamic", TEST_ULDN_LOCALE, u"Punjabi (Naskh, Pakistan, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6762 { "pa_Aran_PK@calendar=islamic", TEST_ULDN_LOCALE, u"Punjabi (Nastaliq, Pakistan, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6763 { "ur_Arab@calendar=islamic", TEST_ULDN_LOCALE, u"Urdu (Naskh, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6764 { "ur_Aran@calendar=islamic", TEST_ULDN_LOCALE, u"Urdu (Nastaliq, Islamic Calendar)" }, // Apple <rdar://problem/47494884>
6765 { "ur_Arab_PK@calendar=islamic", TEST_ULDN_LOCALE, u"Urdu (Naskh, Pakistan, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6766 { "ur_Aran_PK@calendar=islamic", TEST_ULDN_LOCALE, u"Urdu (Nastaliq, Pakistan, Islamic Calendar)" }, // Apple <rdar://problem/47494884>
6767 { "Arab", TEST_ULDN_SCRIPT, u"Arabic" },
6768 { "Aran", TEST_ULDN_SCRIPT, u"Nastaliq" }, // Apple <rdar://problem/47494884>
6769 { "Qaag", TEST_ULDN_SCRIPT, u"Zawgyi" }, // Apple <rdar://problem/51471316>
6770 { "my_Qaag", TEST_ULDN_LOCALE, u"Burmese (Zawgyi)" }, // Apple <rdar://problem/51471316>
6771
6772 { "zh_Hans", TEST_ULOC_LOCALE, u"Chinese, Simplified" }, // Apple <rdar://problem/51418203>
6773 { "zh_Hans_CN", TEST_ULOC_LOCALE, u"Chinese, Simplified (China mainland)" }, // Apple <rdar://problem/51418203>
6774 { "zh_Hant", TEST_ULOC_LOCALE, u"Chinese, Traditional" }, // Apple <rdar://problem/51418203>
6775 { "zh_Hant_HK", TEST_ULOC_LOCALE, u"Chinese, Traditional (Hong Kong)" }, // Apple <rdar://problem/51418203>
6776 { "yue_Hans", TEST_ULOC_LOCALE, u"Cantonese, Simplified" }, // Apple <rdar://problem/51418203>
6777 { "yue_Hans_CN", TEST_ULOC_LOCALE, u"Cantonese, Simplified (China mainland)" }, // Apple <rdar://problem/51418203>
6778 { "yue_Hant", TEST_ULOC_LOCALE, u"Cantonese, Traditional" }, // Apple <rdar://problem/51418203>
6779 { "yue_Hant_HK", TEST_ULOC_LOCALE, u"Cantonese, Traditional (Hong Kong)" }, // Apple <rdar://problem/51418203>
6780 { "zh_Hans@calendar=chinese", TEST_ULOC_LOCALE, u"Chinese, Simplified (Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6781 { "zh_Hans_CN@calendar=chinese", TEST_ULOC_LOCALE, u"Chinese, Simplified (China mainland, Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6782 { "zh_Hant@calendar=chinese", TEST_ULOC_LOCALE, u"Chinese, Traditional (Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6783 { "zh_Hant_HK@calendar=chinese", TEST_ULOC_LOCALE, u"Chinese, Traditional (Hong Kong, Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6784 { "yue_Hans@calendar=chinese", TEST_ULOC_LOCALE, u"Cantonese, Simplified (Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6785 { "yue_Hans_CN@calendar=chinese", TEST_ULOC_LOCALE, u"Cantonese, Simplified (China mainland, Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6786 { "yue_Hant@calendar=chinese", TEST_ULOC_LOCALE, u"Cantonese, Traditional (Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6787 { "yue_Hant_HK@calendar=chinese", TEST_ULOC_LOCALE, u"Cantonese, Traditional (Hong Kong, Chinese Calendar)" }, // Apple <rdar://problem/50750364>
6788 { "ks_Arab", TEST_ULOC_LOCALE, u"Kashmiri (Naskh)" }, // Apple <rdar://problem/51418203>
6789 { "ks_Aran", TEST_ULOC_LOCALE, u"Kashmiri (Nastaliq)" }, // Apple <rdar://problem/47494884>
6790 { "ks_Arab_IN", TEST_ULOC_LOCALE, u"Kashmiri (Naskh, India)" }, // Apple <rdar://problem/51418203>
6791 { "ks_Aran_IN", TEST_ULOC_LOCALE, u"Kashmiri (Nastaliq, India)" }, // Apple <rdar://problem/47494884>
6792 { "pa_Arab", TEST_ULOC_LOCALE, u"Punjabi (Naskh)" }, // Apple <rdar://problem/51418203>
6793 { "pa_Aran", TEST_ULOC_LOCALE, u"Punjabi (Nastaliq)" }, // Apple <rdar://problem/51418203>
6794 { "pa_Arab_PK", TEST_ULOC_LOCALE, u"Punjabi (Naskh, Pakistan)" }, // Apple <rdar://problem/51418203>
6795 { "pa_Aran_PK", TEST_ULOC_LOCALE, u"Punjabi (Nastaliq, Pakistan)" }, // Apple <rdar://problem/51418203>
6796 { "ur_Arab", TEST_ULOC_LOCALE, u"Urdu (Naskh)" }, // Apple <rdar://problem/51418203>
6797 { "ur_Aran", TEST_ULOC_LOCALE, u"Urdu (Nastaliq)" }, // Apple <rdar://problem/47494884>
6798 { "ur_Arab_PK", TEST_ULOC_LOCALE, u"Urdu (Naskh, Pakistan)" }, // Apple <rdar://problem/51418203>
6799 { "ur_Aran_PK", TEST_ULOC_LOCALE, u"Urdu (Nastaliq, Pakistan)" }, // Apple <rdar://problem/47494884>
6800 { "ks_Arab@calendar=islamic", TEST_ULOC_LOCALE, u"Kashmiri (Naskh, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6801 { "ks_Aran@calendar=islamic", TEST_ULOC_LOCALE, u"Kashmiri (Nastaliq, Islamic Calendar)" }, // Apple <rdar://problem/47494884>
6802 { "ks_Arab_IN@calendar=islamic", TEST_ULOC_LOCALE, u"Kashmiri (Naskh, India, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6803 { "ks_Aran_IN@calendar=islamic", TEST_ULOC_LOCALE, u"Kashmiri (Nastaliq, India, Islamic Calendar)" }, // Apple <rdar://problem/47494884>
6804 { "pa_Arab@calendar=islamic", TEST_ULOC_LOCALE, u"Punjabi (Naskh, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6805 { "pa_Aran@calendar=islamic", TEST_ULOC_LOCALE, u"Punjabi (Nastaliq, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6806 { "pa_Arab_PK@calendar=islamic", TEST_ULOC_LOCALE, u"Punjabi (Naskh, Pakistan, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6807 { "pa_Aran_PK@calendar=islamic", TEST_ULOC_LOCALE, u"Punjabi (Nastaliq, Pakistan, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6808 { "ur_Arab@calendar=islamic", TEST_ULOC_LOCALE, u"Urdu (Naskh, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6809 { "ur_Aran@calendar=islamic", TEST_ULOC_LOCALE, u"Urdu (Nastaliq, Islamic Calendar)" }, // Apple <rdar://problem/47494884>
6810 { "ur_Arab_PK@calendar=islamic", TEST_ULOC_LOCALE, u"Urdu (Naskh, Pakistan, Islamic Calendar)" }, // Apple <rdar://problem/50687287>
6811 { "ur_Aran_PK@calendar=islamic", TEST_ULOC_LOCALE, u"Urdu (Nastaliq, Pakistan, Islamic Calendar)" }, // Apple <rdar://problem/47494884>
6812 { "my_Qaag", TEST_ULOC_LOCALE, u"Burmese (Zawgyi)" }, // Apple <rdar://problem/51471316>
2ca993e8
A
6813};
6814
6815static const UldnItem en_StdMidShrt[] = {
3d1f044b
A
6816 { "en_US", TEST_ULDN_LOCALE, u"English (US)" },
6817 { "en_US_POSIX", TEST_ULDN_LOCALE, u"English (US, Computer)" },
6818 { "en_US@calendar=chinese", TEST_ULDN_LOCALE, u"English (US, Calendar: chinese)" },
6819 { "en_CA", TEST_ULDN_LOCALE, u"English (Canada)" },
6820 { "pt", TEST_ULDN_LOCALE, u"Portuguese" },
6821 { "pt_BR", TEST_ULDN_LOCALE, u"Portuguese (Brazil)" },
6822 { "pt_PT", TEST_ULDN_LOCALE, u"Portuguese (Portugal)" },
6823 { "zh_Hans", TEST_ULDN_LOCALE, u"Chinese, Simplified" },
6824 { "zh_Hant_HK", TEST_ULDN_LOCALE, u"Chinese, Traditional (Hong Kong)" },
6825 { "zh_HK", TEST_ULDN_LOCALE, u"Chinese (Hong Kong)" },
6826 { "Latn", TEST_ULDN_SCRIPT, u"Latin" },
6827 { "Hans", TEST_ULDN_SCRIPT, u"Simplified Han" },
6828 { "Hant", TEST_ULDN_SCRIPT, u"Traditional Han" },
6829 { "US", TEST_ULDN_REGION, u"US" },
6830 { "CA", TEST_ULDN_REGION, u"Canada" },
6831 { "GB", TEST_ULDN_REGION, u"UK" },
6832 { "HK", TEST_ULDN_REGION, u"Hong Kong" },
2ca993e8
A
6833};
6834
6835static const UldnItem en_DiaMidLong[] = {
3d1f044b
A
6836 { "en_US", TEST_ULDN_LOCALE, u"American English" },
6837 { "en_US_POSIX", TEST_ULDN_LOCALE, u"American English (Computer)" },
6838 { "en_US@calendar=chinese", TEST_ULDN_LOCALE, u"American English (Chinese Calendar)" },
6839 { "en_CA", TEST_ULDN_LOCALE, u"Canadian English" },
6840 { "pt", TEST_ULDN_LOCALE, u"Portuguese" },
6841 { "pt_BR", TEST_ULDN_LOCALE, u"Brazilian Portuguese" },
6842 { "pt_PT", TEST_ULDN_LOCALE, u"European Portuguese" },
6843 { "zh_Hans", TEST_ULDN_LOCALE, u"Chinese, Simplified" },
6844 { "zh_Hant_HK", TEST_ULDN_LOCALE, u"Chinese, Traditional (Hong Kong)" },
6845 { "zh_HK", TEST_ULDN_LOCALE, u"Chinese (Hong Kong)" },
6846 { "Latn", TEST_ULDN_SCRIPT, u"Latin" },
6847 { "Hans", TEST_ULDN_SCRIPT, u"Simplified Han" },
6848 { "Hant", TEST_ULDN_SCRIPT, u"Traditional Han" },
6849 { "US", TEST_ULDN_REGION, u"United States" },
6850 { "CA", TEST_ULDN_REGION, u"Canada" },
6851 { "GB", TEST_ULDN_REGION, u"United Kingdom" },
6852 { "HK", TEST_ULDN_REGION, u"Hong Kong" },
2ca993e8
A
6853};
6854
6855static const UldnItem en_DiaMidShrt[] = {
3d1f044b
A
6856 { "en_US", TEST_ULDN_LOCALE, u"US English" },
6857 { "en_US_POSIX", TEST_ULDN_LOCALE, u"US English (Computer)" },
6858 { "en_US@calendar=chinese", TEST_ULDN_LOCALE, u"US English (Calendar: chinese)" },
6859 { "en_CA", TEST_ULDN_LOCALE, u"Canadian English" },
6860 { "pt", TEST_ULDN_LOCALE, u"Portuguese" },
6861 { "pt_BR", TEST_ULDN_LOCALE, u"Brazilian Portuguese" },
6862 { "pt_PT", TEST_ULDN_LOCALE, u"European Portuguese" },
6863 { "zh_Hans", TEST_ULDN_LOCALE, u"Chinese, Simplified" },
6864 { "zh_Hant_HK", TEST_ULDN_LOCALE, u"Chinese, Traditional (Hong Kong)" },
6865 { "zh_HK", TEST_ULDN_LOCALE, u"Chinese (Hong Kong)" },
6866 { "Latn", TEST_ULDN_SCRIPT, u"Latin" },
6867 { "Hans", TEST_ULDN_SCRIPT, u"Simplified Han" },
6868 { "Hant", TEST_ULDN_SCRIPT, u"Traditional Han" },
6869 { "US", TEST_ULDN_REGION, u"US" },
6870 { "CA", TEST_ULDN_REGION, u"Canada" },
6871 { "GB", TEST_ULDN_REGION, u"UK" },
6872 { "HK", TEST_ULDN_REGION, u"Hong Kong" },
2ca993e8
A
6873};
6874
6875static const UldnItem fr_StdMidLong[] = {
3d1f044b
A
6876 { "en_US", TEST_ULDN_LOCALE, u"anglais (É.-U.)" },
6877 { "US", TEST_ULDN_REGION, u"États-Unis" },
6878 { "HK", TEST_ULDN_REGION, u"Hong Kong" },
2ca993e8
A
6879};
6880
6881static const UldnItem fr_StdMidShrt[] = {
3d1f044b
A
6882 { "en_US", TEST_ULDN_LOCALE, u"anglais (É.-U.)" },
6883 { "US", TEST_ULDN_REGION, u"É.-U." },
6884 { "HK", TEST_ULDN_REGION, u"Hong Kong" },
2ca993e8
A
6885};
6886
6887static const UldnItem fr_StdBegLong[] = {
3d1f044b 6888 { "en_US", TEST_ULDN_LOCALE, u"Anglais (É.-U.)" },
2ca993e8
A
6889};
6890
6891static const UldnItem fr_StdLstLong[] = {
3d1f044b
A
6892 { "en_US", TEST_ULDN_LOCALE, u"Anglais (É.-U.)" },
6893 { "PS", TEST_ULDN_REGION, u"Territoires palestiniens" },
2ca993e8
A
6894};
6895
6896static const UldnItem fr_DiaMidLong[] = {
3d1f044b 6897 { "en_US", TEST_ULDN_LOCALE, u"anglais américain" },
2ca993e8
A
6898};
6899
f3c0d7a5 6900static const UldnItem ca_StdLstLong[] = {
3d1f044b
A
6901 { "PS", TEST_ULDN_REGION, u"Territoris palestins" },
6902};
6903
6904static const UldnItem ur_StdMidLong[] = {
6905 { "ps_Arab", TEST_ULDN_LOCALE, u"پشتو (عربی)" },
6906 { "ps_Arab_AF", TEST_ULDN_LOCALE, u"پشتو (عربی،افغانستان)" },
6907 { "ur_Aran", TEST_ULDN_LOCALE, u"اردو (نستعلیق)" }, // Apple <rdar://problem/47494884>
6908 { "ur_Arab", TEST_ULDN_LOCALE, u"اردو (نسخ)" }, // Apple <rdar://problem/50687287>
6909 { "ur_Aran_PK", TEST_ULDN_LOCALE, u"اردو (نستعلیق،پاکستان)" }, // Apple <rdar://problem/47494884>
6910 { "ur_Arab_PK", TEST_ULDN_LOCALE, u"اردو (نسخ،پاکستان)" }, // Apple <rdar://problem/50687287>
6911
6912 { "ps_Arab", TEST_ULOC_LOCALE, u"پشتو (عربی)" },
6913 { "ps_Arab_AF", TEST_ULOC_LOCALE, u"پشتو (عربی،افغانستان)" },
6914 { "ur_Aran", TEST_ULOC_LOCALE, u"اردو (نستعلیق)" }, // Apple <rdar://problem/47494884>
6915 { "ur_Arab", TEST_ULOC_LOCALE, u"اردو (نسخ)" }, // Apple <rdar://problem/51418203>
6916 { "ur_Aran_PK", TEST_ULOC_LOCALE, u"اردو (نستعلیق،پاکستان)" }, // Apple <rdar://problem/47494884>
6917 { "ur_Arab_PK", TEST_ULOC_LOCALE, u"اردو (نسخ،پاکستان)" }, // Apple <rdar://problem/51418203>
6918};
6919
6920static const UldnItem pa_Arab_StdMidLong[] = {
6921 { "pa_Aran", TEST_ULDN_LOCALE, u"پنجابی (نستعلیق)" }, // Apple <rdar://problem/47494884>
6922 { "pa_Arab", TEST_ULDN_LOCALE, u"پنجابی (نسخ)" }, // Apple <rdar://problem/50687287>
6923 { "pa_Aran_PK", TEST_ULDN_LOCALE, u"پنجابی (نستعلیق, پاکستان)" }, // Apple <rdar://problem/47494884>
6924 { "pa_Arab_PK", TEST_ULDN_LOCALE, u"پنجابی (نسخ, پاکستان)" }, // Apple <rdar://problem/50687287>
6925
6926 { "pa_Aran", TEST_ULOC_LOCALE, u"پنجابی (نستعلیق)" }, // Apple <rdar://problem/51418203>
6927 { "pa_Arab", TEST_ULOC_LOCALE, u"پنجابی (نسخ)" }, // Apple <rdar://problem/51418203>
6928 { "pa_Aran_PK", TEST_ULOC_LOCALE, u"پنجابی (نستعلیق, پاکستان)" }, // Apple <rdar://problem/51418203>
6929 { "pa_Arab_PK", TEST_ULOC_LOCALE, u"پنجابی (نسخ, پاکستان)" }, // Apple <rdar://problem/51418203>
6930};
6931
6932static const UldnItem zh_StdMidLong[] = {
6933 { "zh_Hans", TEST_ULDN_LOCALE, u"简体中文" }, // Apple <rdar://problem/50750364>
6934 { "zh_Hans_CN", TEST_ULDN_LOCALE, u"简体中文(中国大陆)" }, // Apple <rdar://problem/50750364>
6935 { "zh_Hant", TEST_ULDN_LOCALE, u"繁体中文" }, // Apple <rdar://problem/50750364>
6936 { "zh_Hant_HK", TEST_ULDN_LOCALE, u"繁体中文(香港)" }, // Apple <rdar://problem/50750364>
6937 { "yue_Hans", TEST_ULDN_LOCALE, u"简体粤语" }, // Apple <rdar://problem/50750364>
6938 { "yue_Hans_CN", TEST_ULDN_LOCALE, u"简体粤语(中国大陆)" }, // Apple <rdar://problem/50750364>
6939 { "yue_Hant", TEST_ULDN_LOCALE, u"繁体粤语" }, // Apple <rdar://problem/50750364>
6940 { "yue_Hant_HK", TEST_ULDN_LOCALE, u"繁体粤语(香港)" }, // Apple <rdar://problem/50750364>
6941 { "ps_Arab", TEST_ULDN_LOCALE, u"普什图语(阿拉伯文)" },
6942 { "ps_Arab_AF", TEST_ULDN_LOCALE, u"普什图语(阿拉伯文,阿富汗)" },
6943 { "ur_Aran", TEST_ULDN_LOCALE, u"乌尔都语(波斯体)" }, // Apple <rdar://problem/47494884>
6944 { "ur_Arab", TEST_ULDN_LOCALE, u"乌尔都语(誊抄体)" }, // Apple <rdar://problem/50687287>
6945 { "ur_Aran_PK", TEST_ULDN_LOCALE, u"乌尔都语(波斯体,巴基斯坦)" }, // Apple <rdar://problem/47494884>
6946 { "ur_Arab_PK", TEST_ULDN_LOCALE, u"乌尔都语(誊抄体,巴基斯坦)" }, // Apple <rdar://problem/50687287>
6947
6948 { "zh_Hans", TEST_ULOC_LOCALE, u"简体中文" }, // Apple <rdar://problem/51418203>
6949 { "zh_Hans_CN", TEST_ULOC_LOCALE, u"简体中文(中国大陆)" }, // Apple <rdar://problem/51418203>
6950 { "zh_Hant", TEST_ULOC_LOCALE, u"繁体中文" }, // Apple <rdar://problem/51418203>
6951 { "zh_Hant_HK", TEST_ULOC_LOCALE, u"繁体中文(香港)" }, // Apple <rdar://problem/51418203>
6952 { "yue_Hans", TEST_ULOC_LOCALE, u"简体粤语" }, // Apple <rdar://problem/51418203>
6953 { "yue_Hans_CN", TEST_ULOC_LOCALE, u"简体粤语(中国大陆)" }, // Apple <rdar://problem/51418203>
6954 { "yue_Hant", TEST_ULOC_LOCALE, u"繁体粤语" }, // Apple <rdar://problem/51418203>
6955 { "yue_Hant_HK", TEST_ULOC_LOCALE, u"繁体粤语(香港)" }, // Apple <rdar://problem/51418203>
6956 { "ur_Aran", TEST_ULOC_LOCALE, u"乌尔都语(波斯体)" }, // Apple <rdar://problem/47494884>
6957 { "ur_Arab", TEST_ULOC_LOCALE, u"乌尔都语(誊抄体)" }, // Apple <rdar://problem/51418203>
6958 { "ur_Aran_PK", TEST_ULOC_LOCALE, u"乌尔都语(波斯体,巴基斯坦)" }, // Apple <rdar://problem/47494884>
6959 { "ur_Arab_PK", TEST_ULOC_LOCALE, u"乌尔都语(誊抄体,巴基斯坦)" }, // Apple <rdar://problem/51418203>
6960};
6961
6962static const UldnItem hi_Latn_StdMidLong[] = { // Apple <rdar://problem/53216112>
6963 { "en", TEST_ULDN_LOCALE, u"English" },
6964 { "hi_Deva", TEST_ULDN_LOCALE, u"Hindi (Devanagari)" },
6965 { "hi_Latn", TEST_ULDN_LOCALE, u"Hindi (Latin)" },
6966 { "hi_Latn_IN", TEST_ULDN_LOCALE, u"Hindi (Latin, Bhaarat)" },
f3c0d7a5
A
6967};
6968
c5116b9f
A
6969static const UldnItem mni_Beng_StdMidLong[] = { // Apple <rdar://problem/54153189>
6970 { "mni_Beng", TEST_ULDN_LOCALE, u"মৈতৈলোন্ (বাংলা)" },
6971 { "mni_Mtei", TEST_ULDN_LOCALE, u"মৈতৈলোন্ (মেইটেই মায়েক)" },
6972};
6973
6974static const UldnItem mni_Mtei_StdMidLong[] = { // Apple <rdar://problem/54153189>
6975 { "mni_Beng", TEST_ULDN_LOCALE, u"ꯃꯤꯇꯩꯂꯣꯟ (ꯕꯪꯂꯥ)" },
6976 { "mni_Mtei", TEST_ULDN_LOCALE, u"ꯃꯤꯇꯩꯂꯣꯟ (ꯃꯤꯇꯩ ꯃꯌꯦꯛ)" },
6977};
6978
6979static const UldnItem sat_Olck_StdMidLong[] = { // Apple <rdar://problem/54153189>
6980 { "sat_Olck", TEST_ULDN_LOCALE, u"ᱥᱟᱱᱛᱟᱲᱤ (ᱚᱞ ᱪᱤᱠᱤ)" },
6981 { "sat_Deva", TEST_ULDN_LOCALE, u"ᱥᱟᱱᱛᱟᱲᱤ (ᱫᱮᱣᱟᱱᱟᱜᱟᱨᱤ)" },
6982};
6983
6984static const UldnItem sat_Deva_StdMidLong[] = { // Apple <rdar://problem/54153189>
6985 { "sat_Olck", TEST_ULDN_LOCALE, u"सानताड़ी (अल चीकी)" },
6986 { "sat_Deva", TEST_ULDN_LOCALE, u"सानताड़ी (देवानागारी)" },
6987};
6988
2ca993e8
A
6989static const UldnLocAndOpts uldnLocAndOpts[] = {
6990 { "en", optStdMidLong, en_StdMidLong, UPRV_LENGTHOF(en_StdMidLong) },
6991 { "en", optStdMidShrt, en_StdMidShrt, UPRV_LENGTHOF(en_StdMidShrt) },
6992 { "en", optDiaMidLong, en_DiaMidLong, UPRV_LENGTHOF(en_DiaMidLong) },
6993 { "en", optDiaMidShrt, en_DiaMidShrt, UPRV_LENGTHOF(en_DiaMidShrt) },
6994 { "fr", optStdMidLong, fr_StdMidLong, UPRV_LENGTHOF(fr_StdMidLong) },
6995 { "fr", optStdMidShrt, fr_StdMidShrt, UPRV_LENGTHOF(fr_StdMidShrt) },
6996 { "fr", optStdBegLong, fr_StdBegLong, UPRV_LENGTHOF(fr_StdBegLong) },
6997 { "fr", optStdLstLong, fr_StdLstLong, UPRV_LENGTHOF(fr_StdLstLong) },
f3c0d7a5 6998 { "fr_CA", optStdLstLong, fr_StdLstLong, UPRV_LENGTHOF(fr_StdLstLong) },
2ca993e8 6999 { "fr", optDiaMidLong, fr_DiaMidLong, UPRV_LENGTHOF(fr_DiaMidLong) },
f3c0d7a5 7000 { "ca", optStdLstLong, ca_StdLstLong, UPRV_LENGTHOF(ca_StdLstLong) },
3d1f044b
A
7001 { "ur", optStdMidLong, ur_StdMidLong, UPRV_LENGTHOF(ur_StdMidLong) },
7002 { "ur_Arab", optStdMidLong, ur_StdMidLong, UPRV_LENGTHOF(ur_StdMidLong) },
7003 { "ur_Aran", optStdMidLong, ur_StdMidLong, UPRV_LENGTHOF(ur_StdMidLong) },
7004 { "pa_Arab", optStdMidLong, pa_Arab_StdMidLong, UPRV_LENGTHOF(pa_Arab_StdMidLong) },
7005 { "pa_Aran", optStdMidLong, pa_Arab_StdMidLong, UPRV_LENGTHOF(pa_Arab_StdMidLong) },
7006 { "zh", optStdMidLong, zh_StdMidLong, UPRV_LENGTHOF(zh_StdMidLong) },
7007 { "hi_Latn", optStdMidLong, hi_Latn_StdMidLong, UPRV_LENGTHOF(hi_Latn_StdMidLong) },
c5116b9f
A
7008 { "mni_Beng", optStdMidLong, mni_Beng_StdMidLong, UPRV_LENGTHOF(mni_Beng_StdMidLong) },
7009 { "mni_Mtei", optStdMidLong, mni_Mtei_StdMidLong, UPRV_LENGTHOF(mni_Mtei_StdMidLong) },
7010 { "sat_Olck", optStdMidLong, sat_Olck_StdMidLong, UPRV_LENGTHOF(sat_Olck_StdMidLong) },
7011 { "sat_Deva", optStdMidLong, sat_Deva_StdMidLong, UPRV_LENGTHOF(sat_Deva_StdMidLong) },
2ca993e8
A
7012 { NULL, NULL, NULL, 0 }
7013};
7014
7015enum { kUNameBuf = 128, kBNameBuf = 256 };
7016
7017static void TestUldnNameVariants() {
7018 const UldnLocAndOpts * uloPtr;
7019 for (uloPtr = uldnLocAndOpts; uloPtr->displayLocale != NULL; uloPtr++) {
7020 UErrorCode status = U_ZERO_ERROR;
7021 ULocaleDisplayNames * uldn = uldn_openForContext(uloPtr->displayLocale, (UDisplayContext*)uloPtr->displayOptions, 3, &status);
7022 if (U_FAILURE(status)) {
7023 log_data_err("uldn_openForContext fails, displayLocale %s, contexts %03X %03X %03X: %s - Are you missing data?\n",
7024 uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
7025 u_errorName(status) );
7026 continue;
7027 }
7028 const UldnItem * itemPtr = uloPtr->testItems;
7029 int32_t itemCount = uloPtr->countItems;
7030 for (; itemCount-- > 0; itemPtr++) {
3d1f044b 7031 UChar uget[kUNameBuf];
2ca993e8
A
7032 int32_t ulenget, ulenexp;
7033 const char* typeString;
2ca993e8
A
7034 status = U_ZERO_ERROR;
7035 switch (itemPtr->nameType) {
7036 case TEST_ULDN_LOCALE:
7037 ulenget = uldn_localeDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
3d1f044b 7038 typeString = "uldn_localeDisplayName";
2ca993e8
A
7039 break;
7040 case TEST_ULDN_LANGUAGE:
7041 ulenget = uldn_languageDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
3d1f044b 7042 typeString = "uldn_languageDisplayName";
2ca993e8
A
7043 break;
7044 case TEST_ULDN_SCRIPT:
7045 ulenget = uldn_scriptDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
3d1f044b 7046 typeString = "uldn_scriptDisplayName";
2ca993e8
A
7047 break;
7048 case TEST_ULDN_REGION:
7049 ulenget = uldn_regionDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
3d1f044b
A
7050 typeString = "uldn_regionDisplayName";
7051 break;
7052 case TEST_ULOC_LOCALE:
7053 ulenget = uloc_getDisplayName(itemPtr->localeToName, uloPtr->displayLocale, uget, kUNameBuf, &status);
7054 typeString = "uloc_getDisplayName";
7055 break;
7056 case TEST_ULOC_LANGUAGE:
7057 ulenget = uloc_getDisplayLanguage(itemPtr->localeToName, uloPtr->displayLocale, uget, kUNameBuf, &status);
7058 typeString = "uloc_getDisplayLanguage";
7059 break;
7060 case TEST_ULOC_SCRIPT:
7061 ulenget = uloc_getDisplayScript(itemPtr->localeToName, uloPtr->displayLocale, uget, kUNameBuf, &status);
7062 typeString = "uloc_getDisplayScript";
7063 break;
7064 case TEST_ULOC_REGION:
7065 ulenget = uloc_getDisplayCountry(itemPtr->localeToName, uloPtr->displayLocale, uget, kUNameBuf, &status);
7066 typeString = "uloc_getDisplayCountry";
2ca993e8
A
7067 break;
7068 default:
7069 continue;
7070 }
7071 if (U_FAILURE(status)) {
3d1f044b 7072 log_data_err("%s fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s: %s\n",
2ca993e8
A
7073 typeString, uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
7074 itemPtr->localeToName, u_errorName(status) );
7075 continue;
7076 }
3d1f044b
A
7077 ulenexp = u_strlen(itemPtr->expectResult);
7078 if (ulenget != ulenexp || u_strncmp(uget, itemPtr->expectResult, ulenexp) != 0) {
2ca993e8 7079 char bexp[kBNameBuf], bget[kBNameBuf];
3d1f044b 7080 u_strToUTF8(bexp, kBNameBuf, NULL, itemPtr->expectResult, ulenexp, &status);
2ca993e8 7081 u_strToUTF8(bget, kBNameBuf, NULL, uget, ulenget, &status);
3d1f044b 7082 log_data_err("%s fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s:\n expect %2d: %s\n get %2d: %s\n",
2ca993e8
A
7083 typeString, uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
7084 itemPtr->localeToName, ulenexp, bexp, ulenget, bget );
7085 }
7086 }
7087
7088 uldn_close(uldn);
7089 }
7090}
7091
3d1f044b
A
7092#define ULOC_UND_TESTNUM 9
7093
7094static const char* for_empty[ULOC_UND_TESTNUM] = { // ""
7095 "", // uloc_getName
7096 "", // uloc_getLanguage
7097 "en_Latn_US_POSIX", // uloc_addLikelySubtags
7098 "en__POSIX", // uloc_minimizeSubtags
7099 "en_US_POSIX", // uloc_canonicalize
7100 "", // uloc_getParent
7101 "und", // uloc_toLanguageTag
7102 "", // uloc_getDisplayName in en
7103 "", // uloc_getDisplayLanguage in en
7104};
7105static const char* for_root[ULOC_UND_TESTNUM] = { // "root"
7106 "root", // uloc_getName
7107 "root", // uloc_getLanguage
7108 "root", // uloc_addLikelySubtags
7109 "root", // uloc_minimizeSubtags
7110 "root", // uloc_canonicalize
7111 "", // uloc_getParent
7112 "root", // uloc_toLanguageTag
7113 "Root", // uloc_getDisplayName in en
7114 "Root", // uloc_getDisplayLanguage in en
7115};
7116static const char* for_und[ULOC_UND_TESTNUM] = { // "und"
7117 "und", // uloc_getName
7118 "und", // uloc_getLanguage
7119 "en_Latn_US", // uloc_addLikelySubtags
7120 "und", // uloc_minimizeSubtags
7121 "und", // uloc_canonicalize
7122 "", // uloc_getParent
7123 "und", // uloc_toLanguageTag
7124 "Unknown language", // uloc_getDisplayName in en
7125 "Unknown language", // uloc_getDisplayLanguage in en
7126};
7127static const char* for_und_ZZ[ULOC_UND_TESTNUM] = { // "und_ZZ"
7128 "und_ZZ", // uloc_getName
7129 "und", // uloc_getLanguage
7130 "en_Latn_US", // uloc_addLikelySubtags
7131 "und", // uloc_minimizeSubtags
7132 "und_ZZ", // uloc_canonicalize
7133 "und", // uloc_getParent
7134 "und-ZZ", // uloc_toLanguageTag
7135 "Unknown language (Unknown Region)", // uloc_getDisplayName in en
7136 "Unknown language", // uloc_getDisplayLanguage in en
7137};
7138static const char* for_empty_ZZ[ULOC_UND_TESTNUM] = { // "_ZZ"
7139 "_ZZ", // uloc_getName
7140 "", // uloc_getLanguage
7141 "en_Latn_US", // uloc_addLikelySubtags
7142 "und", // uloc_minimizeSubtags
7143 "_ZZ", // uloc_canonicalize
7144 "", // uloc_getParent
7145 "und-ZZ", // uloc_toLanguageTag
7146 "Unknown Region", // uloc_getDisplayName in en
7147 "", // uloc_getDisplayLanguage in en
7148};
7149
7150typedef struct {
7151 const char * locale;
7152 const char ** expResults;
7153} RootUndEmptyItem;
7154
7155static const RootUndEmptyItem rootUndEmptryItems[] = {
7156 { "", for_empty },
7157 { "root", for_root },
7158 { "und", for_und },
7159 { "und_ZZ", for_und_ZZ },
7160 { "_ZZ", for_empty_ZZ },
7161 { NULL, NULL }
7162};
7163
7164enum { kULocMax = 64, kBLocMax = 128 };
7165
7166static void TestRootUndEmpty() {
7167 const RootUndEmptyItem* itemPtr;
7168 for (itemPtr = rootUndEmptryItems; itemPtr->locale != NULL; itemPtr++) {
7169 const char* loc = itemPtr->locale;
7170 const char** expResultsPtr = itemPtr->expResults;
7171 const char* bexp;
7172 char bget[kBLocMax];
7173 UChar uexp[kULocMax];
7174 UChar uget[kULocMax];
7175 int32_t ulen, blen;
7176 UErrorCode status;
7177
7178 status = U_ZERO_ERROR;
7179 bexp = *expResultsPtr++;
7180 blen = uloc_getName(loc, bget, kBLocMax, &status);
7181 if (U_FAILURE(status)) {
7182 log_err("loc \"%s\", uloc_getName status: %s\n", loc, u_errorName(status) );
7183 } else if (uprv_strcmp(bget, bexp) != 0) {
7184 log_err("loc \"%s\", uloc_getName expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7185 }
7186
7187 status = U_ZERO_ERROR;
7188 bexp = *expResultsPtr++;
7189 blen = uloc_getLanguage(loc, bget, kBLocMax, &status);
7190 if (U_FAILURE(status)) {
7191 log_err("loc \"%s\", uloc_getLanguage status: %s\n", loc, u_errorName(status) );
7192 } else if (uprv_strcmp(bget, bexp) != 0) {
7193 log_err("loc \"%s\", uloc_getLanguage expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7194 }
7195
7196 status = U_ZERO_ERROR;
7197 bexp = *expResultsPtr++;
7198 blen = uloc_addLikelySubtags(loc, bget, kBLocMax, &status);
7199 if (U_FAILURE(status)) {
7200 log_err("loc \"%s\", uloc_addLikelySubtags status: %s\n", loc, u_errorName(status) );
7201 } else if (uprv_strcmp(bget, bexp) != 0) {
7202 log_err("loc \"%s\", uloc_addLikelySubtags expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7203 }
7204
7205 status = U_ZERO_ERROR;
7206 bexp = *expResultsPtr++;
7207 blen = uloc_minimizeSubtags(loc, bget, kBLocMax, &status);
7208 if (U_FAILURE(status)) {
7209 log_err("loc \"%s\", uloc_minimizeSubtags status: %s\n", loc, u_errorName(status) );
7210 } else if (uprv_strcmp(bget, bexp) != 0) {
7211 log_err("loc \"%s\", uloc_minimizeSubtags expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7212 }
7213
7214 status = U_ZERO_ERROR;
7215 bexp = *expResultsPtr++;
7216 blen = uloc_canonicalize(loc, bget, kBLocMax, &status);
7217 if (U_FAILURE(status)) {
7218 log_err("loc \"%s\", uloc_canonicalize status: %s\n", loc, u_errorName(status) );
7219 } else if (uprv_strcmp(bget, bexp) != 0) {
7220 log_err("loc \"%s\", uloc_canonicalize expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7221 }
7222
7223 status = U_ZERO_ERROR;
7224 bexp = *expResultsPtr++;
7225 blen = uloc_getParent(loc, bget, kBLocMax, &status);
7226 if (U_FAILURE(status)) {
7227 log_err("loc \"%s\", uloc_getParent status: %s\n", loc, u_errorName(status) );
7228 } else if (uprv_strcmp(bget, bexp) != 0) {
7229 log_err("loc \"%s\", uloc_getParent expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7230 }
7231
7232 status = U_ZERO_ERROR;
7233 bexp = *expResultsPtr++;
7234 blen = uloc_toLanguageTag(loc, bget, kBLocMax, TRUE, &status);
7235 if (U_FAILURE(status)) {
7236 log_err("loc \"%s\", uloc_toLanguageTag status: %s\n", loc, u_errorName(status) );
7237 } else if (uprv_strcmp(bget, bexp) != 0) {
7238 log_err("loc \"%s\", uloc_toLanguageTag expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7239 }
7240
7241 status = U_ZERO_ERROR;
7242 bexp = *expResultsPtr++;
7243 u_unescape(bexp, uexp, kULocMax);
7244 uexp[kULocMax-1] = 0; // force zero term
7245 ulen = uloc_getDisplayName(loc, "en", uget, kULocMax, &status);
7246 if (U_FAILURE(status)) {
7247 log_err("loc \"%s\", uloc_getDisplayName en status: %s\n", loc, u_errorName(status) );
7248 } else if (u_strcmp(uget, uexp) != 0) {
7249 u_austrncpy(bget, uget, kBLocMax);
7250 bget[kBLocMax-1] = 0;
7251 log_err("loc \"%s\", uloc_getDisplayName en expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7252 }
7253
7254 status = U_ZERO_ERROR;
7255 bexp = *expResultsPtr++;
7256 u_unescape(bexp, uexp, kULocMax);
7257 uexp[kULocMax-1] = 0; // force zero term
7258 ulen = uloc_getDisplayLanguage(loc, "en", uget, kULocMax, &status);
7259 if (U_FAILURE(status)) {
7260 log_err("loc \"%s\", uloc_getDisplayLanguage en status: %s\n", loc, u_errorName(status) );
7261 } else if (u_strcmp(uget, uexp) != 0) {
7262 u_austrncpy(bget, uget, kBLocMax);
7263 bget[kBLocMax-1] = 0;
7264 log_err("loc \"%s\", uloc_getDisplayLanguage en expect \"%s\", get \"%s\"\n", loc, bexp, bget );
7265 }
7266 }
7267}
7268
7269
4f1e1a09 7270#if !U_PLATFORM_HAS_WIN32_API
08b89b0a
A
7271/* Apple-specific, test for Apple-specific function ualoc_getAppleParent */
7272static const char* localesAndAppleParent[] = {
7273 "en", "root",
7274 "en-US", "en",
b331163b 7275 "en-CA", "en_001",
9f1b1155
A
7276 "en-CN", "en",
7277 "en-JP", "en",
7278 "en-TW", "en",
08b89b0a
A
7279 "en-001", "en",
7280 "en_001", "en",
a961784b 7281 "en-150", "en_GB",
08b89b0a
A
7282 "en-GB", "en_001",
7283 "en_GB", "en_001",
08b89b0a 7284 "en-AU", "en_GB",
a961784b
A
7285 "en-BE", "en_150",
7286 "en-DG", "en_GB",
7287 "en-FK", "en_GB",
7288 "en-GG", "en_GB",
7289 "en-GI", "en_GB",
b331163b 7290 "en-HK", "en_GB",
a961784b
A
7291 "en-IE", "en_GB",
7292 "en-IM", "en_GB",
b331163b 7293 "en-IN", "en_GB",
a961784b
A
7294 "en-IO", "en_GB",
7295 "en-JE", "en_GB",
a62d09fc 7296 "en-JM", "en_GB",
a961784b
A
7297 "en-MO", "en_GB",
7298 "en-MT", "en_GB",
2ca993e8
A
7299 "en-MV", "en_GB",
7300 "en-NZ", "en_AU",
b331163b 7301 "en-PK", "en_GB",
a961784b
A
7302 "en-SG", "en_GB",
7303 "en-SH", "en_GB",
7304 "en-VG", "en_GB",
08b89b0a
A
7305 "es", "root",
7306 "es-ES", "es",
7307 "es-419", "es",
7308 "es_419", "es",
7309 "es-MX", "es_419",
7310 "es-AR", "es_419",
2ca993e8 7311 "es-BR", "es_419",
a62d09fc 7312 "es-BZ", "es_419",
f3c0d7a5
A
7313 "es-AG", "es_419",
7314 "es-AW", "es_419",
9f1b1155 7315 "es-CA", "es_419",
f3c0d7a5
A
7316 "es-CW", "es_419",
7317 "es-SX", "es_419",
7318 "es-TT", "es_419",
08b89b0a
A
7319 "fr", "root",
7320 "fr-CA", "fr",
7321 "fr-CH", "fr",
7322 "haw", "root",
7323 "nl", "root",
7324 "nl-BE", "nl",
7325 "pt", "root",
7326 "pt-BR", "pt",
7327 "pt-PT", "pt",
7328 "pt-MO", "pt_PT",
2ca993e8
A
7329 "pt-CH", "pt_PT",
7330 "pt-GQ", "pt_PT",
7331 "pt-LU", "pt_PT",
08b89b0a
A
7332 "sr", "root",
7333 "sr-Cyrl", "sr",
7334 "sr-Latn", "root",
7335 "tlh", "root",
7336 "zh_CN", "root",
7337 "zh-CN", "root",
7338 "zh", "zh_CN",
7339 "zh-Hans", "zh",
7340 "zh_TW", "root",
7341 "zh-TW", "root",
7342 "zh-Hant", "zh_TW",
b331163b
A
7343 "zh_HK", "zh_Hant_HK",
7344 "zh-HK", "zh_Hant_HK",
08b89b0a
A
7345 "zh_Hant", "zh_TW",
7346 "zh-Hant-HK", "zh_Hant",
7347 "zh_Hant_HK", "zh_Hant",
7348 "zh-Hant-MO", "zh_Hant_HK",
7349 "zh-Hans-HK", "zh_Hans",
7350 "root", "root",
7351 "en-Latn", "en",
7352 "en-Latn-US", "en_Latn",
7353 "en_US_POSIX", "en_US",
7354 "en_Latn_US_POSIX", "en_Latn_US",
7355 "en-u-ca-hebrew", "root",
7356 "en@calendar=hebrew", "root",
7357 "en_@calendar=hebrew", "root",
7358 "en-", "root",
7359 "en_", "root",
7360 "Default@2x", "root",
7361 "default", "root",
7362 NULL /* terminator */
7363};
7364
7365static void TestGetAppleParent() {
7366 const char **localesPtr = localesAndAppleParent;
7367 const char * locale;
7368 while ((locale = *localesPtr++) != NULL) {
7369 const char * expectParent = *localesPtr++;
7370 UErrorCode status = U_ZERO_ERROR;
7371 char getParent[ULOC_FULLNAME_CAPACITY];
7372 int32_t plen = ualoc_getAppleParent(locale, getParent, ULOC_FULLNAME_CAPACITY, &status);
7373 if (U_FAILURE(status)) {
7374 log_err("FAIL: ualoc_getAppleParent input \"%s\", status %s\n", locale, u_errorName(status));
7375 } else if (uprv_strcmp(expectParent, getParent) != 0) {
7376 log_err("FAIL: ualoc_getAppleParent input \"%s\", expected parent \"%s\", got parent \"%s\"\n", locale, expectParent, getParent);
7377 }
7378 }
7379}
b331163b
A
7380
7381/* Apple-specific, test for Apple-specific function ualoc_getLanguagesForRegion */
7382enum { kUALanguageEntryMax = 10 };
7383
7384static void TestGetLanguagesForRegion() {
7385 UALanguageEntry entries[kUALanguageEntryMax];
7386 int32_t entryCount;
7387 UErrorCode status;
7388 const char * region;
7389
7390 status = U_ZERO_ERROR;
7391 region = "CN";
7392 entryCount = ualoc_getLanguagesForRegion(region, 0.001, entries, kUALanguageEntryMax, &status);
7393 if (U_FAILURE(status)) {
7394 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
7395 } else {
7396 // Expect approximately:
7397 // zh_Hans 0.90 UALANGSTATUS_OFFICIAL
7398 // wuu 0.06 Wu
7399 // hsn 0.06 Xiang
2ca993e8 7400 // yue 0.043 Yue including Cantonese
b331163b
A
7401 // hak 0.023 Hakka
7402 // nan 0.019 Minnan
7403 // gan 0.017 Gan
7404 // ii 0.006 Yi
7405 // ug_Arab 0.0055 Uighur UALANGSTATUS_REGIONAL_OFFICIAL
7406 // ...at least 4 more with fractions >= 0.001
7407 if (entryCount < kUALanguageEntryMax) {
7408 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
7409 } else {
7410 UALanguageEntry* entryPtr = entries;
7411 if (uprv_strcmp(entryPtr->languageCode, "zh_Hans") != 0 || entryPtr->userFraction < 0.8 || entryPtr->userFraction > 1.0 || entryPtr->status != UALANGSTATUS_OFFICIAL) {
7412 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region, entryPtr->languageCode, entryPtr->userFraction, (int)entryPtr->status);
7413 }
7414 for (entryPtr++; entryPtr < entries + kUALanguageEntryMax && uprv_strcmp(entryPtr->languageCode, "ug_Arab") != 0; entryPtr++)
7415 ;
7416 if (entryPtr < entries + kUALanguageEntryMax) {
7417 // we found ug_Arab, make sure it has correct status
7418 if (entryPtr->status != UALANGSTATUS_REGIONAL_OFFICIAL) {
7419 log_err("FAIL: ualoc_getLanguagesForRegion %s, ug_Arab had incorrect status %d\n", (int)entryPtr->status);
7420 }
7421 } else {
7422 // did not find ug_Arab
7423 log_err("FAIL: ualoc_getLanguagesForRegion %s, entries did not include ug_Arab\n", region);
7424 }
7425 }
7426 }
7427
7428 status = U_ZERO_ERROR;
7429 region = "CA";
7430 entryCount = ualoc_getLanguagesForRegion(region, 0.001, entries, kUALanguageEntryMax, &status);
7431 if (U_FAILURE(status)) {
7432 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
7433 } else {
7434 // Expect approximately:
7435 // en 0.85 UALANGSTATUS_OFFICIAL
7436 // fr 0.22 UALANGSTATUS_OFFICIAL
7437 // ...
7438 if (entryCount < 2) {
7439 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
7440 } else {
7441 if (uprv_strcmp(entries[0].languageCode, "en") != 0 || entries[0].userFraction < 0.7 || entries[0].userFraction > 1.0 || entries[0].status != UALANGSTATUS_OFFICIAL) {
7442 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region, entries[0].languageCode, entries[0].userFraction, (int)entries[0].status);
7443 }
7444 if (uprv_strcmp(entries[1].languageCode, "fr") != 0 || entries[1].userFraction < 0.1 || entries[1].userFraction > 1.0 || entries[1].status != UALANGSTATUS_OFFICIAL) {
7445 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[1] { %s, %.3f, %d }\n", region, entries[1].languageCode, entries[1].userFraction, (int)entries[1].status);
7446 }
7447 }
7448 }
7449
7450 status = U_ZERO_ERROR;
7451 region = "IN";
7452 entryCount = ualoc_getLanguagesForRegion(region, 0.001, NULL, 0, &status);
7453 if (U_FAILURE(status)) {
7454 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
7455 } else {
7456 if (entryCount < 40) {
7457 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
7458 }
7459 }
3d1f044b
A
7460
7461 status = U_ZERO_ERROR;
7462 region = "FO";
7463 entryCount = ualoc_getLanguagesForRegion(region, 0.001, entries, kUALanguageEntryMax, &status);
7464 if (U_FAILURE(status)) {
7465 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
7466 } else {
7467 // Expect approximately:
7468 // fo 0.93 UALANGSTATUS_OFFICIAL
7469 // da 0.03 UALANGSTATUS_OFFICIAL
7470 // ...
7471 if (entryCount < 2) {
7472 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
7473 } else {
7474 if (uprv_strcmp(entries[0].languageCode, "fo") != 0 || entries[0].userFraction < 0.90 || entries[0].userFraction > 0.98 || entries[0].status != UALANGSTATUS_OFFICIAL) {
7475 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region, entries[0].languageCode, entries[0].userFraction, (int)entries[0].status);
7476 }
7477 if (uprv_strcmp(entries[1].languageCode, "da") != 0 || entries[1].userFraction < 0.02 || entries[1].userFraction > 0.04 || entries[1].status != UALANGSTATUS_OFFICIAL) {
7478 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[1] { %s, %.3f, %d }\n", region, entries[1].languageCode, entries[1].userFraction, (int)entries[1].status);
7479 }
7480 }
7481 }
b331163b
A
7482}
7483
7484/* data for TestAppleLocalizationsToUse */
7485
7486typedef struct {
7487 const char * const *locs;
7488 int32_t locCount;
7489} AppleLocsAndCount;
7490
7491enum { kNumLocSets = 6 };
7492
7493typedef struct {
7494 const char * language;
7495 const char ** expLocsForSets[kNumLocSets];
7496} LangAndExpLocs;
7497
7498
7499static const char * appleLocs1[] = {
7500 "Arabic",
7501 "Danish",
7502 "Dutch",
7503 "English",
7504 "Finnish",
7505 "French",
7506 "German",
7507 "Italian",
7508 "Japanese",
7509 "Korean",
7510 "Norwegian",
7511 "Polish",
7512 "Portuguese",
7513 "Russian",
7514 "Spanish",
7515 "Swedish",
7516 "Thai",
7517 "Turkish",
7518 "ca",
7519 "cs",
7520 "el",
7521 "he",
7522 "hr",
7523 "hu",
7524 "id",
7525 "ms",
7526 "ro",
7527 "sk",
7528 "uk",
7529 "vi",
7530 "zh_CN", "zh_TW",
7531};
7532
7533static const char * appleLocs2[] = {
7534 "ar",
7535 "ca",
7536 "cs",
7537 "da",
7538 "de",
7539 "el",
7540 "en", "en_AU", "en_GB",
7541 "es", "es_MX",
7542 "fi",
7543 "fr", "fr_CA",
7544 "he",
7545 "hr",
7546 "hu",
7547 "id",
7548 "it",
7549 "ja",
7550 "ko",
7551 "ms",
7552 "nl",
7553 "no",
7554 "pl",
7555 "pt", "pt_PT",
7556 "ro",
7557 "ru",
7558 "sk",
7559 "sv",
7560 "th",
7561 "tr",
7562 "uk",
7563 "vi",
7564 "zh_CN", "zh_HK", "zh_TW",
7565};
7566
7567static const char * appleLocs3[] = {
7568 "ar",
7569 "ca",
7570 "cs",
7571 "da",
7572 "de",
7573 "el",
7574 "en", "en_AU", "en_CA", "en_GB",
7575 "es", "es_419",
7576 "fi",
7577 "fr", "fr_CA", "fr_FR",
7578 "he",
7579 "hr",
7580 "hu",
7581 "id",
3d1f044b 7582 "it", "it_CH", // <rdar://problem/35829322>
b331163b
A
7583 "ja",
7584 "ko",
7585 "ms",
7586 "nb",
7587 "nl",
7588 "pl",
7589 "pt", "pt_BR", "pt_PT",
7590 "ro",
7591 "ru",
7592 "sk",
7593 "sv",
7594 "th",
7595 "tr",
7596 "uk",
7597 "vi",
7598 "zh_CN", "zh_HK", "zh_MO", "zh_TW",
7599};
7600
7601static const char * appleLocs4[] = {
7602 "en", "en_AU", "en_CA", "en_GB", "en_IN", "en_US",
7603 "es", "es_419", "es_MX",
7604 "fr", "fr_CA", "fr_CH", "fr_FR",
3d1f044b 7605 "it", "it_CH", "it_IT", // <rdar://problem/35829322>
b331163b
A
7606 "nl", "nl_BE", "nl_NL",
7607 "pt", "pt_BR",
7608 "ro", "ro_MD", "ro_RO",
7609 "zh_Hans", "zh_Hant", "zh_Hant_HK",
7610};
7611
7612static const char * appleLocs5[] = {
7613 "en", "en_001", "en_AU", "en_GB",
7614 "es", "es_ES", "es_MX",
7615 "zh_CN", "zh_Hans", "zh_Hant", "zh_TW",
7616 "yi",
7617 "fil",
7618 "haw",
7619 "tlh",
7620 "sr",
7621 "sr-Latn",
7622};
7623
7624// list 6
7625static const char * appleLocs6[] = {
7626 "en", "en_001", "en_150", "en_AU", "en_GB",
7627 "es", "es_419", "es_ES", "es_MX",
7628 "zh_CN", "zh_Hans", "zh_Hant", "zh_Hant_HK", "zh_HK", "zh_TW",
7629 "iw",
7630 "in",
7631 "mo",
7632 "tl",
7633};
7634
7635static const AppleLocsAndCount locAndCountEntries[kNumLocSets] = {
7636 { appleLocs1, UPRV_LENGTHOF(appleLocs1) },
7637 { appleLocs2, UPRV_LENGTHOF(appleLocs2) },
7638 { appleLocs3, UPRV_LENGTHOF(appleLocs3) },
7639 { appleLocs4, UPRV_LENGTHOF(appleLocs4) },
7640 { appleLocs5, UPRV_LENGTHOF(appleLocs5) },
7641 { appleLocs6, UPRV_LENGTHOF(appleLocs6) },
7642};
7643
7644
7645static const char* l1_ar[] = { "ar", NULL };
7646static const char* l1_Ara[] = { "Arabic", NULL };
7647static const char* l1_ca[] = { "ca", NULL };
7648static const char* l1_cs[] = { "cs", NULL };
7649static const char* l1_da[] = { "da", NULL };
7650static const char* l1_Dan[] = { "Danish", NULL };
7651static const char* l1_de[] = { "de", NULL };
7652static const char* l1_Ger[] = { "German", NULL };
7653static const char* l1_el[] = { "el", NULL };
7654static const char* l1_en[] = { "en", NULL };
7655static const char* l1_Eng[] = { "English", NULL };
7656static const char* l2_en_001_[] = { "en_001", "en", NULL };
7657static const char* l2_en_CA_[] = { "en_CA", "en", NULL };
7658static const char* l2_en_GB_[] = { "en_GB", "en", NULL };
7659static const char* l2_en_US_[] = { "en_US", "en", NULL };
7660static const char* l2_en_GB_Eng[] = { "en_GB", "English", NULL };
7661static const char* l3_en_GB001_[] = { "en_GB", "en_001", "en", NULL };
7662static const char* l3_en_AUGB_[] = { "en_AU", "en_GB", "en", NULL };
7663static const char* l3_en_INGB_[] = { "en_IN", "en_GB", "en", NULL };
7664static const char* l4_en_150GB001_[] = { "en_150", "en_GB", "en_001", "en", NULL };
7665static const char* l4_en_AUGB001_[] = { "en_AU", "en_GB", "en_001", "en", NULL };
7666static const char* l1_es[] = { "es", NULL };
7667static const char* l1_Spa[] = { "Spanish", NULL };
7668static const char* l2_es_419_[] = { "es_419", "es", NULL };
7669static const char* l2_es_ES_[] = { "es_ES", "es", NULL };
7670static const char* l2_es_MX_[] = { "es_MX", "es", NULL };
7671static const char* l2_es_MX_Spa[] = { "es_MX", "Spanish", NULL };
7672static const char* l3_es_MX419_[] = { "es_MX", "es_419", "es", NULL };
7673static const char* l1_fi[] = { "fi", NULL };
7674static const char* l1_Fin[] = { "Finnish", NULL };
7675static const char* l1_fil[] = { "fil", NULL };
7676static const char* l1_tl[] = { "tl", NULL };
7677static const char* l1_fr[] = { "fr", NULL };
7678static const char* l1_Fre[] = { "French", NULL };
7679static const char* l2_fr_CA_[] = { "fr_CA", "fr", NULL };
7680static const char* l2_fr_CH_[] = { "fr_CH", "fr", NULL };
7681static const char* l2_fr_FR_[] = { "fr_FR", "fr", NULL };
7682static const char* l1_haw[] = { "haw", NULL };
7683static const char* l1_he[] = { "he", NULL };
7684static const char* l1_hr[] = { "hr", NULL };
7685static const char* l1_hu[] = { "hu", NULL };
7686static const char* l1_id[] = { "id", NULL };
7687static const char* l1_in[] = { "in", NULL };
7688static const char* l1_it[] = { "it", NULL };
3d1f044b
A
7689static const char* l2_it_CH[] = { "it_CH", "it", NULL }; // <rdar://problem/35829322>
7690static const char* l2_it_IT[] = { "it_IT", "it", NULL }; // <rdar://problem/35829322>
b331163b
A
7691static const char* l1_Ita[] = { "Italian", NULL };
7692static const char* l1_ja[] = { "ja", NULL };
7693static const char* l1_Japn[] = { "Japanese", NULL };
7694static const char* l1_ko[] = { "ko", NULL };
7695static const char* l1_Kor[] = { "Korean", NULL };
7696static const char* l1_ms[] = { "ms", NULL };
7697static const char* l1_nb[] = { "nb", NULL };
7698static const char* l1_no[] = { "no", NULL };
7699static const char* l1_Nor[] = { "Norwegian", NULL };
a961784b 7700static const char* l2_no_NO_[] = { "no_NO", "no", NULL };
b331163b
A
7701static const char* l1_nl[] = { "nl", NULL };
7702static const char* l1_Dut[] = { "Dutch", NULL };
7703static const char* l2_nl_BE_[] = { "nl_BE", "nl", NULL };
7704static const char* l1_pl[] = { "pl", NULL };
7705static const char* l1_Pol[] = { "Polish", NULL };
7706static const char* l1_pt[] = { "pt", NULL };
7707static const char* l1_pt_PT[] = { "pt_PT", NULL };
7708static const char* l1_Port[] = { "Portuguese", NULL };
7709static const char* l2_pt_BR_[] = { "pt_BR", "pt", NULL };
7710static const char* l2_pt_PT_[] = { "pt_PT", "pt", NULL };
7711static const char* l1_ro[] = { "ro", NULL };
7712static const char* l2_ro_MD_[] = { "ro_MD", "ro", NULL };
7713static const char* l1_mo[] = { "mo", NULL };
7714static const char* l1_ru[] = { "ru", NULL };
7715static const char* l1_Rus[] = { "Russian", NULL };
7716static const char* l1_sk[] = { "sk", NULL };
7717static const char* l1_sr[] = { "sr", NULL };
7718static const char* l1_srLatn[] = { "sr-Latn", NULL };
7719static const char* l1_sv[] = { "sv", NULL };
7720static const char* l1_Swe[] = { "Swedish", NULL };
7721static const char* l1_th[] = { "th", NULL };
7722static const char* l1_Thai[] = { "Thai", NULL };
7723static const char* l1_tlh[] = { "tlh", NULL };
7724static const char* l1_tr[] = { "tr", NULL };
7725static const char* l1_Tur[] = { "Turkish", NULL };
7726static const char* l1_uk[] = { "uk", NULL };
7727static const char* l1_vi[] = { "vi", NULL };
7728static const char* l1_yi[] = { "yi", NULL };
7729static const char* l1_iw[] = { "iw", NULL };
7730static const char* l1_zh_CN[] = { "zh_CN", NULL };
7731static const char* l1_zh_TW[] = { "zh_TW", NULL };
7732static const char* l1_zh_Hans[] = { "zh_Hans", NULL };
7733static const char* l1_zh_Hant[] = { "zh_Hant", NULL };
7734static const char* l1_zhHant[] = { "zh-Hant", NULL };
7735static const char* l2_zh_HKTW[] = { "zh_HK", "zh_TW", NULL };
7736static const char* l2_zh_Hant_HK_[] = { "zh_Hant_HK", "zh_Hant", NULL };
7737static const char* l2_zh_CN_Hans[] = { "zh_CN", "zh_Hans", NULL };
7738static const char* l2_zh_TW_Hant[] = { "zh_TW", "zh_Hant", NULL };
7739static const char* l3_zh_MOHKTW[] = { "zh_MO", "zh_HK", "zh_TW", NULL };
7740static const char* l3_zh_HK_HantHK_Hant[] = { "zh_HK", "zh_Hant_HK", "zh_Hant", NULL };
7741
7742static const LangAndExpLocs appleLangAndLoc[] = {
7743// language\ result for appleLocs1 appleLocs2 appleLocs3 appleLocs4 appleLocs5 appleLocs6
7744 { "zh", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
7745 { "zh-Hans", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
7746 { "zh-Hant", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l1_zh_Hant, l1_zh_Hant } },
7747 { "zh-Hans-CN", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l2_zh_CN_Hans, l2_zh_CN_Hans } },
7748 { "zh-Hans-SG", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
7749 { "zh-Hant-TW", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l2_zh_TW_Hant, l2_zh_TW_Hant } },
7750 { "zh-Hant-HK", { l1_zh_TW, l2_zh_HKTW, l2_zh_HKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
7751 { "zh-Hant-MO", { l1_zh_TW, l2_zh_HKTW, l3_zh_MOHKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
7752 { "zh-Hans-HK", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
7753 { "zh-CN", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l2_zh_CN_Hans, l2_zh_CN_Hans } },
7754 { "zh-SG", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
7755 { "zh-TW", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l2_zh_TW_Hant, l2_zh_TW_Hant } },
7756 { "zh-HK", { l1_zh_TW, l2_zh_HKTW, l2_zh_HKTW, l2_zh_Hant_HK_, l1_zh_Hant, l3_zh_HK_HantHK_Hant } },
7757 { "zh-MO", { l1_zh_TW, l2_zh_HKTW, l3_zh_MOHKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
7758 { "en", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
7759 { "en-US", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
f3c0d7a5 7760 { "en_US", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
9f1b1155 7761 { "en-CN", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
f3c0d7a5 7762 { "en-JP", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
9f1b1155 7763 { "en-TW", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
f3c0d7a5
A
7764 { "en-TR", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
7765 { "en-001", { l1_Eng, l1_en, l1_en, l1_en, l2_en_001_, l2_en_001_ } },
b331163b 7766 { "en-CA", { l1_Eng, l1_en, l2_en_CA_, l2_en_CA_, l2_en_001_, l2_en_001_ } },
f3c0d7a5 7767 { "en-IL", { l1_Eng, l1_en, l1_en, l1_en, l2_en_001_, l2_en_001_ } },
b331163b
A
7768 { "en-GB", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
7769 { "en-IN", { l1_Eng, l2_en_GB_, l2_en_GB_, l3_en_INGB_, l3_en_GB001_, l3_en_GB001_ } },
f3c0d7a5 7770 { "en-BD", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
3d1f044b 7771 { "en-LK", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
a961784b
A
7772 { "en-GG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
7773 { "en-HK", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
7774 { "en-IE", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
a62d09fc 7775 { "en-JM", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
a961784b
A
7776 { "en-MO", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
7777 { "en-MT", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
a961784b
A
7778 { "en-PK", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
7779 { "en-SG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
7780 { "en-VG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
f3c0d7a5
A
7781 { "en-ZA", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
7782 { "en-AU", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
7783 { "en-NZ", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
7784 { "en-WS", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
b331163b 7785 { "en-150", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
f3c0d7a5
A
7786 { "en-FR", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
7787 { "en-BE", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
b331163b
A
7788 { "en-Latn", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
7789 { "en-Latn-US", { l1_Eng, l1_en, l1_en, l1_en,/*TODO*/ l1_en, l1_en } },
7790 { "en-US-POSIX", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
7791 { "en-Latn-US-POSIX", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
7792 { "en-u-ca-hebrew", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
7793 { "en@calendar=hebrew", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
7794 { "en-", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
7795 { "en_", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
7796 { "es", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
7797 { "es-ES", { l1_Spa, l1_es, l1_es, l1_es, l2_es_ES_, l2_es_ES_ } },
7798 { "es-419", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
7799 { "es-MX", { l1_Spa, l2_es_MX_, l2_es_419_, l3_es_MX419_, l2_es_MX_, l3_es_MX419_ } },
7800 { "es-AR", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
3d1f044b 7801 { "es-BO", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } }, // <rdar://problem/34459988>
2ca993e8 7802 { "es-BR", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
a62d09fc 7803 { "es-BZ", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
f3c0d7a5
A
7804 { "es-AG", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
7805 { "es-AW", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
9f1b1155 7806 { "es-CA", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
f3c0d7a5
A
7807 { "es-CW", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
7808 { "es-SX", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
7809 { "es-TT", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
b331163b
A
7810 { "es-Latn", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
7811 { "es-Latn-MX", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
7812 { "pt", { l1_Port, l1_pt, l1_pt, l1_pt, NULL, NULL } },
7813 { "pt-BR", { l1_Port, l1_pt, l2_pt_BR_, l2_pt_BR_, NULL, NULL } },
7814 { "pt-PT", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
7815 { "pt-MO", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
2ca993e8 7816 { "pt-CH", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
f3c0d7a5 7817 { "pt-FR", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
2ca993e8
A
7818 { "pt-GQ", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
7819 { "pt-LU", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
b331163b
A
7820 { "fr", { l1_Fre, l1_fr, l1_fr, l1_fr, NULL, NULL } },
7821 { "fr-FR", { l1_Fre, l1_fr, l2_fr_FR_, l2_fr_FR_, NULL, NULL } },
7822 { "fr-CA", { l1_Fre, l2_fr_CA_, l2_fr_CA_, l2_fr_CA_, NULL, NULL } },
7823 { "fr-CH", { l1_Fre, l1_fr, l1_fr, l2_fr_CH_, NULL, NULL } },
7824 { "ar", { l1_Ara, l1_ar, l1_ar, NULL, NULL, NULL } },
7825 { "da", { l1_Dan, l1_da, l1_da, NULL, NULL, NULL } },
7826 { "nl", { l1_Dut, l1_nl, l1_nl, l1_nl, NULL, NULL } },
7827 { "nl-BE", { l1_Dut, l1_nl, l1_nl, l2_nl_BE_, NULL, NULL } },
7828 { "fi", { l1_Fin, l1_fi, l1_fi, NULL, NULL, NULL } },
7829 { "de", { l1_Ger, l1_de, l1_de, NULL, NULL, NULL } },
3d1f044b
A
7830 { "it", { l1_Ita, l1_it, l1_it, l1_it, NULL, NULL } },
7831 { "it_CH", { l1_Ita, l1_it, l2_it_CH, l2_it_CH, NULL, NULL } }, // <rdar://problem/35829322>
7832 { "it_IT", { l1_Ita, l1_it, l1_it, l2_it_IT, NULL, NULL } }, // <rdar://problem/35829322>
7833 { "it_VA", { l1_Ita, l1_it, l1_it, l1_it, NULL, NULL } }, // <rdar://problem/35829322>
b331163b
A
7834 { "ja", { l1_Japn, l1_ja, l1_ja, NULL, NULL, NULL } },
7835 { "ko", { l1_Kor, l1_ko, l1_ko, NULL, NULL, NULL } },
7836 { "nb", { l1_Nor, l1_no, l1_nb, NULL, NULL, NULL } },
7837 { "no", { l1_Nor, l1_no, l1_nb, NULL, NULL, NULL } },
7838 { "pl", { l1_Pol, l1_pl, l1_pl, NULL, NULL, NULL } },
7839 { "ru", { l1_Rus, l1_ru, l1_ru, NULL, NULL, NULL } },
7840 { "sv", { l1_Swe, l1_sv, l1_sv, NULL, NULL, NULL } },
7841 { "th", { l1_Thai, l1_th, l1_th, NULL, NULL, NULL } },
7842 { "tr", { l1_Tur, l1_tr, l1_tr, NULL, NULL, NULL } },
7843 { "ca", { l1_ca, l1_ca, l1_ca, NULL, NULL, NULL } },
7844 { "cs", { l1_cs, l1_cs, l1_cs, NULL, NULL, NULL } },
7845 { "el", { l1_el, l1_el, l1_el, NULL, NULL, NULL } },
7846 { "he", { l1_he, l1_he, l1_he, NULL, NULL, l1_iw } },
7847 { "iw", { l1_he, l1_he, l1_he, NULL, NULL, l1_iw } },
7848 { "hr", { l1_hr, l1_hr, l1_hr, NULL, NULL, NULL } },
7849 { "hu", { l1_hu, l1_hu, l1_hu, NULL, NULL, NULL } },
7850 { "id", { l1_id, l1_id, l1_id, NULL, NULL, l1_in } },
7851 { "in", { l1_id, l1_id, l1_id, NULL, NULL, l1_in } },
7852 { "ms", { l1_ms, l1_ms, l1_ms, NULL, NULL, NULL } },
2ca993e8 7853 { "ro", { l1_ro, l1_ro, l1_ro, l1_ro, NULL, l1_mo } },
3d1f044b 7854 { "mo", { l1_ro, l1_ro, l1_ro, l1_ro, NULL, l1_mo } },
b331163b
A
7855 { "sk", { l1_sk, l1_sk, l1_sk, NULL, NULL, NULL } },
7856 { "uk", { l1_uk, l1_uk, l1_uk, NULL, NULL, NULL } },
7857 { "vi", { l1_vi, l1_vi, l1_vi, NULL, NULL, NULL } },
7858 { "yi", { NULL, NULL, NULL, NULL, l1_yi, NULL } },
7859 { "ji", { NULL, NULL, NULL, NULL, l1_yi, NULL } },
7860 { "fil", { NULL, NULL, NULL, NULL, l1_fil, l1_tl } },
7861 { "tl", { NULL, NULL, NULL, NULL, l1_fil, l1_tl } },
7862 { "haw", { NULL, NULL, NULL, NULL, l1_haw, NULL } },
7863 { "sr", { NULL, NULL, NULL, NULL, l1_sr, NULL } },
7864 { "sr-Cyrl", { NULL, NULL, NULL, NULL, l1_sr, NULL } },
7865 { "sr-Latn", { NULL, NULL, NULL, NULL, l1_srLatn, NULL } },
7866 { "tlh", { NULL, NULL, NULL, NULL, l1_tlh, NULL } },
7867 { "Default@2x", { NULL, NULL, NULL, NULL, NULL, NULL } },
7868 { "default", { NULL, NULL, NULL, NULL, NULL, NULL } },
7869 { "root", { NULL, NULL, NULL, NULL, NULL, NULL } },
7870 { "", { NULL, NULL, NULL, NULL, NULL, NULL } },
7871 { "_US", { NULL, NULL, NULL, NULL, NULL, NULL } },
7872 { "-US", { NULL, NULL, NULL, NULL, NULL, NULL } },
7873 { "-u-ca-hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
7874 { "-u-ca-hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
7875 { "@calendar=hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
7876};
7877enum { kNumAppleLangAndLoc = UPRV_LENGTHOF(appleLangAndLoc) };
7878
7879/* tests from <rdar://problem/21518031> */
7880
a961784b
A
7881static const char * appleLocsA1[] = { "en", "fr", "no", "zh-Hant" };
7882static const char * appleLocsA2[] = { "en", "fr", "nb", "zh_TW", "zh_CN", "zh-Hant" };
b331163b
A
7883static const char * appleLocsA3[] = { "en", "en_IN", "en_GB", "fr", "de", "zh_TW" };
7884static const char * appleLocsA4[] = { "Spanish", "es_MX", "English", "en_GB" };
7885static const char * appleLocsA5[] = { "en", "fr", "de", "pt", "pt_PT" };
a961784b 7886static const char * appleLocsA6[] = { "en", "no", "no_NO", "pt_PT" };
b331163b
A
7887
7888static const AppleLocsAndCount locAndCountEntriesA[kNumLocSets] = {
7889 { appleLocsA1, UPRV_LENGTHOF(appleLocsA1) },
7890 { appleLocsA2, UPRV_LENGTHOF(appleLocsA2) },
7891 { appleLocsA3, UPRV_LENGTHOF(appleLocsA3) },
7892 { appleLocsA4, UPRV_LENGTHOF(appleLocsA4) },
7893 { appleLocsA5, UPRV_LENGTHOF(appleLocsA5) },
7894 { appleLocsA6, UPRV_LENGTHOF(appleLocsA6) },
7895};
7896
7897static const LangAndExpLocs appleLangAndLocA[] = {
7898// language\ result for appleLocsA1 appleLocsA2 appleLocsA3 appleLocsA4 appleLocsA5 appleLocsA6
7899 { "zh-Hant", { l1_zhHant,/*0*/ l1_zhHant,/*zh_TW*/ l1_zh_TW, NULL, NULL, NULL } },
7900 { "zh_Hant", { l1_zhHant, l1_zhHant,/*zh_TW*/ l1_zh_TW, NULL, NULL, NULL } },
7901 { "zh_HK", { l1_zhHant, l1_zhHant,/*zh_TW*/ l1_zh_TW, NULL, NULL, NULL } },
7902 { "en_IN", { l1_en, l1_en, l3_en_INGB_, l2_en_GB_Eng, l1_en, l1_en } },
7903 { "es_MX", { NULL, NULL, NULL, l2_es_MX_Spa, NULL, NULL } },
7904 { "pt_PT", { NULL, NULL, NULL, NULL, l2_pt_PT_, l1_pt_PT } },
7905 { "pt", { NULL, NULL, NULL, NULL, l1_pt, l1_pt_PT } },
a961784b
A
7906 { "no", { l1_no, l1_nb, NULL, NULL, NULL, l1_no } },
7907 { "no_NO", { l1_no, l1_nb, NULL, NULL, NULL, l2_no_NO_ } },
7908 { "nb", { l1_no, l1_nb, NULL, NULL, NULL, l1_no } },
7909 { "nb_NO", { l1_no, l1_nb, NULL, NULL, NULL, l2_no_NO_ } },
b331163b
A
7910};
7911enum { kNumAppleLangAndLocA = UPRV_LENGTHOF(appleLangAndLocA) };
7912
7913/* tests from log attached to 21682790 */
7914
7915static const char * appleLocsB1[] = {
7916 "ar", "Base", "ca", "cs",
7917 "da", "Dutch", "el", "English",
7918 "es_MX", "fi", "French", "German",
7919 "he", "hr", "hu", "id",
7920 "Italian", "Japanese", "ko", "ms",
7921 "no", "pl", "pt", "pt_PT",
7922 "ro", "ru", "sk", "Spanish",
7923 "sv", "th", "tr", "uk",
7924 "vi", "zh_CN", "zh_TW"
7925};
7926
7927static const char * appleLocsB2[] = {
7928 "ar", "ca", "cs",
7929 "da", "Dutch", "el", "English",
7930 "es_MX", "fi", "French", "German",
7931 "he", "hr", "hu", "id",
7932 "Italian", "Japanese", "ko", "ms",
7933 "no", "pl", "pt", "pt_PT",
7934 "ro", "ru", "sk", "Spanish",
7935 "sv", "th", "tr", "uk",
7936 "vi", "zh_CN", "zh_TW"
7937};
7938
7939static const char * appleLocsB3[] = {
7940 "ar", "ca", "cs", "da",
7941 "de", "el", "en", "es",
7942 "es_MX", "fi", "French", "he",
7943 "hr", "hu", "id", "Italian",
7944 "ja", "ko", "ms", "nl",
7945 "no", "pl", "pt", "pt_PT",
7946 "ro", "ru", "sk", "sv",
7947 "th", "tr", "uk", "vi",
7948 "zh_CN", "zh_TW"
7949};
7950
7951static const char * appleLocsB4[] = {
7952 "ar", "ca", "cs", "da",
7953 "de", "el", "en", "es",
7954 "es_MX", "fi", "fr", "he",
7955 "hr", "hu", "id", "it",
7956 "ja", "ko", "ms", "nl",
7957 "no", "pl", "pt", "pt_PT",
7958 "ro", "ru", "sk", "sv",
7959 "th", "tr", "uk", "vi",
7960 "zh_CN", "zh_TW"
7961};
7962
7963static const char * appleLocsB5[] = { "en" };
7964
7965static const char * appleLocsB6[] = { "English" };
7966
7967static const AppleLocsAndCount locAndCountEntriesB[kNumLocSets] = {
7968 { appleLocsB1, UPRV_LENGTHOF(appleLocsB1) },
7969 { appleLocsB2, UPRV_LENGTHOF(appleLocsB2) },
7970 { appleLocsB3, UPRV_LENGTHOF(appleLocsB3) },
7971 { appleLocsB4, UPRV_LENGTHOF(appleLocsB4) },
7972 { appleLocsB5, UPRV_LENGTHOF(appleLocsB5) },
7973 { appleLocsB6, UPRV_LENGTHOF(appleLocsB6) },
7974};
7975
7976static const LangAndExpLocs appleLangAndLocB[] = {
7977// language\ result for appleLocsB1 appleLocsB2 appleLocsB3 appleLocsB4 appleLocsB5 appleLocsB6
7978// Prefs 1, logged with sets B1-B3
7979 { "en", { l1_Eng, l1_Eng, l1_en, l1_en, l1_en, l1_Eng } },
7980 { "es", { l1_Spa, l1_Spa, l1_es, l1_es, NULL, NULL } },
7981// Prefs 2, logged with sets B1-B6
7982 { "English", { l1_Eng, l1_Eng, l1_en, l1_en, l1_en, l1_Eng } },
7983 { "Spanish", { l1_Spa, l1_Spa, l1_es, l1_es, NULL, NULL } },
7984};
7985enum { kNumAppleLangAndLocB = UPRV_LENGTHOF(appleLangAndLocB) };
7986
7987typedef struct {
7988 const AppleLocsAndCount * locAndCountEntriesPtr;
7989 const LangAndExpLocs * appleLangAndLocPtr;
7990 int32_t appleLangAndLocCount;
7991} AppleLocToUseTestSet;
7992
7993static const AppleLocToUseTestSet altuTestSets[] = {
7994 { locAndCountEntries, appleLangAndLoc, kNumAppleLangAndLoc },
7995 { locAndCountEntriesA, appleLangAndLocA, kNumAppleLangAndLocA },
7996 { locAndCountEntriesB, appleLangAndLocB, kNumAppleLangAndLocB },
7997 { NULL, NULL, 0 }
7998};
7999
8000/* tests for multiple prefs sets */
8001
2ca993e8
A
8002static const char * appleLocsM1[] = { "en", "en_GB", "pt", "pt_PT", "zh_CN", "zh_Hant" };
8003static const char * prefLangsM1[] = { "tlh", "zh_HK", "zh_SG", "zh_Hans", "pt_BR", "pt_PT", "en_IN", "en" };
8004static const char * locsToUseM1[] = { "zh_Hant" };
8005
8006// Tests from first pass at <rdar://problem/22012864>, 2015-11-18
8007
8008static const char * appleLocsM2[] = { "fr-FR", "en-US", "en-GB" };
8009static const char * prefLangsM2[] = { "fr-CH" };
8010static const char * locsToUseM2[] = { "fr-FR" };
8011
8012static const char * appleLocsM3[] = { "es-es", "fr-fr" };
8013static const char * prefLangsM3[] = { "fr-US", "fr", "en-US" };
8014static const char * locsToUseM3[] = { "fr-fr" };
8015
8016static const char * appleLocsM4[] = { "es-es", "fr-fr", "fr" };
8017static const char * prefLangsM4[] = { "fr-US", "fr", "en-US" };
8018static const char * locsToUseM4[] = { "fr" };
8019
8020// Tests from second pass at <rdar://problem/22012864>, 2015-12-08
8021// Per Karan M
8022static const char * appleLocsM5[] = { "en-US", "fr-FR", "de-DE", "es-ES", "es-419", "pt-PT", "pt-BR", "zh-CN", "zh-TW", "zh-HK", "ja-JP", "ko-KR" };
8023static const char * prefLangsM5[] = { "fr-US", "en-US" };
8024static const char * locsToUseM5[] = { "fr-FR" };
8025// Per Peter E; expected result changed from "en-US" to "de-CH" per <rdar://problem/26559053>
8026static const char * appleLocsM6[] = { "de-CH", "en-US" };
8027static const char * prefLangsM6[] = { "de-DE", "en-US" };
8028static const char * locsToUseM6[] = { "de-CH" };
8029// The following is used for M7-MD
8030static const char * appleLocsMx[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-HK", "zh-TW" };
8031// Per Karan M
8032static const char * prefLangsM7[] = { "fr-ES", "en-AU" };
8033static const char * locsToUseM7[] = { "fr-FR" };
8034// Per Karan M
8035static const char * prefLangsM8[] = { "de-IT", "en-AU" };
8036static const char * locsToUseM8[] = { "de-DE" };
8037// Per Karan M
8038static const char * prefLangsM9[] = { "hi-US", "en-AU" };
8039static const char * locsToUseM9[] = { "hi-IN" };
8040// Per Karan M
8041static const char * prefLangsMA[] = { "en-IN", "zh-HK" };
8042static const char * locsToUseMA[] = { "en-AU" };
8043// Per Karan M
8044static const char * prefLangsMB[] = { "pt-PT", "en-AU" };
8045static const char * locsToUseMB[] = { "en-AU" };
8046// per Paul B:
8047static const char * prefLangsMC[] = { "pt-PT", "ar" };
8048static const char * locsToUseMC[] = { "pt-BR" };
8049// Per Karan M
8050static const char * prefLangsMD[] = { "zh-CN", "en-AU" };
8051static const char * locsToUseMD[] = { "en-AU" };
8052// Per Karan M
8053static const char * appleLocsME[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-CN", "zh-HK" };
8054static const char * prefLangsME[] = { "zh-TW", "en-AU" };
8055static const char * locsToUseME[] = { "zh-HK" };
8056// Per Peter E in diagnosis for <rdar://problem/22012864> and <rdar://problem/23815194>
8057static const char * appleLocsMF[] = { "en", "en-GB", "fr", "es" };
8058static const char * prefLangsMF[] = { "en-IN", "en-GB", "de", "fr" };
8059static const char * locsToUseMF[] = { "en-GB", "en" };
8060// Per Karan M in <rdar://problem/23982460>
8061static const char * appleLocsMG[] = { "zh-Hans", "zh-Hant", "zh-HK" };
8062static const char * prefLangsMG[] = { "zh-Hans-US", "zh-HK", "en-US" };
8063static const char * locsToUseMG[] = { "zh-Hans" };
8064// Per <rdar://problem/25903891>
8065static const char * appleLocsMH[] = { "zh-TW", "zh-CN", "zh-HK" };
8066static const char * prefLangsMH[] = { "zh-Hans-HK", "zh-HK", "en" };
8067static const char * locsToUseMH[] = { "zh-CN" };
8068// Per <rdar://problem/26559053>
8069static const char * appleLocsMI[] = { "unk", "en-US", "ar-SA" };
8070static const char * prefLangsMI[] = { "ar-US" };
8071static const char * locsToUseMI[] = { "ar-SA" };
f3c0d7a5
A
8072// Per <rdar://problem/30501523> - first for comparison with zh, then real test
8073static const char * appleLocsMJ[] = { "zh-CN", "en-US" };
8074static const char * prefLangsMJ[] = { "zh", "zh_AC" };
8075static const char * locsToUseMJ[] = { "zh-CN" };
8076static const char * appleLocsMK[] = { "yue-CN", "en-US" };
8077static const char * prefLangsMK[] = { "yue", "yue_AC" };
8078static const char * locsToUseMK[] = { "yue-CN" };
8079// Per <rdar://problem/30433534>
8080static const char * appleLocsML[] = { "nl_NL", "es_MX", "fr_FR", "zh_TW", "it_IT", "vi_VN", "fr_CH", "es_CL",
8081 "en_ZA", "ko_KR", "ca_ES", "ro_RO", "en_PH", "en_CA", "en_SG", "en_IN",
8082 "en_NZ", "it_CH", "fr_CA", "da_DK", "de_AT", "pt_BR", "yue_CN", "zh_CN",
8083 "sv_SE", "es_ES", "ar_SA", "hu_HU", "fr_BE", "en_GB", "ja_JP", "zh_HK",
8084 "fi_FI", "tr_TR", "nb_NO", "en_ID", "en_SA", "pl_PL", "ms_MY", "cs_CZ",
8085 "el_GR", "id_ID", "hr_HR", "en_AE", "he_IL", "ru_RU", "wuu_CN", "de_DE",
8086 "de_CH", "en_AU", "nl_BE", "th_TH", "pt_PT", "sk_SK", "en_US", "en_IE",
8087 "es_CO", "uk_UA", "es_US" };
8088static const char * prefLangsML[] = { "en-JP" };
8089static const char * locsToUseML[] = { "en_US" };
8090// Per <rdar://problem/32421203>
8091static const char * appleLocsMM1[] = { "pt-PT" };
8092static const char * appleLocsMM2[] = { "pt-BR" };
8093static const char * appleLocsMM3[] = { "pt-PT", "pt-BR" };
8094static const char * appleLocsMM4[] = { "en", "pt-PT" };
8095static const char * appleLocsMM5[] = { "en", "pt-BR" };
8096static const char * appleLocsMM6[] = { "en", "pt-PT", "pt-BR" };
8097static const char * prefLangsMM1[] = { "pt-PT" };
8098static const char * prefLangsMM2[] = { "pt-BR" };
8099static const char * prefLangsMM3[] = { "pt" };
8100static const char * prefLangsMM4[] = { "pt-PT", "en" };
8101static const char * prefLangsMM5[] = { "pt-BR", "en" };
8102static const char * prefLangsMM6[] = { "pt", "en" };
8103static const char * locsToUseMMptPT[] = { "pt-PT" };
8104static const char * locsToUseMMptBR[] = { "pt-BR" };
8105static const char * locsToUseMMen[] = { "en" };
8106// Per <rdar://problem/32658828>
8107static const char * appleLocsMN[] = { "en-US", "en-GB" };
8108static const char * prefLangsMN1[] = { "en-KR" };
8109static const char * prefLangsMN2[] = { "en-SA" };
8110static const char * prefLangsMN3[] = { "en-TW" };
8111static const char * prefLangsMN4[] = { "en-JP" };
8112static const char * locsToUseMN_U[] = { "en-US" };
9f1b1155
A
8113// Per <rdar://problem/36010857>
8114static const char * appleLocsMO[] = { "Dutch", "French", "German", "Italian", "Japanese", "Spanish",
8115 "ar", "ca", "cs", "da", "el", "en_AU", "en_GB", "en_IN",
8116 "es_419", "fi", "fr_CA", "he", "hi", "hr", "hu", "id", "ko",
8117 "ms", "no", "pl", "pt", "pt_PT", "ro", "ru", "sk", "sv",
8118 "th", "tr", "uk", "vi", "zh_CN", "zh_HK", "zh_TW" };
8119static const char * prefLangsMO1[] = { "en-US" };
8120static const char * locsToUseMO1[] = { "en_GB" };
3d1f044b
A
8121// Per <rdar://problem/47494729>
8122static const char * appleLocsMP[] = { "en-IN", "hi-IN" };
8123static const char * prefLangsMP[] = { "hi-Latn-IN", "en-IN" };
8124static const char * locsToUseMP[] = { "en-IN" };
8125// Per <rdar://problem/34459988&35829322>
8126static const char * appleLocsMQa[] = { "en_AU", "en_IE", "en_IN", "en_SA", "en_UK", "en_US", "es_AR", "es_CO", "es_ES", "es_MX", "fr_CA", "fr_FR", "it_CH", "it_IT", "zh_CN", "zh_HK", "zh_TW" };
8127static const char * appleLocsMQb[] = { "en_AU", "en_IE", "en_IN", "en_SA", "en_UK", "en", "es_AR", "es_CO", "es", "es_MX", "fr_CA", "fr", "it_CH", "it", "zh_CN", "zh_HK", "zh_TW" };
8128static const char * prefLangsMQ1[] = { "es-BO" };
8129static const char * locsToUseMQ1[] = { "es_MX" };
8130static const char * prefLangsMQ2[] = { "it-VA" };
8131static const char * locsToUseMQ2a[] = { "it_IT" };
8132static const char * locsToUseMQ2b[] = { "it" };
8133// Per <rdar://problem/50913699>
8134static const char * appleLocsMRa[] = { "en", "hi" };
8135static const char * appleLocsMRb[] = { "en", "hi", "hi_Latn" };
8136static const char * prefLangsMRx[] = { "hi_Latn_IN", "en_IN", "hi_IN" };
8137static const char * prefLangsMRy[] = { "hi_Latn", "en", "hi" };
8138static const char * locsToUseMRa[] = { "en" };
8139static const char * locsToUseMRb[] = { "hi_Latn", "en" };
8140// For <rdar://problem/50280505>
8141static const char * appleLocsMSa[] = { "en", "en_GB" };
8142static const char * appleLocsMSb[] = { "en", "en_GB", "en_AU" };
8143static const char * prefLangsMSx[] = { "en_NZ" };
8144static const char * prefLangsMSy[] = { "en_NZ", "en_AU" };
8145static const char * locsToUseMSa[] = { "en_GB", "en" };
8146static const char * locsToUseMSb[] = { "en_AU", "en_GB", "en" };
1a147d09
A
8147// For <rdar://problem/55885283>
8148static const char * appleLocsMT[] = { "ca-ES", "fi", "nl", "en-US", "hu", "pt-BR", "pl-PL", "it",
8149 "ru", "el", "el-GR", "ca", "de-DE", "sv-SE", "tr", "pl",
8150 "sv", "tr-TR", "da", "en", "nb", "pt-PT", "nb-NO",
8151 "es-ES@collation=traditional", "sl-SI", "cs", "hu-HU",
8152 "cs-CZ", "sk", "sl", "de", "da-DK", "es-MX", "vi", "nl-NL",
8153 "es", "fi-FI", "fr", "it-IT", "es-ES", "fr-CA", "vi-VN",
8154 "pt", "sk-SK", "eu-ES", "ru-RU", "eu", "fr-FR", "unk" };
8155static const char * prefLangsMTa[] = { "en" };
8156static const char * prefLangsMTb[] = { "he" };
8157static const char * locsToUseMTa[] = { "en" };
8158static const char * locsToUseMTb[] = { };
2ca993e8
A
8159
8160typedef struct {
8161 const char * name;
8162 const char ** availLocs;
8163 int32_t availLocsCount;
8164 const char ** prefLangs;
8165 int32_t prefLangsCount;
8166 const char ** locsToUse;
8167 int32_t locsToUseCount;
8168} MultiPrefTest;
8169
8170static const MultiPrefTest multiTestSets[] = {
8171 { "M1", appleLocsM1, UPRV_LENGTHOF(appleLocsM1), prefLangsM1, UPRV_LENGTHOF(prefLangsM1), locsToUseM1, UPRV_LENGTHOF(locsToUseM1) },
8172 //
8173 { "M2", appleLocsM2, UPRV_LENGTHOF(appleLocsM2), prefLangsM2, UPRV_LENGTHOF(prefLangsM2), locsToUseM2, UPRV_LENGTHOF(locsToUseM2) },
8174 { "M3", appleLocsM3, UPRV_LENGTHOF(appleLocsM3), prefLangsM3, UPRV_LENGTHOF(prefLangsM3), locsToUseM3, UPRV_LENGTHOF(locsToUseM3) },
8175 { "M4", appleLocsM4, UPRV_LENGTHOF(appleLocsM4), prefLangsM4, UPRV_LENGTHOF(prefLangsM4), locsToUseM4, UPRV_LENGTHOF(locsToUseM4) },
8176 //
8177 { "M5", appleLocsM5, UPRV_LENGTHOF(appleLocsM5), prefLangsM5, UPRV_LENGTHOF(prefLangsM5), locsToUseM5, UPRV_LENGTHOF(locsToUseM5) },
8178 { "M6", appleLocsM6, UPRV_LENGTHOF(appleLocsM6), prefLangsM6, UPRV_LENGTHOF(prefLangsM6), locsToUseM6, UPRV_LENGTHOF(locsToUseM6) },
8179 { "M7", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM7, UPRV_LENGTHOF(prefLangsM7), locsToUseM7, UPRV_LENGTHOF(locsToUseM7) },
8180 { "M8", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM8, UPRV_LENGTHOF(prefLangsM8), locsToUseM8, UPRV_LENGTHOF(locsToUseM8) },
8181 { "M9", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM9, UPRV_LENGTHOF(prefLangsM9), locsToUseM9, UPRV_LENGTHOF(locsToUseM9) },
8182 { "MA", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMA, UPRV_LENGTHOF(prefLangsMA), locsToUseMA, UPRV_LENGTHOF(locsToUseMA) },
8183 { "MB", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMB, UPRV_LENGTHOF(prefLangsMB), locsToUseMB, UPRV_LENGTHOF(locsToUseMB) },
8184 { "MC", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMC, UPRV_LENGTHOF(prefLangsMC), locsToUseMC, UPRV_LENGTHOF(locsToUseMC) },
8185 { "MD", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMD, UPRV_LENGTHOF(prefLangsMD), locsToUseMD, UPRV_LENGTHOF(locsToUseMD) },
8186 { "ME", appleLocsME, UPRV_LENGTHOF(appleLocsME), prefLangsME, UPRV_LENGTHOF(prefLangsME), locsToUseME, UPRV_LENGTHOF(locsToUseME) },
8187 { "MF", appleLocsMF, UPRV_LENGTHOF(appleLocsMF), prefLangsMF, UPRV_LENGTHOF(prefLangsMF), locsToUseMF, UPRV_LENGTHOF(locsToUseMF) },
8188 { "MG", appleLocsMG, UPRV_LENGTHOF(appleLocsMG), prefLangsMG, UPRV_LENGTHOF(prefLangsMG), locsToUseMG, UPRV_LENGTHOF(locsToUseMG) },
8189 { "MH", appleLocsMH, UPRV_LENGTHOF(appleLocsMH), prefLangsMH, UPRV_LENGTHOF(prefLangsMH), locsToUseMH, UPRV_LENGTHOF(locsToUseMH) },
8190 { "MI", appleLocsMI, UPRV_LENGTHOF(appleLocsMI), prefLangsMI, UPRV_LENGTHOF(prefLangsMI), locsToUseMI, UPRV_LENGTHOF(locsToUseMI) },
f3c0d7a5
A
8191 { "MJ", appleLocsMJ, UPRV_LENGTHOF(appleLocsMJ), prefLangsMJ, UPRV_LENGTHOF(prefLangsMJ), locsToUseMJ, UPRV_LENGTHOF(locsToUseMJ) },
8192 { "MK", appleLocsMK, UPRV_LENGTHOF(appleLocsMK), prefLangsMK, UPRV_LENGTHOF(prefLangsMK), locsToUseMK, UPRV_LENGTHOF(locsToUseMK) },
8193 { "ML", appleLocsML, UPRV_LENGTHOF(appleLocsML), prefLangsML, UPRV_LENGTHOF(prefLangsML), locsToUseML, UPRV_LENGTHOF(locsToUseML) },
8194 { "MM11", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8195 { "MM21", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8196 { "MM31", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8197 { "MM41", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8198 { "MM51", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8199 { "MM61", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8200 { "MM12", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8201 { "MM22", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8202 { "MM32", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8203 { "MM42", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8204 { "MM52", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8205 { "MM62", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8206 { "MM13", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8207 { "MM23", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8208 { "MM33", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8209 { "MM43", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8210 { "MM53", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8211 { "MM63", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8212 { "MM14", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8213 { "MM24", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8214 { "MM34", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8215 { "MM44", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8216 { "MM54", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMen, UPRV_LENGTHOF(locsToUseMMen) }, // want en, see <rdar://problem/22012864>
8217 { "MM64", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8218 { "MM15", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8219 { "MM25", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8220 { "MM35", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8221 { "MM45", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8222 { "MM55", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8223 { "MM65", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8224 { "MM16", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8225 { "MM26", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8226 { "MM36", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8227 { "MM46", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
8228 { "MM56", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8229 { "MM66", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
8230 { "MN1", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN1, UPRV_LENGTHOF(prefLangsMN1), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
8231 { "MN2", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN2, UPRV_LENGTHOF(prefLangsMN2), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
8232 { "MN3", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN3, UPRV_LENGTHOF(prefLangsMN3), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
8233 { "MN4", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN4, UPRV_LENGTHOF(prefLangsMN4), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
3d1f044b
A
8234 { "MO", appleLocsMO, UPRV_LENGTHOF(appleLocsMO), prefLangsMO1, UPRV_LENGTHOF(prefLangsMO1), locsToUseMO1, UPRV_LENGTHOF(locsToUseMO1) },
8235 { "MP", appleLocsMP, UPRV_LENGTHOF(appleLocsMP), prefLangsMP, UPRV_LENGTHOF(prefLangsMP), locsToUseMP, UPRV_LENGTHOF(locsToUseMP) },
8236 { "MQ1a", appleLocsMQa, UPRV_LENGTHOF(appleLocsMQa), prefLangsMQ1, UPRV_LENGTHOF(prefLangsMQ1), locsToUseMQ1, UPRV_LENGTHOF(locsToUseMQ1) },
8237// { "MQ1b", appleLocsMQb, UPRV_LENGTHOF(appleLocsMQb), prefLangsMQ1, UPRV_LENGTHOF(prefLangsMQ1), locsToUseMQ1, UPRV_LENGTHOF(locsToUseMQ1) }, // still to do for <rdar://problem/34459988>
8238 { "MQ2a", appleLocsMQa, UPRV_LENGTHOF(appleLocsMQa), prefLangsMQ2, UPRV_LENGTHOF(prefLangsMQ2), locsToUseMQ2a, UPRV_LENGTHOF(locsToUseMQ2a) },
8239 { "MQ2b", appleLocsMQb, UPRV_LENGTHOF(appleLocsMQb), prefLangsMQ2, UPRV_LENGTHOF(prefLangsMQ2), locsToUseMQ2b, UPRV_LENGTHOF(locsToUseMQ2b) },
8240 { "MRa", appleLocsMRa, UPRV_LENGTHOF(appleLocsMRa), prefLangsMRx, UPRV_LENGTHOF(prefLangsMRx), locsToUseMRa, UPRV_LENGTHOF(locsToUseMRa) },
8241 { "MRb", appleLocsMRb, UPRV_LENGTHOF(appleLocsMRb), prefLangsMRx, UPRV_LENGTHOF(prefLangsMRx), locsToUseMRb, UPRV_LENGTHOF(locsToUseMRb) },
8242 { "MRa", appleLocsMRa, UPRV_LENGTHOF(appleLocsMRa), prefLangsMRy, UPRV_LENGTHOF(prefLangsMRy), locsToUseMRa, UPRV_LENGTHOF(locsToUseMRa) },
8243 { "MRb", appleLocsMRb, UPRV_LENGTHOF(appleLocsMRb), prefLangsMRy, UPRV_LENGTHOF(prefLangsMRy), locsToUseMRb, UPRV_LENGTHOF(locsToUseMRb) },
8244 { "MSax", appleLocsMSa, UPRV_LENGTHOF(appleLocsMSa), prefLangsMSx, UPRV_LENGTHOF(prefLangsMSx), locsToUseMSa, UPRV_LENGTHOF(locsToUseMSa) },
8245 { "MSay", appleLocsMSa, UPRV_LENGTHOF(appleLocsMSa), prefLangsMSy, UPRV_LENGTHOF(prefLangsMSy), locsToUseMSa, UPRV_LENGTHOF(locsToUseMSa) },
8246 { "MSbx", appleLocsMSb, UPRV_LENGTHOF(appleLocsMSb), prefLangsMSx, UPRV_LENGTHOF(prefLangsMSx), locsToUseMSb, UPRV_LENGTHOF(locsToUseMSb) },
8247 { "MSby", appleLocsMSb, UPRV_LENGTHOF(appleLocsMSb), prefLangsMSy, UPRV_LENGTHOF(prefLangsMSy), locsToUseMSb, UPRV_LENGTHOF(locsToUseMSb) },
1a147d09
A
8248 { "MTa", appleLocsMT, UPRV_LENGTHOF(appleLocsMT), prefLangsMTa, UPRV_LENGTHOF(prefLangsMTa), locsToUseMTa, UPRV_LENGTHOF(locsToUseMTa) },
8249 { "MTb", appleLocsMT, UPRV_LENGTHOF(appleLocsMT), prefLangsMTb, UPRV_LENGTHOF(prefLangsMTb), locsToUseMTb, UPRV_LENGTHOF(locsToUseMTb) },
f3c0d7a5 8250
2ca993e8 8251 { NULL, NULL, 0, NULL, 0, NULL, 0 }
b331163b
A
8252};
8253
2ca993e8 8254
b331163b
A
8255/* general enums */
8256
8257enum { kMaxLocalizationsToUse = 8, kPrintArrayBufSize = 128 };
8258
8259// array, array of pointers to strings to print
8260// count, count of array elements, may be -1 if array is terminated by a NULL entry
8261// buf, buffer into which to put concatenated strings
8262// bufSize, length of buf
8263static void printStringArray(const char **array, int32_t count, char *buf, int32_t bufSize) {
8264 char * bufPtr = buf;
8265 const char * curEntry;
8266 int32_t idx, countMax = bufSize/16;
8267 if (count < 0 || count > countMax) {
8268 count = countMax;
8269 }
8270 for (idx = 0; idx < count && (curEntry = *array++) != NULL; idx++) {
8271 int32_t len = sprintf(bufPtr, "%s\"%.12s\"", (idx > 0)? ", ": "", curEntry);
8272 if (len <= 0) {
8273 break;
8274 }
8275 bufPtr += len;
8276 }
8277 *bufPtr = 0; /* ensure termination */
8278}
8279
8280static UBool equalStringArrays(const char **array1, int32_t count1, const char **array2, int32_t count2) {
8281 const char ** array1Ptr = array1;
8282 const char ** array2Ptr = array2;
2ca993e8 8283 int32_t idx;
b331163b
A
8284 if (count1 < 0) {
8285 count1 = 0;
8286 while (*array1Ptr++ != NULL) {
8287 count1++;
8288 }
8289 }
8290 if (count2 < 0) {
8291 count2 = 0;
8292 while (*array2Ptr++ != NULL) {
8293 count2++;
8294 }
8295 }
8296 if (count1 != count2) {
8297 return FALSE;
8298 }
b331163b
A
8299 for (idx = 0; idx < count1; idx++) {
8300 if (uprv_strcmp(array1[idx], array2[idx]) != 0) {
8301 return FALSE;
8302 }
8303 }
8304 return TRUE;
8305}
8306
8307static void TestAppleLocalizationsToUse() {
8308 const AppleLocToUseTestSet * testSetPtr;
2ca993e8 8309 const MultiPrefTest * multiSetPtr;
b331163b
A
8310 const char * locsToUse[kMaxLocalizationsToUse];
8311 int32_t numLocsToUse;
8312 UErrorCode status;
8313 char printExpected[kPrintArrayBufSize];
8314 char printActual[kPrintArrayBufSize];
8315
8316 for (testSetPtr = altuTestSets; testSetPtr->locAndCountEntriesPtr != NULL; testSetPtr++) {
8317 int32_t iLocSet, iLang;
8318
8319 for (iLocSet = 0; iLocSet < kNumLocSets; iLocSet++) {
8320 for (iLang = 0; iLang < testSetPtr->appleLangAndLocCount; iLang++) {
b331163b
A
8321 const char * language = testSetPtr->appleLangAndLocPtr[iLang].language;
8322 const char ** expLocsForSet = testSetPtr->appleLangAndLocPtr[iLang].expLocsForSets[iLocSet];
2ca993e8 8323 status = U_ZERO_ERROR;
b331163b
A
8324
8325 numLocsToUse = ualoc_localizationsToUse(&language, 1,
8326 testSetPtr->locAndCountEntriesPtr[iLocSet].locs, testSetPtr->locAndCountEntriesPtr[iLocSet].locCount,
8327 locsToUse, kMaxLocalizationsToUse, &status);
8328 if (U_FAILURE(status)) {
8329 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, status %s\n",
8330 testSetPtr-altuTestSets, iLocSet+1, language, u_errorName(status));
8331 } else if (numLocsToUse == 0 && expLocsForSet != NULL) {
8332 printStringArray(expLocsForSet, -1, printExpected, kPrintArrayBufSize);
8333 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect {%s}, get no results\n",
8334 testSetPtr-altuTestSets, iLocSet+1, language, printExpected);
8335 } else if (numLocsToUse > 0 && expLocsForSet == NULL) {
8336 printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
8337 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect no results, get {%s}\n",
8338 testSetPtr-altuTestSets, iLocSet+1, language, printActual);
8339 } else if (numLocsToUse > 0 && !equalStringArrays(expLocsForSet, -1, locsToUse, numLocsToUse)) {
8340 printStringArray(expLocsForSet, -1, printExpected, kPrintArrayBufSize);
8341 printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
8342 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s:\n expect {%s}\n get {%s}\n",
8343 testSetPtr-altuTestSets, iLocSet+1, language, printExpected, printActual);
8344 }
8345 }
8346 }
8347 }
8348
2ca993e8
A
8349 for (multiSetPtr = multiTestSets; multiSetPtr->name != NULL; multiSetPtr++) {
8350 status = U_ZERO_ERROR;
8351 numLocsToUse = ualoc_localizationsToUse(multiSetPtr->prefLangs, multiSetPtr->prefLangsCount, multiSetPtr->availLocs, multiSetPtr->availLocsCount, locsToUse, kMaxLocalizationsToUse, &status);
8352 if (U_FAILURE(status)) {
8353 log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s, status %s\n", multiSetPtr->name, multiSetPtr->name, u_errorName(status));
8354 } else if (!equalStringArrays(multiSetPtr->locsToUse, multiSetPtr->locsToUseCount, locsToUse, numLocsToUse)) {
8355 printStringArray(multiSetPtr->locsToUse, multiSetPtr->locsToUseCount, printExpected, kPrintArrayBufSize);
8356 printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
8357 log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s:\n expect {%s}\n get {%s}\n",
8358 multiSetPtr->name, multiSetPtr->name, printExpected, printActual);
8359 }
8360 }
b331163b 8361}
4f1e1a09 8362#endif