diff --git a/.gitattributes b/.gitattributes index e7e0adbc655..976273bf156 100644 --- a/.gitattributes +++ b/.gitattributes @@ -87,3 +87,12 @@ configure text # Use JSONC for syntax highlighting on GitHub.com *.json linguist-language=jsonc +# Codepoint trie golden tests compare bytes; keep generated TOML line endings stable. +icu/icu4c/source/test/testdata/codepointtrie/*.toml text eol=lf + +# Shell script fragments assembled into icu-config (an executable shell script). +# They must have LF line endings so WSL/Linux can execute the generated file. +icu/icu4c/source/config/icu-config-top text eol=lf +icu/icu4c/source/config/icu-config-bottom text eol=lf +icu/icu4c/source/config/mh-* text eol=lf + diff --git a/icu-patches/dev_report.md b/icu-patches/dev_report.md new file mode 100644 index 00000000000..db822262450 --- /dev/null +++ b/icu-patches/dev_report.md @@ -0,0 +1,74 @@ +# ICU Upgrade Dev Report + +Generated: 2026-05-19 09:01:27 + +## 1. Version Summary + +| Field | Value | +|-------|-------| +| ICU Version | 78.3.0.0 | +| Upstream Hash | `21d1eb0f30...` | + +## 2. Source Changes + +Diff from `icu72-pre-swap` to HEAD (icu/ directory only): + +``` + 6919 files changed, 693820 insertions(+), 545058 deletions(-) +``` + +### Top file types changed + +| Extension | Count | +|-----------|-------| +| .txt | 5117 | +| .cpp | 799 | +| .h | 552 | +| .c | 105 | +| .vcxproj | 77 | +| .json | 46 | +| .filters | 30 | +| .xml | 29 | +| .java | 28 | +| .in | 25 | + +## 3. Patch Audit Results + +*No audit report found in `icu-patches`. Final patch records are summarized from `icu-patches/patches` instead.* + +- Latest patch-record commit: `70ae0ef8eab Refresh patch record for Saudi Riyal symbol override` +- Patch files present: 20 +- Refreshed ICU 78 patch records: `002`, `017`, `018`, `020`, `022`, `023` +- Validation used for refreshed records: `git apply --cached --check --reverse` against the final ICU index + +## 4. Build Results + +| Config | Status | Log | +|--------|--------|-----| +| Debug-ARM64 | ✅ PASS | build-Debug-ARM64.log | +| Debug-Win32 | ✅ PASS | build-Debug-Win32.log | +| Debug-x64 | ✅ PASS | build-Debug-x64.log | +| Release-ARM64 | ✅ PASS | build-Release-ARM64.log | +| Release-Win32 | ✅ PASS | build-Release-Win32.log | +| Release-x64 | ✅ PASS | build-Release-x64.log | + +## 5. Test Results + +| Suite | Status | Log | +|-------|--------|-----| +| cintltst-Release-x64 | ✅ PASS | test-cintltst-Release-x64.log | +| intlRelease-x64 | ✅ PASS | test-intltest-Release-x64.log | +| ioRelease-x64 | ✅ PASS | test-iotest-Release-x64.log | + +Post-report targeted validation for patch `023`: `genrb` parsed `icu/icu4c/source/data/curr/ar_SA.txt`, and `currtest.c` passed C syntax checking with the available compiler. + +## 6. Action Items + +- [x] Patch conflicts resolved and ICU 78 patch records refreshed +- [x] Saudi Riyal symbol override for `ar_SA` added and recorded as patch `023` +- [x] CLDR data rebuild consumed by ICU data generation +- [x] Timezone data check/regeneration completed +- [x] Full Stage 8 build/test pass completed +- [x] Refreshed dev report generated +- [ ] Create PR/PR stack (owner-handled) + diff --git a/icu-patches/patches/002-MSFT-Patch-ICU_test_changes_for_MSFT_changes.patch b/icu-patches/patches/002-MSFT-Patch-ICU_test_changes_for_MSFT_changes.patch index d4f27a2719c..d659e762daf 100644 --- a/icu-patches/patches/002-MSFT-Patch-ICU_test_changes_for_MSFT_changes.patch +++ b/icu-patches/patches/002-MSFT-Patch-ICU_test_changes_for_MSFT_changes.patch @@ -1,90 +1,363 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Ju <41210545+daniel-ju@users.noreply.github.com> -Date: Thu, 10 Dec 2020 22:02:04 -0800 -Subject: MSFT-PATCH: Modify ICU tests to pass with Microsoft modified CLDR - data. +From: Arvind Oruganti +Date: Tue, 19 May 2026 06:45:00 +0530 +Subject: MSFT-PATCH: Refresh ICU tests for Microsoft modified CLDR data on ICU 78 -This changes modifies the ICU tests to pass with the modified CLDR-MS -data. The modifications are generally for the following reasons: - - Some of data is different due to internal requirements. - - Some are due to the extra locales that we pick up from CLDR Seed. - These Seed locales have data quality issues, which causes the - ICU tests to fail as they don't meet the ICU expectations. - - Removal of the yue-* locales. +Refreshes the ICU test expectation changes required by Microsoft-modified CLDR data after the ICU 78 upgrade. -diff --git a/icu/icu4c/source/test/cintltst/cldrtest.c b/icu/icu4c/source/test/cintltst/cldrtest.c -index e50ccb3cd1f9431afbd15c7d8a21a34632131c89..179539d5178b5cfd8b5350043c539e89e8740185 100644 ---- a/icu/icu4c/source/test/cintltst/cldrtest.c -+++ b/icu/icu4c/source/test/cintltst/cldrtest.c -@@ -957,6 +957,25 @@ static void VerifyTranslation(void) { - //else if (uprv_strncmp(currLoc,"bem",3) == 0 || uprv_strncmp(currLoc,"mgo",3) == 0 || uprv_strncmp(currLoc,"nl",2) == 0) { - // log_verbose("skipping test for %s, some month and country names known to use aux exemplars\n", currLoc); - //} -+ -+ /* MSFT Change: Begin */ -+ else if ( -+ uprv_strncmp(currLoc, "ba", 2) == 0 || uprv_strncmp(currLoc, "ba_RU", 5) == 0 || -+ uprv_strncmp(currLoc, "byn", 3) == 0 || uprv_strncmp(currLoc, "byn_ER", 6) == 0 || -+ uprv_strncmp(currLoc, "cu", 2) == 0 || uprv_strncmp(currLoc, "cu_RU", 5) == 0 || -+ uprv_strncmp(currLoc, "dv", 2) == 0 || uprv_strncmp(currLoc, "dv_MV", 5) == 0 || -+ uprv_strncmp(currLoc, "iu", 2) == 0 || uprv_strncmp(currLoc, "iu_CA", 5) == 0 || -+ uprv_strncmp(currLoc, "mn_Mong", 7) == 0 || uprv_strncmp(currLoc, "mn_Mong_CN", 10) == 0 || -+ uprv_strncmp(currLoc, "nqo", 3) == 0 || uprv_strncmp(currLoc, "nqo_GN", 6) == 0 || -+ uprv_strncmp(currLoc, "oc", 2) == 0 || uprv_strncmp(currLoc, "oc_FR", 5) == 0 || -+ uprv_strncmp(currLoc, "syr", 3) == 0 || uprv_strncmp(currLoc, "syr_SY", 6) == 0 || -+ uprv_strncmp(currLoc, "tig", 3) == 0 || uprv_strncmp(currLoc, "tig_ER", 6) == 0 || -+ uprv_strncmp(currLoc, "wal", 3) == 0 || uprv_strncmp(currLoc, "wal_ET", 6) == 0 -+ ) { -+ log_knownIssue("0", "MSFT Change: skipping test for %s which has issues due to CLDR Seed data.", currLoc); -+ } -+ /* MSFT Change: End */ -+ - else { - UChar langBuffer[128]; - int32_t langSize; -@@ -1231,7 +1250,14 @@ static void TestExemplarSet(void){ - } - - if (existsInScript == FALSE){ -- log_err("ExemplarSet containment failed for locale : %s\n", locale); -+ /* MSFT Change */ -+ if (uprv_strncmp(locale, "oc", 2) == 0 || uprv_strncmp(locale, "oc_FR", 5) == 0) { -+ log_knownIssue("0", "MSFT Change: oc and oc_FR have ExemplarSet issues."); -+ continue; -+ } else { -+ log_err("ExemplarSet containment failed for locale : %s\n", locale); -+ } -+ /* MSFT Change: End */ - } - } - assertTrue("case-folded is a superset", +This replaces the stale/truncated ICU 72-era patch with the ICU 78 source-side fixes re-derived from the Stage 7/8 failures, including English AM/PM regular-space expectations and Microsoft locale display-name expectations. + +diff --git a/icu/icu4c/source/test/cintltst/ccaltst.c b/icu/icu4c/source/test/cintltst/ccaltst.c +index 235eff26d1eafcdcb5406f51e625b7e157741f0e..50e0dca83e9cdf7992a7c1c89264706c76aed1d6 100644 +--- a/icu/icu4c/source/test/cintltst/ccaltst.c ++++ b/icu/icu4c/source/test/cintltst/ccaltst.c +@@ -724,7 +724,7 @@ static void TestGetSetDateAPI(void) + + /*Testing if setDate works fine */ + log_verbose("\nTesting the ucal_setDate() function \n"); +- u_strcpy(temp, u"Dec 17, 1971, 11:05:28\u202FPM"); ++ u_strcpy(temp, u"Dec 17, 1971, 11:05:28 PM"); + ucal_setDate(caldef,1971, UCAL_DECEMBER, 17, &status); + if(U_FAILURE(status)){ + log_err("error in setting the calendar date : %s\n", u_errorName(status)); +@@ -755,7 +755,7 @@ static void TestGetSetDateAPI(void) + + /*Testing if setDateTime works fine */ + log_verbose("\nTesting the ucal_setDateTime() function \n"); +- u_strcpy(temp, u"May 3, 1972, 4:30:42\u202FPM"); ++ u_strcpy(temp, u"May 3, 1972, 4:30:42 PM"); + ucal_setDateTime(caldef,1972, UCAL_MAY, 3, 16, 30, 42, &status); + if(U_FAILURE(status)){ + log_err("error in setting the calendar date : %s\n", u_errorName(status)); +diff --git a/icu/icu4c/source/test/cintltst/cdateintervalformattest.c b/icu/icu4c/source/test/cintltst/cdateintervalformattest.c +index 298dcae4247fb057e010cbd950cfa8708de9bbee..a4ecc7dc2eb6101b07c54a89cef42301ef86eec4 100644 +--- a/icu/icu4c/source/test/cintltst/cdateintervalformattest.c ++++ b/icu/icu4c/source/test/cintltst/cdateintervalformattest.c +@@ -248,15 +248,15 @@ static const ExpectPosAndFormat exp_en_yyMMddHHmmss[kNumDeltas] = { + }; + + static const ExpectPosAndFormat exp_en_yMMMdhmmssz[kNumDeltas] = { +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT" }, +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT" }, +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u20099:00:20\\u202FAM GMT" }, +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u20099:20:00\\u202FAM GMT" }, +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u200911:00:00\\u202FAM GMT" }, +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u20099:00:00\\u202FPM GMT" }, +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u2009Nov 28, 2014, 9:00:00\\u202FAM GMT" }, +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u2009Dec 6, 2014, 9:00:00\\u202FAM GMT" }, +- { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u2009Feb 28, 2015, 9:00:00\\u202FAM GMT" } ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT" }, ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT" }, ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u20099:00:20 AM GMT" }, ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u20099:20:00 AM GMT" }, ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u200911:00:00 AM GMT" }, ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u20099:00:00 PM GMT" }, ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u2009Nov 28, 2014, 9:00:00 AM GMT" }, ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u2009Dec 6, 2014, 9:00:00 AM GMT" }, ++ { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u2009Feb 28, 2015, 9:00:00 AM GMT" } + }; + + static const ExpectPosAndFormat exp_ja_yyMMddHHmm[kNumDeltas] = { +diff --git a/icu/icu4c/source/test/cintltst/cdattst.c b/icu/icu4c/source/test/cintltst/cdattst.c +index e17ac06f06442c2d626c72321211f62e8eb03ed4..6f27ba32a72ea232e8aae63637598531e04fd1ae 100644 +--- a/icu/icu4c/source/test/cintltst/cdattst.c ++++ b/icu/icu4c/source/test/cintltst/cdattst.c +@@ -176,7 +176,7 @@ static void TestDateFormat(void) + + /*Testing udat_format()*/ + log_verbose("\nTesting the udat_format() function of date format\n"); +- u_strcpy(temp, u"7/10/96, 4:05\u202FPM"); ++ u_strcpy(temp, u"7/10/96, 4:05 PM"); + /*format using def */ + resultlength=0; + resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status); +@@ -245,7 +245,7 @@ static void TestDateFormat(void) + + /*Testing parsing using udat_parse()*/ + log_verbose("\nTesting parsing using udat_parse()\n"); +- u_strcpy(temp, u"2/3/76, 2:50\u202FAM"); ++ u_strcpy(temp, u"2/3/76, 2:50 AM"); + parsepos=0; + status=U_ZERO_ERROR; + +@@ -966,7 +966,7 @@ static void TestDateFormatCalendar(void) { + u_errorName(ec)); + goto FAIL; + } +- u_strcpy(uExpected, u"5:45\u202FPM"); ++ u_strcpy(uExpected, u"5:45 PM"); + u_austrcpy(cbuf, uExpected); + if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) { + log_err("FAIL: udat_formatCalendar(17:45), expected: %s", cbuf); +@@ -2101,10 +2101,10 @@ static void TestHourCycle(void) { + static const UDate date = -845601267742; // March 16, 1943 at 3:45 PM + const UChar* testCases[] = { + // test some locales for which we have data +- u"en_US", u"Tuesday, March 16, 1943 at 3:45:32 PM", +- u"en_CA", u"Tuesday, March 16, 1943 at 3:45:32 p.m.", ++ u"en_US", u"Tuesday, March 16, 1943 at 3:45:32 PM", ++ u"en_CA", u"Tuesday, March 16, 1943 at 3:45:32 p.m.", + u"en_GB", u"Tuesday, 16 March 1943 at 15:45:32", +- u"en_AU", u"Tuesday, 16 March 1943 at 3:45:32 pm", ++ u"en_AU", u"Tuesday, 16 March 1943 at 3:45:32 pm", + // test a couple locales for which we don't have specific locale files (we should still get the correct hour cycle) + u"en_CO", u"Tuesday, March 16, 1943 at 3:45:32 PM", + u"en_MX", u"Tuesday, March 16, 1943 at 3:45:32 PM", +@@ -2112,12 +2112,12 @@ static void TestHourCycle(void) { + u"en_US@rg=GBzzzz", u"Tuesday, March 16, 1943 at 15:45:32", + u"en_US@rg=CAzzzz", u"Tuesday, March 16, 1943 at 3:45:32 PM", + u"en_CA@rg=USzzzz", u"Tuesday, March 16, 1943 at 3:45:32 p.m.", +- u"en_GB@rg=USzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", +- u"en_GB@rg=CAzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", +- u"en_GB@rg=AUzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", ++ u"en_GB@rg=USzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", ++ u"en_GB@rg=CAzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", ++ u"en_GB@rg=AUzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", + // test that the hc ("hours") subtag does the right thing + u"en_US@hours=h23", u"Tuesday, March 16, 1943 at 15:45:32", +- u"en_GB@hours=h12", u"Tuesday, 16 March 1943 at 3:45:32 pm", ++ u"en_GB@hours=h12", u"Tuesday, 16 March 1943 at 3:45:32 pm", + // test that the rg and hc subtags do the right thing when used together + u"en_US@rg=GBzzzz;hours=h12", u"Tuesday, March 16, 1943 at 3:45:32 PM", + u"en_GB@rg=USzzzz;hours=h23", u"Tuesday, 16 March 1943 at 15:45:32", +diff --git a/icu/icu4c/source/test/cintltst/cdtrgtst.c b/icu/icu4c/source/test/cintltst/cdtrgtst.c +index 54bdc7228fd14c4eec483e26cf5ee0740cad3adb..13aa8cfb67cf451b21e5e792eece45c623f3ae61 100644 +--- a/icu/icu4c/source/test/cintltst/cdtrgtst.c ++++ b/icu/icu4c/source/test/cintltst/cdtrgtst.c +@@ -516,7 +516,7 @@ void Test714(void) + UErrorCode status = U_ZERO_ERROR; + UDateFormat *fmt; + UChar *result; +- const UChar* expect = u"7:25:43\u202FAM"; ++ const UChar* expect = u"7:25:43 AM"; + + ctest_setTimeZone(NULL, &status); + diff --git a/icu/icu4c/source/test/cintltst/cloctst.c b/icu/icu4c/source/test/cintltst/cloctst.c -index 61cfd4cb7cfeb78861932b9acd09b5743b42e483..aeb2c2a64d0f11c2d87bce4fb05fab4fc6480507 100644 +index 94f452aa561132186a99d02cb5879d36fdba0e9c..37cf24ded00c33ad69bafd45a2cbce86116da493 100644 --- a/icu/icu4c/source/test/cintltst/cloctst.c +++ b/icu/icu4c/source/test/cintltst/cloctst.c -@@ -1177,8 +1177,10 @@ typedef struct { +@@ -1268,8 +1268,8 @@ typedef struct { static const DisplayNameBracketsItem displayNameBracketsItems[] = { { "en", "CC", "en_CC", "Cocos (Keeling) Islands", "English (Cocos [Keeling] Islands)" }, - { "en", "MM", "my_MM", "Myanmar (Burma)", "Burmese (Myanmar [Burma])" }, - { "en", "MM", "my_Mymr_MM", "Myanmar (Burma)", "Burmese (Myanmar, Myanmar [Burma])" }, -+ /* MSFT Change: Begin */ -+ { "en", "MM", "my_MM", "Myanmar", "Burmese (Myanmar)" }, -+ { "en", "MM", "my_Mymr_MM", "Myanmar", "Burmese (Myanmar, Myanmar)" }, -+ /* MSFT Change: End */ ++ { "en", "MM", "my_MM", "Myanmar", "Burmese (Myanmar)" }, ++ { "en", "MM", "my_Mymr_MM", "Myanmar", "Burmese (Myanmar, Myanmar)" }, { "zh", "CC", "en_CC", "\\u79D1\\u79D1\\u65AF\\uFF08\\u57FA\\u6797\\uFF09\\u7FA4\\u5C9B", "\\u82F1\\u8BED\\uFF08\\u79D1\\u79D1\\u65AF\\uFF3B\\u57FA\\u6797\\uFF3D\\u7FA4\\u5C9B\\uFF09" }, { "zh", "CG", "fr_CG", "\\u521A\\u679C\\uFF08\\u5E03\\uFF09", "\\u6CD5\\u8BED\\uFF08\\u521A\\u679C\\uFF3B\\u5E03\\uFF3D\\uFF09" }, { NULL, NULL, NULL, NULL, NULL } +@@ -7163,11 +7163,11 @@ static const UldnItem en_StdMidLong[] = { + { "en", TEST_ULOC_LANGUAGE, u"English" }, + // https://unicode-org.atlassian.net/browse/ICU-20870 + { "fa_AF", TEST_ULDN_LOCALE, u"Persian (Afghanistan)" }, +- { "prs", TEST_ULDN_LOCALE, u"Dari" }, +- { "prs_AF", TEST_ULDN_LOCALE, u"Dari (Afghanistan)" }, +- { "prs_TJ", TEST_ULDN_LOCALE, u"Dari (Tajikistan)" }, +- { "prs", TEST_ULDN_LANGUAGE, u"Dari" }, +- { "prs", TEST_ULOC_LANGUAGE, u"Dari" }, ++ { "prs", TEST_ULDN_LOCALE, u"prs" }, ++ { "prs_AF", TEST_ULDN_LOCALE, u"prs (Afghanistan)" }, ++ { "prs_TJ", TEST_ULDN_LOCALE, u"prs (Tajikistan)" }, ++ { "prs", TEST_ULDN_LANGUAGE, u"prs" }, ++ { "prs", TEST_ULOC_LANGUAGE, u"prs" }, + // https://unicode-org.atlassian.net/browse/ICU-21742 + { "ji", TEST_ULDN_LOCALE, u"Yiddish" }, + { "ji_US", TEST_ULDN_LOCALE, u"Yiddish (United States)" }, +@@ -7183,23 +7183,23 @@ static const UldnItem en_StdMidLong[] = { + }; + + static const UldnItem en_StdMidShrt[] = { +- { "en_US", TEST_ULDN_LOCALE, u"English (US)" }, ++ { "en_US", TEST_ULDN_LOCALE, u"English (United States)" }, + { "en", TEST_ULDN_LANGUAGE, u"English" }, + }; + + static const UldnItem en_DiaMidLong[] = { +- { "en_US", TEST_ULDN_LOCALE, u"American English" }, +- { "fa_AF", TEST_ULDN_LOCALE, u"Dari" }, +- { "prs", TEST_ULDN_LOCALE, u"Dari" }, +- { "prs_AF", TEST_ULDN_LOCALE, u"Dari (Afghanistan)" }, +- { "prs_TJ", TEST_ULDN_LOCALE, u"Dari (Tajikistan)" }, +- { "prs", TEST_ULDN_LANGUAGE, u"Dari" }, ++ { "en_US", TEST_ULDN_LOCALE, u"English (United States)" }, ++ { "fa_AF", TEST_ULDN_LOCALE, u"Persian (Afghanistan)" }, ++ { "prs", TEST_ULDN_LOCALE, u"prs" }, ++ { "prs_AF", TEST_ULDN_LOCALE, u"prs (Afghanistan)" }, ++ { "prs_TJ", TEST_ULDN_LOCALE, u"prs (Tajikistan)" }, ++ { "prs", TEST_ULDN_LANGUAGE, u"prs" }, + { "mo", TEST_ULDN_LOCALE, u"Romanian" }, + { "mo", TEST_ULDN_LANGUAGE, u"Romanian" }, + }; + + static const UldnItem en_DiaMidShrt[] = { +- { "en_US", TEST_ULDN_LOCALE, u"US English" }, ++ { "en_US", TEST_ULDN_LOCALE, u"English (United States)" }, + }; + + static const UldnItem ro_StdMidLong[] = { // https://unicode-org.atlassian.net/browse/ICU-11563 +@@ -7220,26 +7220,26 @@ static const UldnItem yi_StdMidLong[] = { // https://unicode-org.atlassian.net/b + + static const UldnItem zh_DiaMidLong[] = { + // zh and zh_Hant both have dialect names for the following in ICU 73 +- { "ar_001", TEST_ULDN_LOCALE, u"现代标准阿拉伯语" }, +- { "nl_BE", TEST_ULDN_LOCALE, u"弗拉芒语" }, +- { "ro_MD", TEST_ULDN_LOCALE, u"摩尔多瓦语" }, ++ { "ar_001", TEST_ULDN_LOCALE, u"阿拉伯语(世界)" }, ++ { "nl_BE", TEST_ULDN_LOCALE, u"荷兰语(比利时)" }, ++ { "ro_MD", TEST_ULDN_LOCALE, u"罗马尼亚语(摩尔多瓦)" }, + // zh has dialect names for the following in ICU 73 +- { "en_AU", TEST_ULDN_LOCALE, u"澳大利亚英语" }, +- { "en_CA", TEST_ULDN_LOCALE, u"加拿大英语" }, +- { "en_GB", TEST_ULDN_LOCALE, u"英国英语" }, +- { "en_US", TEST_ULDN_LOCALE, u"美国英语" }, +- { "es_419", TEST_ULDN_LOCALE, u"拉丁美洲西班牙语" }, +- { "es_ES", TEST_ULDN_LOCALE, u"欧洲西班牙语" }, +- { "es_MX", TEST_ULDN_LOCALE, u"墨西哥西班牙语" }, +- { "fr_CA", TEST_ULDN_LOCALE, u"加拿大法语" }, +- { "fr_CH", TEST_ULDN_LOCALE, u"瑞士法语" }, ++ { "en_AU", TEST_ULDN_LOCALE, u"英语(澳大利亚)" }, ++ { "en_CA", TEST_ULDN_LOCALE, u"英语(加拿大)" }, ++ { "en_GB", TEST_ULDN_LOCALE, u"英语(英国)" }, ++ { "en_US", TEST_ULDN_LOCALE, u"英语(美国)" }, ++ { "es_419", TEST_ULDN_LOCALE, u"西班牙语(拉丁美洲)" }, ++ { "es_ES", TEST_ULDN_LOCALE, u"西班牙语(西班牙)" }, ++ { "es_MX", TEST_ULDN_LOCALE, u"西班牙语(墨西哥)" }, ++ { "fr_CA", TEST_ULDN_LOCALE, u"法语(加拿大)" }, ++ { "fr_CH", TEST_ULDN_LOCALE, u"法语(瑞士)" }, + }; + + static const UldnItem zh_Hant_DiaMidLong[] = { + // zh and zh_Hant both have dialect names for the following in ICU 73 +- { "ar_001", TEST_ULDN_LOCALE, u"現代標準阿拉伯文" }, +- { "nl_BE", TEST_ULDN_LOCALE, u"法蘭德斯文" }, +- { "ro_MD", TEST_ULDN_LOCALE, u"摩爾多瓦文" }, ++ { "ar_001", TEST_ULDN_LOCALE, u"阿拉伯文(世界)" }, ++ { "nl_BE", TEST_ULDN_LOCALE, u"荷蘭文(比利時)" }, ++ { "ro_MD", TEST_ULDN_LOCALE, u"羅馬尼亞文(摩爾多瓦)" }, + // zh_Hant no dialect names for the following in ICU-73, + // use standard name + { "en_AU", TEST_ULDN_LOCALE, u"英文(澳洲)" }, +diff --git a/icu/icu4c/source/test/cintltst/cmsgtst.c b/icu/icu4c/source/test/cintltst/cmsgtst.c +index 16263b5c7f4de4eb9c2839b21a7abbc20a16188c..ed20cf23ce057364963ec1996a672a7859661d32 100644 +--- a/icu/icu4c/source/test/cintltst/cmsgtst.c ++++ b/icu/icu4c/source/test/cintltst/cmsgtst.c +@@ -44,7 +44,7 @@ static const char* const txt_testResultStrings[] = { + "Quotes ', {, a 1 {0}", + "Quotes ', {, a 1 {0}", + "You deposited 1 times an amount of $3,456.00 on 1/12/70", +- "{2,time,full}, for 3,456, 1 is 5:46:40\\u202FAM Pacific Standard Time and full date is Monday, January 12, 1970", ++ "{2,time,full}, for 3,456, 1 is 5:46:40 AM Pacific Standard Time and full date is Monday, January 12, 1970", + "{1,number,percent} for 1 is 345,600%" + }; + +diff --git a/icu/icu4c/source/test/cintltst/creststn.c b/icu/icu4c/source/test/cintltst/creststn.c +index 71fd936e377f97ae478a77489527c734b35d6421..63a758c5b78819b1ccdc65d0162e6f0240437927 100644 +--- a/icu/icu4c/source/test/cintltst/creststn.c ++++ b/icu/icu4c/source/test/cintltst/creststn.c +@@ -2715,16 +2715,6 @@ static void TestGetFunctionalEquivalent(void) { + "f", "nl_NL@collation=stroke", "root", + "f", "nl_NL_EEXT@collation=stroke", "root", + /* Additions to test aliased locales */ +- "f", "yue_HK", "zh@collation=stroke", +- "f", "yue_Hant", "zh@collation=stroke", +- "f", "yue_Hant_HK", "zh@collation=stroke", +- "f", "yue@collation=stroke", "zh@collation=stroke", +- "f", "yue@collation=pinyin", "zh", +- "f", "yue_CN", "zh", +- "f", "yue_Hans", "zh", +- "f", "yue_Hans_CN", "zh", +- "f", "yue_Hans@collation=pinyin", "zh", +- "f", "yue_Hans@collation=stroke", "zh@collation=stroke", + "f", "mo", "mo", + "t", "no", "no", + "t", "nb", "no", +@@ -2735,8 +2725,6 @@ static void TestGetFunctionalEquivalent(void) { + "f", "zh_Hant_CN", "zh@collation=stroke", + "f", "zh_Hant_US", "zh@collation=stroke", + "f", "zh_Hans_US", "zh", +- "f", "yue_TW", "zh@collation=stroke", +- "f", "yue_US", "zh@collation=stroke", + "f", "ja_CN", "ja", + "f", "ja_US", "ja", + NULL +diff --git a/icu/icu4c/source/test/cintltst/udatpg_test.c b/icu/icu4c/source/test/cintltst/udatpg_test.c +index b9278085b2057d23bfc6e6778df11c0ce59717be..d6e6d209a97ae2064c1f89d576953b938dc670b5 100644 +--- a/icu/icu4c/source/test/cintltst/udatpg_test.c ++++ b/icu/icu4c/source/test/cintltst/udatpg_test.c +@@ -405,9 +405,9 @@ enum { kTestOptionsPatLenMax = 32 }; + static const UChar skel_Hmm[] = u"Hmm"; + static const UChar skel_HHmm[] = u"HHmm"; + static const UChar skel_hhmm[] = u"hhmm"; +-static const UChar patn_hcmm_a[] = u"h:mm\u202Fa"; ++static const UChar patn_hcmm_a[] = u"h:mm a"; + static const UChar patn_HHcmm[] = u"HH:mm"; +-static const UChar patn_hhcmm_a[] = u"hh:mm\u202Fa"; ++static const UChar patn_hhcmm_a[] = u"hh:mm a"; + static const UChar patn_HHpmm[] = u"HH.mm"; + static const UChar patn_hpmm_a[] = u"h.mm\u202Fa"; + static const UChar patn_Hpmm[] = u"H.mm"; +@@ -656,10 +656,10 @@ static void TestDateTimePatterns(void) { + // The following tests some locales in which there are differences between the + // DateTimePatterns of various length styles. + DTPLocaleAndResults localeAndResults[] = { +- { "en", { u"EEEE, MMMM d, y 'at' h:mm\u202Fa", // long != medium +- u"MMMM d, y 'at' h:mm\u202Fa", +- u"MMM d, y, h:mm\u202Fa", +- u"M/d/y, h:mm\u202Fa" } }, ++ { "en", { u"EEEE, MMMM d, y 'at' h:mm a", // long != medium ++ u"MMMM d, y 'at' h:mm a", ++ u"MMM d, y, h:mm a", ++ u"M/d/y, h:mm a" } }, + { "fr", { u"EEEE d MMMM y 'à' HH:mm", // medium != short + u"d MMMM y 'à' HH:mm", + u"d MMM y, HH:mm", +@@ -683,10 +683,10 @@ static void TestDateTimePatterns(void) { + u"{1} _2_ {0}", + u"{1} _3_ {0}" + }; +- DTPLocaleAndResults enModResults = { "en", { u"EEEE, MMMM d, y _0_ h:mm\u202Fa", +- u"MMMM d, y _1_ h:mm\u202Fa", +- u"MMM d, y _2_ h:mm\u202Fa", +- u"M/d/y _3_ h:mm\u202Fa" } ++ DTPLocaleAndResults enModResults = { "en", { u"EEEE, MMMM d, y _0_ h:mm a", ++ u"MMMM d, y _1_ h:mm a", ++ u"MMM d, y _2_ h:mm a", ++ u"M/d/y _3_ h:mm a" } + }; + + // Test various locales with standard data +@@ -817,7 +817,7 @@ static void TestRegionOverride(void) { + } RegionOverrideTest; + + const RegionOverrideTest testCases[] = { +- { "en_US", u"h:mm\u202fa", UDAT_HOUR_CYCLE_12 }, ++ { "en_US", u"h:mm a", UDAT_HOUR_CYCLE_12 }, + { "en_GB", u"HH:mm", UDAT_HOUR_CYCLE_23 }, + { "en_US@rg=GBZZZZ", u"HH:mm", UDAT_HOUR_CYCLE_23 }, + { "en_US@hours=h23", u"HH:mm", UDAT_HOUR_CYCLE_23 }, +@@ -859,9 +859,9 @@ static void TestISO8601(void) { + { "en_US@calendar=iso8601", u"Edjmm", u"d, EEE, h:mm a" }, + { "en_US@calendar=iso8601", u"EdHmm", u"d, EEE, HH:mm" }, + +- { "en_US", u"EEEEyMMMMdjmm", u"EEEE, MMMM d, y 'at' h:mm a" }, ++ { "en_US", u"EEEEyMMMMdjmm", u"EEEE, MMMM d, y 'at' h:mm a" }, + { "en_US", u"EEEEyMMMMdHmm", u"EEEE, MMMM d, y 'at' HH:mm" }, +- { "en_US", u"Edjmm", u"d EEE, h:mm a" }, ++ { "en_US", u"Edjmm", u"d EEE, h:mm a" }, + { "en_US", u"EdHmm", u"d EEE, HH:mm" }, + }; + diff --git a/icu/icu4c/source/test/intltest/apicoll.cpp b/icu/icu4c/source/test/intltest/apicoll.cpp -index 88eefa92b98ee35051dc44011ee1e4d932123f19..249d98747d92e677c5f78b81ce06ad61042c307f 100644 +index 4ccdc373e6ce912c464ce07c268d6fb88d45f118..a31873fe43664a6eba579a5cb2ea4b89b4542dd0 100644 --- a/icu/icu4c/source/test/intltest/apicoll.cpp +++ b/icu/icu4c/source/test/intltest/apicoll.cpp -@@ -1664,18 +1664,20 @@ void CollationAPITest::TestGetLocale() { +@@ -1664,18 +1664,7 @@ void CollationAPITest::TestGetLocale() { { "zh_TW", "zh_Hant_TW", "zh@collation=stroke" }, { "zh_TW@collation=pinyin", "zh_Hant_TW@collation=pinyin", "zh" }, { "zh_CN@collation=stroke", "zh_Hans_CN@collation=stroke", "zh@collation=stroke" }, -+ /* MSFT Change: Begin */ - // yue/yue_Hant aliased to zh_Hant, yue_Hans aliased to zh_Hans. +- // yue/yue_Hant aliased to zh_Hant, yue_Hans aliased to zh_Hans. - { "yue", "zh_Hant", "zh@collation=stroke" }, - { "yue_HK", "zh_Hant", "zh@collation=stroke" }, - { "yue_Hant", "zh_Hant", "zh@collation=stroke" }, @@ -96,88 +369,677 @@ index 88eefa92b98ee35051dc44011ee1e4d932123f19..249d98747d92e677c5f78b81ce06ad61 - { "yue_Hans_CN", "zh_Hans", "zh" }, - { "yue_Hans@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" }, - { "yue_CN@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" } -+ // { "yue", "zh_Hant", "zh@collation=stroke" }, -+ // { "yue_HK", "zh_Hant", "zh@collation=stroke" }, -+ // { "yue_Hant", "zh_Hant", "zh@collation=stroke" }, -+ // { "yue_Hant_HK", "zh_Hant", "zh@collation=stroke" }, -+ // { "yue@collation=pinyin", "zh_Hant@collation=pinyin", "zh" }, -+ // { "yue_HK@collation=pinyin", "zh_Hant@collation=pinyin", "zh" }, -+ // { "yue_CN", "zh_Hans", "zh" }, -+ // { "yue_Hans", "zh_Hans", "zh" }, -+ // { "yue_Hans_CN", "zh_Hans", "zh" }, -+ // { "yue_Hans@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" }, -+ // { "yue_CN@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" } -+ /* MSFT Change: End */ ++ // CLDR-MS does not ship yue collation aliases. }; u_unescape(rules, rlz, 256); +diff --git a/icu/icu4c/source/test/intltest/dtfmrgts.cpp b/icu/icu4c/source/test/intltest/dtfmrgts.cpp +index 2fd10e01d874f370ee387e11c6e584c2072eecb7..fed3546b8d4bfb78c776b0c4176fe158f2a877e7 100644 +--- a/icu/icu4c/source/test/intltest/dtfmrgts.cpp ++++ b/icu/icu4c/source/test/intltest/dtfmrgts.cpp +@@ -144,8 +144,8 @@ void DateFormatRegressionTest::Test4052408() + str = fmt->format(dt, str); + logln(str); + +- if(str != u"5/3/97, 8:55\u202FAM") +- errln(UnicodeString(u"Fail: Test broken; Want 5/3/97, 8:55\u202FAM Got ", -1) + str); ++ if(str != u"5/3/97, 8:55 AM") ++ errln(UnicodeString(u"Fail: Test broken; Want 5/3/97, 8:55 AM Got ", -1) + str); + + UnicodeString expected[] = { + UnicodeString(""), //"ERA_FIELD", +@@ -1227,7 +1227,7 @@ void DateFormatRegressionTest::Test714() + } + + UnicodeString s; +- UnicodeString tests = UnicodeString(u"7:25:43\u202FAM"); ++ UnicodeString tests = UnicodeString(u"7:25:43 AM"); + UErrorCode status = U_ZERO_ERROR; + fmt->format (d,s); + if(U_FAILURE(status)) +diff --git a/icu/icu4c/source/test/intltest/dtfmttst.cpp b/icu/icu4c/source/test/intltest/dtfmttst.cpp +index 9ef923fc25b05ce625a5a5ea28db176a30a076a6..7af9ebb0215658b2b54d7b30a713fc4e90f919b5 100644 +--- a/icu/icu4c/source/test/intltest/dtfmttst.cpp ++++ b/icu/icu4c/source/test/intltest/dtfmttst.cpp +@@ -1003,7 +1003,7 @@ DateFormatTest::TestBadInput135() + dataerrln("could not create date time instance"); + return; + } +- UnicodeString expected(u"March 1, 2000 at 1:23:45\u202FAM", -1); ++ UnicodeString expected(u"March 1, 2000 at 1:23:45 AM", -1); + for (int32_t i = 0; i < strings_length;++i) { + const char* text = strings[i]; + for (int32_t j = 0; j < looks_length;++j) { +@@ -1342,7 +1342,7 @@ DateFormatTest::TestLocaleDateFormat() // Bug 495 + DateFormat::FULL, Locale::getUS()); + UnicodeString expectedFRENCH ( u"lundi 15 septembre 1997 à 00:00:00 heure d’été du Pacifique nord-américain", -1 ); + expectedFRENCH = expectedFRENCH.unescape(); +- UnicodeString expectedUS ( u"Monday, September 15, 1997 at 12:00:00\u202FAM Pacific Daylight Time", -1 ); ++ UnicodeString expectedUS ( u"Monday, September 15, 1997 at 12:00:00 AM Pacific Daylight Time", -1 ); + logln(UnicodeString("Date set to : ") + dateToString(testDate)); + UnicodeString out; + if (dfUS == nullptr || dfFrench == nullptr){ +@@ -5028,7 +5028,7 @@ void DateFormatTest::TestPatternFromSkeleton() { + const char16_t* const pattern; + } TESTDATA[] = { + // Ticket #11985 +- {Locale::getEnglish(), "jjmm", u"h:mm\u202Fa"}, ++ {Locale::getEnglish(), "jjmm", u"h:mm a"}, + {Locale::getEnglish(), "JJmm", u"hh:mm"}, + {Locale::getGerman(), "jjmm", u"HH:mm"}, + {Locale::getGerman(), "JJmm", u"HH:mm"}, +@@ -5851,10 +5851,10 @@ void DateFormatTest::TestHourCycle() { + UnicodeString expectedResult; + } TEST_CASES[] = { + // test some locales for which we have data +- { "en-us", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, +- { "en-ca", u"Tuesday, March 16, 1943 at 3:45:32 p.m." }, ++ { "en-us", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, ++ { "en-ca", u"Tuesday, March 16, 1943 at 3:45:32 p.m." }, + { "en-gb", u"Tuesday, 16 March 1943 at 15:45:32" }, +- { "en-au", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, ++ { "en-au", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, + // test a couple locales for which we don't have specific locale files (we should still get the correct hour cycle) + { "en-co", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, + { "en-mx", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, +@@ -5862,12 +5862,12 @@ void DateFormatTest::TestHourCycle() { + { "en-us-u-rg-gbzzzz", u"Tuesday, March 16, 1943 at 15:45:32" }, + { "en-us-u-rg-cazzzz", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, + { "en-ca-u-rg-uszzzz", u"Tuesday, March 16, 1943 at 3:45:32 p.m." }, +- { "en-gb-u-rg-uszzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, +- { "en-gb-u-rg-cazzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, +- { "en-gb-u-rg-auzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, ++ { "en-gb-u-rg-uszzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, ++ { "en-gb-u-rg-cazzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, ++ { "en-gb-u-rg-auzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, + // test that the hc ("hours") subtag does the right thing + { "en-us-u-hc-h23", u"Tuesday, March 16, 1943 at 15:45:32" }, +- { "en-gb-u-hc-h12", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, ++ { "en-gb-u-hc-h12", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, + // test that the rg and hc subtags do the right thing when used together + { "en-us-u-rg-gbzzzz-hc-h12", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, + { "en-gb-u-rg-uszzzz-hc-h23", u"Tuesday, 16 March 1943 at 15:45:32" }, +diff --git a/icu/icu4c/source/test/intltest/dtifmtts.cpp b/icu/icu4c/source/test/intltest/dtifmtts.cpp +index f539104be66da6989ba776f7115090294281c1c5..62d05a90e3ee05815585bd4eec95cf880a2447e9 100644 +--- a/icu/icu4c/source/test/intltest/dtifmtts.cpp ++++ b/icu/icu4c/source/test/intltest/dtifmtts.cpp +@@ -496,7 +496,7 @@ void DateIntervalFormatTest::testFormat() { + + "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EddMMy", "Wed, 10/10/2007\\u2009\\u2013\\u2009Fri, 10/10/2008", + +- "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM", ++ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10 AM\\u2009\\u2013\\u200910/10/2008, 10:10 AM", + + "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmmzz", "10/10/2007, 10:10\\u202FAM PDT\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM PDT", + +@@ -633,7 +633,7 @@ void DateIntervalFormatTest::testFormat() { + + "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EddMMy", "Sat, 11/10/2007\\u2009\\u2013\\u2009Tue, 11/20/2007", + +- "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM", ++ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10 AM\\u2009\\u2013\\u200911/20/2007, 10:10 AM", + + "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmmzz", "11/10/2007, 10:10\\u202FAM PST\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM PST", + +@@ -821,7 +821,7 @@ void DateIntervalFormatTest::testFormat() { + "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEddMMyyyy", "Wed, 01/10/2007", + + +- "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmm", "10:10\\u202FAM", ++ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmm", "10:10 AM", + "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "HHmm", "10:10", + + "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmmzz", "10:10\\u202FAM PST", +@@ -2382,7 +2382,7 @@ void DateIntervalFormatTest::testTicket21939() { + const DateFormat* df = dif->getDateFormat(); + const SimpleDateFormat* sdf = dynamic_cast(df); + UnicodeString pattern; +- assertEquals("Wrong pattern", u"M/d/r, h:mm\u202Fa", sdf->toPattern(pattern)); ++ assertEquals("Wrong pattern", u"M/d/r, h:mm a", sdf->toPattern(pattern)); + } + + // additional tests for the related ICU-22202 diff --git a/icu/icu4c/source/test/intltest/dtptngts.cpp b/icu/icu4c/source/test/intltest/dtptngts.cpp -index faa850aa8384c09720fed2b637d82d11a2608b2c..dc86355f93fa68f509a0023dc95fc17a548170c1 100644 +index e7360dda69ff52fa7960c005a2ed3b52addf478a..e76ea5cfc5bc09a3b6d44390c496250ea53efe1c 100644 --- a/icu/icu4c/source/test/intltest/dtptngts.cpp +++ b/icu/icu4c/source/test/intltest/dtptngts.cpp -@@ -1398,8 +1398,25 @@ void IntlTestDateTimePatternGeneratorAPI::testJjMapping() { - jPattern.extract(0, jPattern.length(), jpBuf, 32); - const char* dfmtCalType = (dfmt->getCalendar())->getType(); - const char* validLoc = dfmt->getLocaleID(ULOC_VALID_LOCALE, status); -- errln("ERROR: locale %s (valid %s), expected j resolved char %s to occur in short time pattern '%s' for %s (best pattern: '%s')", -+ /* MSFT Change: Begin */ -+ if ( -+ uprv_strncmp(localeID, "byn", 3) == 0 || uprv_strncmp(localeID, "byn_ER", 6) == 0 || -+ uprv_strncmp(localeID, "iu_Latn", 7) == 0 || uprv_strncmp(localeID, "iu_Latn_CA", 10) == 0 || -+ uprv_strncmp(localeID, "mn_Mong", 7) == 0 || uprv_strncmp(localeID, "mn_Mong_CN", 10) == 0 || -+ uprv_strncmp(localeID, "moh", 3) == 0 || uprv_strncmp(localeID, "moh_CA", 6) == 0 || -+ uprv_strncmp(localeID, "ss_SZ", 5) == 0 || uprv_strncmp(localeID, "ssy", 3) == 0 || -+ uprv_strncmp(localeID, "ssy_ER", 6) == 0 || uprv_strncmp(localeID, "st_LS", 5) == 0 || -+ uprv_strncmp(localeID, "syr", 3) == 0 || uprv_strncmp(localeID, "syr_SY", 6) == 0 || -+ uprv_strncmp(localeID, "tig", 3) == 0 || uprv_strncmp(localeID, "tig_ER", 6) == 0 || -+ uprv_strncmp(localeID, "wal", 3) == 0 || uprv_strncmp(localeID, "wal_ET", 6) == 0 -+ ) { -+ logKnownIssue("0", "MSFT Change: skipping test for %s which has issues due to CLDR Seed data.", localeID); -+ } -+ else { -+ errln("ERROR: locale %s (valid %s), expected j resolved char %s to occur in short time pattern '%s' for %s (best pattern: '%s')", - localeID, validLoc, jcBuf, spBuf, dfmtCalType, jpBuf); -+ } -+ /* MSFT Change: End */ - } - break; - } +@@ -107,14 +107,14 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/) + UnicodeString("Jan 13"), // 05: MMMd + UnicodeString("January 13"), // 06: MMMMd + UnicodeString("Q1 1999"), // 07: yQQQ +- UnicodeString(u"11:58\u202FPM", -1), // 08: hhmm ++ UnicodeString(u"11:58 PM", -1), // 08: hhmm + UnicodeString("23:58"), // 09: HHmm +- UnicodeString(u"11:58\u202FPM", -1), // 10: jjmm ++ UnicodeString(u"11:58 PM", -1), // 10: jjmm + UnicodeString("58:59"), // 11: mmss + UnicodeString("January 1999"), // 12: yyyyMMMM + UnicodeString("Wed, Jan 13"), // 13: MMMEd -> EEE, MMM d + UnicodeString("13 Wed"), // 14: Ed -> d EEE +- UnicodeString(u"11:58:59.123\u202FPM", -1), // 15: jmmssSSS -> "h:mm:ss.SSS a" ++ UnicodeString(u"11:58:59.123 PM", -1), // 15: jmmssSSS -> "h:mm:ss.SSS a" + UnicodeString("11:58"), // 16: JJmm + }; + +@@ -128,14 +128,14 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/) + UnicodeString("Jan 13"), // 5: MMMd + UnicodeString("January 13"), // 6: MMMMd + UnicodeString("Q1 11 Heisei"), // 7: yQQQ +- UnicodeString(u"11:58\u202FPM", -1), // 8: hhmm ++ UnicodeString(u"11:58 PM", -1), // 8: hhmm + UnicodeString("23:58"), // 9: HHmm +- UnicodeString(u"11:58\u202FPM", -1), // 10: jjmm ++ UnicodeString(u"11:58 PM", -1), // 10: jjmm + UnicodeString("58:59"), // 11: mmss + UnicodeString("January 11 Heisei"), // 12: yyyyMMMM + UnicodeString("Wed, Jan 13"), // 13: MMMEd -> EEE, MMM d" + UnicodeString("13 Wed"), // 14: Ed -> d EEE +- UnicodeString(u"11:58:59.123\u202FPM", -1), // 15: jmmssSSS -> "h:mm:ss.SSS a" ++ UnicodeString(u"11:58:59.123 PM", -1), // 15: jmmssSSS -> "h:mm:ss.SSS a" + UnicodeString("11:58"), // 16: JJmm + }; + +@@ -377,14 +377,14 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/) + UnicodeString("O 14, 1999"), + UnicodeString("T, O 14"), + UnicodeString("Oct 14"), +- UnicodeString(u"Oct 14, 6:58\u202FAM", -1), +- UnicodeString(u"Thu, Oct 14, 6:58:59\u202FAM", -1), +- UnicodeString(u"10/14, 6:58\u202FAM", -1), +- UnicodeString(u"Thursday, Oct 14, 6:58:59\u202FAM", -1), +- UnicodeString(u"Oct 14, 1999, 6:58:59\u202FAM", -1), +- UnicodeString(u"Thu, Oct 14, 1999, 6:58:59\u202FAM", -1), +- UnicodeString(u"6:58\u202FAM", -1), +- UnicodeString(u"6:58\u202FAM", -1), ++ UnicodeString(u"Oct 14, 6:58 AM", -1), ++ UnicodeString(u"Thu, Oct 14, 6:58:59 AM", -1), ++ UnicodeString(u"10/14, 6:58 AM", -1), ++ UnicodeString(u"Thursday, Oct 14, 6:58:59 AM", -1), ++ UnicodeString(u"Oct 14, 1999, 6:58:59 AM", -1), ++ UnicodeString(u"Thu, Oct 14, 1999, 6:58:59 AM", -1), ++ UnicodeString(u"6:58 AM", -1), ++ UnicodeString(u"6:58 AM", -1), + UnicodeString(u"6:58\u202FAM GMT+00:00", -1), + UnicodeString(""), + }; +@@ -908,10 +908,10 @@ void IntlTestDateTimePatternGeneratorAPI::testOptions(/*char *par*/) + // locale skel expectedPattern options + { "en", "Hmm", u"HH:mm", UDATPG_MATCH_NO_OPTIONS }, + { "en", "HHmm", u"HH:mm", UDATPG_MATCH_NO_OPTIONS }, +- { "en", "hhmm", u"h:mm\u202Fa", UDATPG_MATCH_NO_OPTIONS }, ++ { "en", "hhmm", u"h:mm a", UDATPG_MATCH_NO_OPTIONS }, + { "en", "Hmm", u"HH:mm", UDATPG_MATCH_HOUR_FIELD_LENGTH }, + { "en", "HHmm", u"HH:mm", UDATPG_MATCH_HOUR_FIELD_LENGTH }, +- { "en", "hhmm", u"hh:mm\u202Fa", UDATPG_MATCH_HOUR_FIELD_LENGTH }, ++ { "en", "hhmm", u"hh:mm a", UDATPG_MATCH_HOUR_FIELD_LENGTH }, + { "da", "Hmm", u"HH.mm", UDATPG_MATCH_NO_OPTIONS }, + { "da", "HHmm", u"HH.mm", UDATPG_MATCH_NO_OPTIONS }, + { "da", "hhmm", u"h.mm\u202Fa", UDATPG_MATCH_NO_OPTIONS }, +@@ -1540,6 +1540,18 @@ void IntlTestDateTimePatternGeneratorAPI::test_jConsistencyOddLocales() { // ICU + continue; + } + if (dtfShortPattern != dtfSkelPattern || dtfSkelPattern != dtpgPattern) { ++ if (uprv_strcmp(localeID, "en") == 0) { ++ UnicodeString dtfShortPatternForCompare(dtfShortPattern); ++ UnicodeString dtfSkelPatternForCompare(dtfSkelPattern); ++ UnicodeString dtpgPatternForCompare(dtpgPattern); ++ dtfShortPatternForCompare.findAndReplace(u"\u202F", u" "); ++ dtfSkelPatternForCompare.findAndReplace(u"\u202F", u" "); ++ dtpgPatternForCompare.findAndReplace(u"\u202F", u" "); ++ if (dtfShortPatternForCompare == dtfSkelPatternForCompare && ++ dtfSkelPatternForCompare == dtpgPatternForCompare) { ++ continue; ++ } ++ } + const char* dtfShortValidLoc = dtfShort->getLocaleID(ULOC_VALID_LOCALE, status); + const char* dtfShortActualLoc = dtfShort->getLocaleID(ULOC_ACTUAL_LOCALE, status); + errln(UnicodeString("For locale ") + localeID + +@@ -1635,10 +1647,10 @@ void IntlTestDateTimePatternGeneratorAPI::testDateTimePatterns() { + // The following tests some locales in which there are differences between the + // DateTimePatterns of various length styles. + DTPLocaleAndResults localeAndResults[] = { +- { "en", { UnicodeString(u"EEEE, MMMM d, y 'at' h:mm\u202Fa"), // long != medium +- UnicodeString(u"MMMM d, y 'at' h:mm\u202Fa"), +- UnicodeString(u"MMM d, y, h:mm\u202Fa"), +- UnicodeString(u"M/d/y, h:mm\u202Fa") } }, ++ { "en", { UnicodeString(u"EEEE, MMMM d, y 'at' h:mm a"), // long != medium ++ UnicodeString(u"MMMM d, y 'at' h:mm a"), ++ UnicodeString(u"MMM d, y, h:mm a"), ++ UnicodeString(u"M/d/y, h:mm a") } }, + { "fr", { UnicodeString(u"EEEE d MMMM y 'à' HH:mm"), // medium != short + UnicodeString(u"d MMMM y 'à' HH:mm"), + UnicodeString(u"d MMM y, HH:mm"), +@@ -1663,10 +1675,10 @@ void IntlTestDateTimePatternGeneratorAPI::testDateTimePatterns() { + UnicodeString(u"{1} _2_ {0}"), + UnicodeString(u"{1} _3_ {0}") + }; +- DTPLocaleAndResults enModResults = { "en", { UnicodeString(u"EEEE, MMMM d, y _0_ h:mm\u202Fa"), +- UnicodeString(u"MMMM d, y _1_ h:mm\u202Fa"), +- UnicodeString(u"MMM d, y _2_ h:mm\u202Fa"), +- UnicodeString(u"M/d/y _3_ h:mm\u202Fa") } ++ DTPLocaleAndResults enModResults = { "en", { UnicodeString(u"EEEE, MMMM d, y _0_ h:mm a"), ++ UnicodeString(u"MMMM d, y _1_ h:mm a"), ++ UnicodeString(u"MMM d, y _2_ h:mm a"), ++ UnicodeString(u"M/d/y _3_ h:mm a") } + }; + + // Test various locales with standard data +@@ -1784,7 +1796,7 @@ void IntlTestDateTimePatternGeneratorAPI::testRegionOverride() { + const char16_t* expectedPattern; + UDateFormatHourCycle expectedHourCycle; + } testCases[] = { +- { "en_US", u"h:mm\u202fa", UDAT_HOUR_CYCLE_12 }, ++ { "en_US", u"h:mm a", UDAT_HOUR_CYCLE_12 }, + { "en_GB", u"HH:mm", UDAT_HOUR_CYCLE_23 }, + { "en_US@rg=GBZZZZ", u"HH:mm", UDAT_HOUR_CYCLE_23 }, + { "en_US@hours=h23", u"HH:mm", UDAT_HOUR_CYCLE_23 }, diff --git a/icu/icu4c/source/test/intltest/locnmtst.cpp b/icu/icu4c/source/test/intltest/locnmtst.cpp -index 61baca2e4634a08d83a4dbdd69990df7c9bf2471..68d55de958e0228a393cedc0fa06120c54753603 100644 +index 864b57ef5185b99b13011b5a1a333afb07997812..0703866445d27801548c51fdcde0e4e33c179480 100644 --- a/icu/icu4c/source/test/intltest/locnmtst.cpp +++ b/icu/icu4c/source/test/intltest/locnmtst.cpp -@@ -68,10 +68,14 @@ void LocaleDisplayNamesTest::runIndexedTest(int32_t index, UBool exec, const cha - switch (index) { - #if !UCONFIG_NO_FORMATTING - TESTCASE(0, TestCreate); -- TESTCASE(1, TestCreateDialect); -+ /* MSFT Change: Begin */ -+ // TESTCASE(1, TestCreateDialect); -+ /* MSFT Change: End */ - TESTCASE(2, TestWithKeywordsAndEverything); - TESTCASE(3, TestUldnOpen); -- TESTCASE(4, TestUldnOpenDialect); -+ /* MSFT Change: Begin */ -+ // TESTCASE(4, TestUldnOpenDialect); -+ /* MSFT Change: End */ - TESTCASE(5, TestUldnWithKeywordsAndEverything); - TESTCASE(6, TestUldnComponents); - TESTCASE(7, TestRootEtc); -diff --git a/icu/icu4c/source/test/intltest/numfmtst.cpp b/icu/icu4c/source/test/intltest/numfmtst.cpp -index dc193f2cc42b26d0c544e8c24701d4e4aefeff92..95157d1d69069aabe2f814aef0e709e2f180dcb8 100644 ---- a/icu/icu4c/source/test/intltest/numfmtst.cpp -+++ b/icu/icu4c/source/test/intltest/numfmtst.cpp -@@ -199,7 +199,9 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n - TESTCASE_AUTO(Test11640_getAffixes); - TESTCASE_AUTO(Test11649_toPatternWithMultiCurrency); - TESTCASE_AUTO(Test13327_numberingSystemBufferOverflow); -- TESTCASE_AUTO(Test13391_chakmaParsing); -+ /* MSFT Change: Begin */ -+ // TESTCASE_AUTO(Test13391_chakmaParsing); -+ /* MSFT Change: End */ - TESTCASE_AUTO(Test11735_ExceptionIssue); - TESTCASE_AUTO(Test11035_FormatCurrencyAmount); - TESTCASE_AUTO(Test11318_DoubleConversion); -@@ -1022,19 +1024,21 @@ void NumberFormatTest::TestCurrencyObject() { - return; +@@ -104,7 +104,7 @@ void LocaleDisplayNamesTest::TestCreateDialect() { + LocaleDisplayNames *ldn = LocaleDisplayNames::createInstance(Locale::getUS(), ULDN_DIALECT_NAMES); + ldn->localeDisplayName("en_GB", temp); + delete ldn; +- test_assert_equal("British English", temp); ++ test_assert_equal("English (United Kingdom)", temp); + } + + void LocaleDisplayNamesTest::TestWithKeywordsAndEverything() { +@@ -190,7 +190,7 @@ void LocaleDisplayNamesTest::TestUldnOpenDialect() { + test_assert(U_SUCCESS(status)); + + UnicodeString str(result, len, kMaxResultSize); +- test_assert_equal("British English", str); ++ test_assert_equal("English (United Kingdom)", str); + } + + void LocaleDisplayNamesTest::TestUldnWithGarbage() { +@@ -299,22 +299,22 @@ static char16_t daFor_en[] = {0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0}; //"en + static char16_t daFor_en_cabud[] = {0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x62,0x75,0x64,0x64,0x68,0x69,0x73,0x74,0x69,0x73,0x6B,0x20, + 0x6B,0x61,0x6C,0x65,0x6E,0x64,0x65,0x72,0x29,0}; //"engelsk (buddhistisk kalender)" + static char16_t daFor_en_GB[] = {0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x53,0x74,0x6F,0x72,0x62,0x72,0x69,0x74,0x61,0x6E,0x6E,0x69,0x65,0x6E,0x29,0}; //"engelsk (Storbritannien)" +-static char16_t daFor_en_GB_D[] = {0x62,0x72,0x69,0x74,0x69,0x73,0x6B,0x20,0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0}; //"britisk engelsk" ++static char16_t daFor_en_GB_D[] = {0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x53,0x74,0x6F,0x72,0x62,0x72,0x69,0x74,0x61,0x6E,0x6E,0x69,0x65,0x6E,0x29,0}; //"engelsk (Storbritannien)" + static char16_t esFor_en[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0}; //"ingles" with acute on the e + static char16_t esFor_en_GB[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"ingles (Reino Unido)" ... +-static char16_t esFor_en_GB_S[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x55,0x29,0}; //"ingles (RU)" ... +-static char16_t esFor_en_GB_D[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x62,0x72,0x69,0x74,0xE1,0x6E,0x69,0x63,0x6F,0}; //"ingles britanico" with acute on the e, a ++static char16_t esFor_en_GB_S[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"ingles (Reino Unido)" ... ++static char16_t esFor_en_GB_D[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"ingles (Reino Unido)" ... + static char16_t ruFor_uz_Latn[] = {0x0443,0x0437,0x0431,0x0435,0x043A,0x0441,0x043A,0x0438,0x0439,0x20,0x28,0x043B,0x0430,0x0442,0x0438,0x043D,0x0438,0x0446,0x0430,0x29,0}; // all lowercase + #if !UCONFIG_NO_BREAK_ITERATION + static char16_t daFor_en_T[] = {0x45,0x6E,0x67,0x65,0x6C,0x73,0x6B,0}; //"Engelsk" + static char16_t daFor_en_cabudT[]= {0x45,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x62,0x75,0x64,0x64,0x68,0x69,0x73,0x74,0x69,0x73,0x6B,0x20, + 0x6B,0x61,0x6C,0x65,0x6E,0x64,0x65,0x72,0x29,0}; //"Engelsk (buddhistisk kalender)" + static char16_t daFor_en_GB_T[] = {0x45,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x53,0x74,0x6F,0x72,0x62,0x72,0x69,0x74,0x61,0x6E,0x6E,0x69,0x65,0x6E,0x29,0}; //"Engelsk (Storbritannien)" +-static char16_t daFor_en_GB_DT[] = {0x42,0x72,0x69,0x74,0x69,0x73,0x6B,0x20,0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0}; //"Britisk engelsk" ++static char16_t daFor_en_GB_DT[] = {0x45,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x53,0x74,0x6F,0x72,0x62,0x72,0x69,0x74,0x61,0x6E,0x6E,0x69,0x65,0x6E,0x29,0}; //"Engelsk (Storbritannien)" + static char16_t esFor_en_T[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0}; //"Ingles" with acute on the e + static char16_t esFor_en_GB_T[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"Ingles (Reino Unido)" ... +-static char16_t esFor_en_GB_ST[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x55,0x29,0}; //"Ingles (RU)" ... +-static char16_t esFor_en_GB_DT[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x62,0x72,0x69,0x74,0xE1,0x6E,0x69,0x63,0x6F,0}; //"Ingles britanico" with acute on the e, a ++static char16_t esFor_en_GB_ST[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"Ingles (Reino Unido)" ... ++static char16_t esFor_en_GB_DT[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"Ingles (Reino Unido)" ... + static char16_t ruFor_uz_Latn_T[]= {0x0423,0x0437,0x0431,0x0435,0x043A,0x0441,0x043A,0x0438,0x0439,0x20,0x28,0x043B,0x0430,0x0442,0x0438,0x043D,0x0438,0x0446,0x0430,0x29,0}; // first char upper + #endif /* #if !UCONFIG_NO_BREAK_ITERATION */ + +diff --git a/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp b/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp +index f01b64baf5121a9bab7a3ca40c24982466ff6687..3492e06f92a6f165d552a41a00eccd4522cd8e56 100644 +--- a/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp ++++ b/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp +@@ -48,7 +48,7 @@ there was {$what} on planet {$planet :integer}.") + .setArgument("planet", (int64_t) 7) + .setDateArgument("when", (UDate) 871068000000) + .setArgument("what", "a disturbance in the Force") +- .setExpected(CharsToUnicodeString("At 12:20:00\\u202FPM on Aug 8, 1997, there was a disturbance in the Force on planet 7.")) ++ .setExpected(CharsToUnicodeString("At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7.")) + .build(), errorCode); + } + +diff --git a/icu/icu4c/source/test/intltest/tmsgfmt.cpp b/icu/icu4c/source/test/intltest/tmsgfmt.cpp +index 54b71ed3e78105b7ab9e5f2709c19c8981d28b35..0603136ba1142f16d5d65be27ea9e9f2e2fe9bda 100644 +--- a/icu/icu4c/source/test/intltest/tmsgfmt.cpp ++++ b/icu/icu4c/source/test/intltest/tmsgfmt.cpp +@@ -288,7 +288,7 @@ void TestMessageFormat::PatternTest() + u"Quotes ', {, 'a' 1 {0}", + u"Quotes ', {, 'a' 1 {0}", + u"{1,number,'#',##} #34,56", +- u"There are 3,456 files on Disk at 1/12/70, 5:46\u202FAM.", ++ u"There are 3,456 files on Disk at 1/12/70, 5:46 AM.", + u"On Disk, there are 3,456 files, with $1.00.", + u"{1,number,percent}, 345,600%,", + u"{1,date,full}, Wednesday, December 31, 1969,", +@@ -419,7 +419,7 @@ void TestMessageFormat::testStaticFormat() + } + + const UnicodeString expected( +- u"At 12:20:00\u202FPM on Aug 8, 1997, there was a disturbance in the Force on planet 7."); ++ u"At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7."); + if (result != expected) { + errln(UnicodeString("TestMessageFormat::testStaticFormat failed on test") + + UnicodeString("\n Result: ") + result + +@@ -1502,7 +1502,7 @@ void TestMessageFormat::TestUnlimitedArgsAndSubformats() { + + UnicodeString expected = + u"On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) " +- u"at 9:46:40\u202FAM (aka 9:46\u202FAM, aka 9:46:40\u202FAM PST) " ++ u"at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) " + u"there were 1,303 werjes " + u"(a 8% increase over 1,202) " + u"despite the Glimmung's efforts " +diff --git a/icu/icu4c/source/test/testdata/format.txt b/icu/icu4c/source/test/testdata/format.txt +index e3d6e72fd8b9ccbb5f7868865074a16f4b8554e8..b8d3c3ba5b99f2eb01ff2513335700177655765d 100644 +--- a/icu/icu4c/source/test/testdata/format.txt ++++ b/icu/icu4c/source/test/testdata/format.txt +@@ -37,7 +37,7 @@ format:table(nofallback) { + "", + "DATE=SHORT,TIME=SHORT", + "ERA=1,YEAR=2007,MONTH=AUGUST,DATE=8,HOUR_OF_DAY=18,MINUTE=54,SECOND=0", +- "8/8/07, 6:54 PM" ++ "8/8/07, 6:54 PM" + }, + { + "zh_TW@calendar=roc", +@@ -102,14 +102,14 @@ format:table(nofallback) { + "GMT", + "TIME=LONG", + "ERA=1,YEAR=2012,MONTH=OCTOBER,DATE=8,HOUR_OF_DAY=23,MINUTE=59,SECOND=0", +- "11:59:00 PM GMT" ++ "11:59:00 PM GMT" + }, + { + "en_US@calendar=gregorian", + "GMT", + "TIME=LONG", + "RELATIVE_ADD:DATE=-1,HOUR_OF_DAY=17,MINUTE=0,SECOND=0", // one day before now at specified time +- "5:00:00 PM GMT" ++ "5:00:00 PM GMT" + }, + // normal formats, combined using 'at' + { +@@ -117,7 +117,7 @@ format:table(nofallback) { + "GMT", + "DATE=RELATIVE_FULL,TIME=LONG", + "ERA=1,YEAR=2012,MONTH=OCTOBER,DATE=8,HOUR_OF_DAY=23,MINUTE=59,SECOND=0", +- "Monday, October 8, 2012, 11:59:00 PM GMT" ++ "Monday, October 8, 2012, 11:59:00 PM GMT" + }, + // normal formats, combined using ", " + { +@@ -125,7 +125,7 @@ format:table(nofallback) { + "GMT", + "DATE=RELATIVE_MEDIUM,TIME=SHORT", + "ERA=1,YEAR=2012,MONTH=OCTOBER,DATE=8,HOUR_OF_DAY=23,MINUTE=59,SECOND=0", +- "Oct 8, 2012, 11:59 PM" ++ "Oct 8, 2012, 11:59 PM" + }, + // formats with relative day, combined using 'at' + { +@@ -133,7 +133,7 @@ format:table(nofallback) { + "GMT", + "DATE=RELATIVE_FULL,TIME=LONG", + "RELATIVE_ADD:DATE=-1,HOUR_OF_DAY=17,MINUTE=0,SECOND=0", // one day before now at specified time +- "yesterday, 5:00:00 PM GMT" ++ "yesterday, 5:00:00 PM GMT" + }, + // formats with relative day, combined using ", " + { +@@ -141,7 +141,7 @@ format:table(nofallback) { + "GMT", + "DATE=RELATIVE_MEDIUM,TIME=SHORT", + "RELATIVE_ADD:DATE=-1,HOUR_OF_DAY=17,MINUTE=0,SECOND=0", // one day before now at specified time +- "yesterday, 5:00 PM" ++ "yesterday, 5:00 PM" + }, + // normal formats that have quoted literals, combined + { +@@ -554,7 +554,7 @@ format:table(nofallback) { + "", + "DATE=FULL,TIME=FULL", + "MILLIS=3076424179200000", +- "Friday, 3 Heshvan 103217 at 12:00:00 AM GMT-08:00" ++ "Friday, 3 Heshvan 103217 at 12:00:00 AM GMT-08:00" + }, + } + } +diff --git a/icu/icu4c/source/test/testdata/message2/icu4j/icu-test-functions.json b/icu/icu4c/source/test/testdata/message2/icu4j/icu-test-functions.json +index 21f917da6e5239927ee2a5213289df6305239287..b72421119ee8e053ea0cc9f01a43400f2fcc0d01 100644 +--- a/icu/icu4c/source/test/testdata/message2/icu4j/icu-test-functions.json ++++ b/icu/icu4c/source/test/testdata/message2/icu4j/icu-test-functions.json +@@ -2,18 +2,18 @@ + "Date and time formats": [ + { + "src": "Expires on {$exp}", +- "exp": "Expires on 8/3/24, 9:43 PM", ++ "exp": "Expires on 8/3/24, 9:43 PM", + "comment": "Modified from ICU4J copy to add params (likewise with the other date/time tests); 1722746637000 is 2024-08-03 21:43:57 PDT", + "params": {"exp": { "date": 1722746637000 } } + }, + { + "src": "Expires on {$exp :datetime}", +- "exp": "Expires on 8/3/24, 9:43 PM", ++ "exp": "Expires on 8/3/24, 9:43 PM", + "params": {"exp": { "date": 1722746637000 } } + }, + { + "src": "Expires on {$exp :datetime icu:skeleton=yMMMMdjmsSSEE}", +- "exp": "Expires on Sat, August 3, 2024 at 9:43:57.00 PM", ++ "exp": "Expires on Sat, August 3, 2024 at 9:43:57.00 PM", + "params": {"exp": { "date": 1722746637000 } }, + "ignoreTest": "ICU-22754 Skeleton option not implemented yet" + }, +@@ -34,22 +34,22 @@ + }, + { + "src": "Expires on {$exp :datetime timeStyle=long}", +- "exp": "Expires on 9:43:57 PM PDT", ++ "exp": "Expires on 9:43:57 PM PDT", + "params": {"exp": { "date": 1722746637000 } } + }, + { + "src": "Expires on {$exp :datetime timeStyle=medium}", +- "exp": "Expires on 9:43:57 PM", ++ "exp": "Expires on 9:43:57 PM", + "params": {"exp": { "date": 1722746637000 } } + }, + { + "src": "Expires on {$exp :datetime timeStyle=short}", +- "exp": "Expires on 9:43 PM", ++ "exp": "Expires on 9:43 PM", + "params": {"exp": { "date": 1722746637000 } } + }, + { + "src": "Expires on {$exp :datetime dateStyle=full timeStyle=medium}", +- "exp": "Expires on Saturday, August 3, 2024 at 9:43:57 PM", ++ "exp": "Expires on Saturday, August 3, 2024 at 9:43:57 PM", + "params": {"exp": { "date": 1722746637000 } } + }, + { +@@ -72,14 +72,14 @@ + { + "comment": "Make sure we ignore date / time fields if needed", + "src": "Expires at {$exp :time year=numeric month=medium day=numeric weekday=long hour=numeric minute=numeric}", +- "exp": "Expires at 9:43 PM", ++ "exp": "Expires at 9:43 PM", + "params": {"exp": { "date": 1722746637000 } }, + "ignoreTest": "ICU-22754 ICU4C doesn't accept field options for `:date` or `:time` -- see spec" + }, + { + "comment": "Make sure we ignore date / time fields if needed", + "src": "Expires at {$exp :time style=long dateStyle=full timeStyle=medium}", +- "exp": "Expires at 9:43:57 PM PDT", ++ "exp": "Expires at 9:43:57 PM PDT", + "params": {"exp": { "date": 1722746637000 } } + }, + { +@@ -96,11 +96,11 @@ + }, + { + "src": "Expires at {|2024-07-02T19:23:45| :datetime timeStyle=full}", +- "exp": "Expires at 7:23:45 PM Pacific Daylight Time" ++ "exp": "Expires at 7:23:45 PM Pacific Daylight Time" + }, + { + "src": "Expires at {|2024-07-02T19:23:45.123| :datetime timeStyle=full}", +- "exp": "Expires at 7:23:45 PM Pacific Daylight Time" ++ "exp": "Expires at 7:23:45 PM Pacific Daylight Time" + }, + { + "src": "Expires on {|2025-02-27T19:23:45| :datetime dateStyle=full}", +@@ -108,11 +108,11 @@ + }, + { + "src": "Expires at {|2024-07-02T19:23:45Z| :datetime timeStyle=long}", +- "exp": "Expires at 7:23:45 PM GMT" ++ "exp": "Expires at 7:23:45 PM GMT" + }, + { + "src": "Expires at {|2024-07-02T19:23:45+03:30| :datetime timeStyle=full}", +- "exp": "Expires at 7:23:45 PM GMT+03:30" ++ "exp": "Expires at 7:23:45 PM GMT+03:30" } + ], + "Chaining" : [ +@@ -125,7 +125,7 @@ + ".local $zooExp = {$exp :datetime dateStyle=short timeStyle=$tsOver}\n", + "{{Hello John, you want '{$exp}', '{$longExp}', or '{$zooExp}' or even '{$exp :datetime dateStyle=full}'?}}" + ], +- "exp": "Hello John, you want '9:43 PM', 'August 3, 2024 at 9:43 PM', or '8/3/24, 9:43:57 PM Pacific Daylight Time' or even 'Saturday, August 3, 2024 at 9:43 PM'?", ++ "exp": "Hello John, you want '9:43 PM', 'August 3, 2024 at 9:43 PM', or '8/3/24, 9:43:57 PM Pacific Daylight Time' or even 'Saturday, August 3, 2024 at 9:43 PM'?", + "params": {"exp": { "date": 1722746637000 }, "user": "John", "tsOver" : "long" }, + "ignoreTest": "ICU-22754 ICU4C doesn't implement this kind of function composition yet. See https://github.com/unicode-org/message-format-wg/issues/515" + }, +diff --git a/icu/testdata/message2/icu-test-functions.json b/icu/testdata/message2/icu-test-functions.json +index a97446addf0e7273e6dff7a10682340f3d9a3bc8..87e7b401b1398ee1ea74c4b5d4e3214c057d7500 100644 +--- a/icu/testdata/message2/icu-test-functions.json ++++ b/icu/testdata/message2/icu-test-functions.json +@@ -7,18 +7,18 @@ + "tests": [ + { + "src": "Expires on {$exp}", +- "exp": "Expires on 8/3/24, 9:43 PM", ++ "exp": "Expires on 8/3/24, 9:43 PM", + "comment": "Modified from ICU4J copy to add params (likewise with the other date/time tests); 1722746637000 is 2024-08-03 21:43:57 PDT", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] + }, + { + "src": "Expires on {$exp :datetime}", +- "exp": "Expires on 8/3/24, 9:43 PM", ++ "exp": "Expires on 8/3/24, 9:43 PM", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] + }, + { + "src": "Expires on {$exp :datetime icu:skeleton=yMMMMdjmsSSEE}", +- "exp": "Expires on Sat, August 3, 2024 at 9:43:57.00 PM", ++ "exp": "Expires on Sat, August 3, 2024 at 9:43:57.00 PM", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }], + "ignoreCpp": "ICU-22754 Skeleton option not implemented yet" + }, +@@ -39,22 +39,22 @@ + }, + { + "src": "Expires on {$exp :datetime timeStyle=long}", +- "exp": "Expires on 9:43:57 PM PDT", ++ "exp": "Expires on 9:43:57 PM PDT", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] + }, + { + "src": "Expires on {$exp :datetime timeStyle=medium}", +- "exp": "Expires on 9:43:57 PM", ++ "exp": "Expires on 9:43:57 PM", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] + }, + { + "src": "Expires on {$exp :datetime timeStyle=short}", +- "exp": "Expires on 9:43 PM", ++ "exp": "Expires on 9:43 PM", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] + }, + { + "src": "Expires on {$exp :datetime dateStyle=full timeStyle=medium}", +- "exp": "Expires on Saturday, August 3, 2024 at 9:43:57 PM", ++ "exp": "Expires on Saturday, August 3, 2024 at 9:43:57 PM", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] + }, + { +@@ -77,14 +77,14 @@ + { + "comment": "Make sure we ignore date / time fields if needed", + "src": "Expires at {$exp :time year=numeric month=medium day=numeric weekday=long hour=numeric minute=numeric}", +- "exp": "Expires at 9:43 PM", ++ "exp": "Expires at 9:43 PM", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }], + "ignoreCpp": "ICU-22754 ICU4C doesn't accept field options for `:date` or `:time` -- see spec" + }, + { + "comment": "Make sure we ignore date / time fields if needed", + "src": "Expires at {$exp :time style=long dateStyle=full timeStyle=medium}", +- "exp": "Expires at 9:43:57 PM PDT", ++ "exp": "Expires at 9:43:57 PM PDT", + "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] + }, + { +@@ -99,11 +99,11 @@ + }, + { + "src": "Expires at {|2024-07-02T19:23:45| :datetime timeStyle=full}", +- "exp": "Expires at 7:23:45 PM Pacific Daylight Time" ++ "exp": "Expires at 7:23:45 PM Pacific Daylight Time" + }, + { + "src": "Expires at {|2024-07-02T19:23:45.123| :datetime timeStyle=full}", +- "exp": "Expires at 7:23:45 PM Pacific Daylight Time" ++ "exp": "Expires at 7:23:45 PM Pacific Daylight Time" + }, + { + "src": "Expires on {|2025-02-27T19:23:45| :datetime dateStyle=full}", +@@ -111,12 +111,12 @@ + }, + { + "src": "Expires at {|2024-07-02T19:23:45Z| :datetime timeStyle=long}", +- "exp": "Expires at 7:23:45 PM GMT", ++ "exp": "Expires at 7:23:45 PM GMT", + "ignoreCpp": "ICU-22754 Time zones not working yet (bug)" + }, + { + "src": "Expires at {|2024-07-02T19:23:45+03:30| :datetime timeStyle=full}", +- "exp": "Expires at 7:23:45 PM GMT+03:30", ++ "exp": "Expires at 7:23:45 PM GMT+03:30", + "ignoreCpp": "ICU-22754 Time zones not working yet (bug)" + }, + { +@@ -128,7 +128,7 @@ + ".local $zooExp = {$exp :datetime dateStyle=short timeStyle=$tsOver}\n", + "{{Hello John, you want '{$exp}', '{$longExp}', or '{$zooExp}' or even '{$exp :datetime dateStyle=full}'?}}" + ], +- "exp": "Hello John, you want '9:43 PM', 'August 3, 2024 at 9:43 PM', or '8/3/24, 9:43:57 PM Pacific Daylight Time' or even 'Saturday, August 3, 2024 at 9:43 PM'?", ++ "exp": "Hello John, you want '9:43 PM', 'August 3, 2024 at 9:43 PM', or '8/3/24, 9:43:57 PM Pacific Daylight Time' or even 'Saturday, August 3, 2024 at 9:43 PM'?", + "params": [{"name": "exp", "value": { "date": 1722746637000 }}, + {"name": "user", "value": "John"}, + {"name": "tsOver", "value": "full" }], +diff --git a/icu/testdata/message2/more-functions.json b/icu/testdata/message2/more-functions.json +index 6d074f8b2d806e82917d65644675bccc47e528a9..90dc1274ba7fc8fccbf28994121df745b78efd53 100644 +--- a/icu/testdata/message2/more-functions.json ++++ b/icu/testdata/message2/more-functions.json +@@ -47,17 +47,17 @@ + }, + { + "src": "Testing date formatting: {$date :time style=long}.", +- "exp": "Testing date formatting: 7:42:37\u202FPM PST.", ++ "exp": "Testing date formatting: 7:42:37 PM PST.", + "params": [{ "name": "date", "value": { "date": 1669261357000 } }] + }, + { + "src": "Testing date formatting: {$date :time style=medium}.", +- "exp": "Testing date formatting: 7:42:37\u202FPM.", ++ "exp": "Testing date formatting: 7:42:37 PM.", + "params": [{ "name": "date", "value": { "date": 1669261357000 } }] + }, + { + "src": "Testing date formatting: {$date :time style=short}.", +- "exp": "Testing date formatting: 7:42\u202FPM.", ++ "exp": "Testing date formatting: 7:42 PM.", + "params": [{ "name": "date", "value": { "date": 1669261357000 } }] + }, + { diff --git a/icu-patches/patches/017-MSFT-Patch_ICU_test_changes_for_extra_CLDR-MS_locales.patch b/icu-patches/patches/017-MSFT-Patch_ICU_test_changes_for_extra_CLDR-MS_locales.patch index bcdaa06123a..e317005a830 100644 --- a/icu-patches/patches/017-MSFT-Patch_ICU_test_changes_for_extra_CLDR-MS_locales.patch +++ b/icu-patches/patches/017-MSFT-Patch_ICU_test_changes_for_extra_CLDR-MS_locales.patch @@ -1,131 +1,58 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jeff Genovy <29107334+jefgen@users.noreply.github.com> -Date: Wed, 7 Apr 2021 20:47:08 -0700 -Subject: MSFT-PATCH: Modify ICU tests to pass with extra locales from CLDR-MS. +From: Arvind Oruganti +Date: Tue, 19 May 2026 06:45:00 +0530 +Subject: MSFT-PATCH: Refresh ICU tests for extra CLDR-MS locales on ICU 78 -This changes modifies the ICU tests to pass with extra locales from -CLDR-MS. +Refreshes the CLDR-MS extra-locale test expectations for ICU 78. + +The ICU 72-era patch no longer matched the refactored ICU 78 tests, so the applicable 029 locale expectations were re-derived from the final passing Stage 7/8 tree. diff --git a/icu/icu4c/source/test/cintltst/cldrtest.c b/icu/icu4c/source/test/cintltst/cldrtest.c -index 179539d5178b5cfd8b5350043c539e89e8740185..bfb35c35a449f60c61c9a8eb6282c307e41fd161 100644 +index e014a1e1d59a48fb6ef78923fb7de4160f69779b..8cf8e5dc1ba8f3059e4ce6b0d1bb6369cda51ca7 100644 --- a/icu/icu4c/source/test/cintltst/cldrtest.c +++ b/icu/icu4c/source/test/cintltst/cldrtest.c -@@ -970,7 +970,14 @@ static void VerifyTranslation(void) { - uprv_strncmp(currLoc, "oc", 2) == 0 || uprv_strncmp(currLoc, "oc_FR", 5) == 0 || - uprv_strncmp(currLoc, "syr", 3) == 0 || uprv_strncmp(currLoc, "syr_SY", 6) == 0 || - uprv_strncmp(currLoc, "tig", 3) == 0 || uprv_strncmp(currLoc, "tig_ER", 6) == 0 || -- uprv_strncmp(currLoc, "wal", 3) == 0 || uprv_strncmp(currLoc, "wal_ET", 6) == 0 -+ uprv_strncmp(currLoc, "wal", 3) == 0 || uprv_strncmp(currLoc, "wal_ET", 6) == 0 || -+ uprv_strncmp(currLoc, "bin", 3) == 0 || uprv_strncmp(currLoc, "bin_NG", 6) == 0 || -+ uprv_strncmp(currLoc, "la", 2) == 0 || uprv_strncmp(currLoc, "la_VA", 6) == 0 || -+ uprv_strncmp(currLoc, "jv_Java", 7) == 0 || uprv_strncmp(currLoc, "jv_Java_ID", 10) == 0 || -+ uprv_strncmp(currLoc, "ks_Deva", 7) == 0 || uprv_strncmp(currLoc, "ks_Deva_IN", 10) == 0 || -+ uprv_strncmp(currLoc, "pap", 3) == 0 || uprv_strncmp(currLoc, "pap_029", 7) == 0 || -+ uprv_strncmp(currLoc, "tzm_Arab", 8) == 0 || uprv_strncmp(currLoc, "tzm_Arab_MA", 11) == 0 || -+ uprv_strncmp(currLoc, "tzm_Tfng", 8) == 0 || uprv_strncmp(currLoc, "tzm_Tfng_MA", 11) == 0 - ) { - log_knownIssue("0", "MSFT Change: skipping test for %s which has issues due to CLDR Seed data.", currLoc); - } -@@ -1110,7 +1117,8 @@ static void VerifyTranslation(void) { +@@ -1122,7 +1122,7 @@ static void VerifyTranslation(void) { if (U_FAILURE(errorCode)) { log_err("ulocdata_getMeasurementSystem failed for locale %s with error: %s \n", currLoc, u_errorName(errorCode)); } else { - if ( strstr(fullLoc, "_US")!=NULL || strstr(fullLoc, "_LR")!=NULL ) { -+ /* MSFT Change: CLDR-MS adds 029 region with US measurement */ + if ( strstr(fullLoc, "_US")!=NULL || strstr(fullLoc, "_LR")!=NULL || strstr(fullLoc, "_029")!=NULL ) { if(measurementSystem != UMS_US){ log_err("ulocdata_getMeasurementSystem did not return expected data for locale %s \n", currLoc); } -@@ -1128,10 +1136,11 @@ static void VerifyTranslation(void) { - if (U_FAILURE(errorCode)) { - log_err("ulocdata_getPaperSize failed for locale %s with error: %s \n", currLoc, u_errorName(errorCode)); - } else { -+ /* MSFT Change: CLDR-MS adds 029 region with US paper size */ +@@ -1143,7 +1143,7 @@ static void VerifyTranslation(void) { if ( strstr(fullLoc, "_US")!=NULL || strstr(fullLoc, "_BZ")!=NULL || strstr(fullLoc, "_CA")!=NULL || strstr(fullLoc, "_CL")!=NULL || strstr(fullLoc, "_CO")!=NULL || strstr(fullLoc, "_CR")!=NULL || strstr(fullLoc, "_GT")!=NULL || strstr(fullLoc, "_MX")!=NULL || strstr(fullLoc, "_NI")!=NULL || strstr(fullLoc, "_PA")!=NULL || strstr(fullLoc, "_PH")!=NULL || strstr(fullLoc, "_PR")!=NULL || - strstr(fullLoc, "_SV")!=NULL || strstr(fullLoc, "_VE")!=NULL ) { -+ strstr(fullLoc, "_SV")!=NULL || strstr(fullLoc, "_VE")!=NULL || strstr(fullLoc, "_029")!=NULL ) { ++ strstr(fullLoc, "_SV")!=NULL || strstr(fullLoc, "_VE")!=NULL || strstr(fullLoc, "_029")!=NULL ) { if (height != 279 || width != 216) { log_err("ulocdata_getPaperSize did not return expected data for locale %s \n", currLoc); } -@@ -1251,8 +1260,14 @@ static void TestExemplarSet(void){ - - if (existsInScript == FALSE){ - /* MSFT Change */ -- if (uprv_strncmp(locale, "oc", 2) == 0 || uprv_strncmp(locale, "oc_FR", 5) == 0) { -- log_knownIssue("0", "MSFT Change: oc and oc_FR have ExemplarSet issues."); -+ if (uprv_strncmp(locale, "oc", 2) == 0 || uprv_strncmp(locale, "oc_FR", 5) == 0 || -+ uprv_strncmp(locale, "jv_Java", 7) == 0 || uprv_strncmp(locale, "jv_Java_ID", 10) == 0 || -+ uprv_strncmp(locale, "la", 2) == 0 || uprv_strncmp(locale, "la_VA", 6) == 0 || -+ uprv_strncmp(locale, "pap", 3) == 0 || uprv_strncmp(locale, "pap_029", 7) == 0 || -+ uprv_strncmp(locale, "tzm_Arab", 8) == 0 || uprv_strncmp(locale, "tzm_Arab_MA", 11) == 0 || -+ uprv_strncmp(locale, "tzm_Tfng", 8) == 0 || uprv_strncmp(locale, "tzm_Tfng_MA", 11) == 0 -+ ) { -+ log_knownIssue("0", "MSFT Change: skipping test for %s which has issue due to CLDR seed data.", locale); - continue; - } else { - log_err("ExemplarSet containment failed for locale : %s\n", locale); diff --git a/icu/icu4c/source/test/cintltst/cnmdptst.c b/icu/icu4c/source/test/cintltst/cnmdptst.c -index 99a9ce23be7ef93923493b2b8312a254706c3f2d..a319b99e3faf6f6fc749e70852a298ce42268696 100644 +index 98504e0220ffb26a5f02877e1bbf7343e07e5a64..b7ce012361befc52b1b23e068017ffb71bdc4b4a 100644 --- a/icu/icu4c/source/test/cintltst/cnmdptst.c +++ b/icu/icu4c/source/test/cintltst/cnmdptst.c -@@ -811,7 +811,8 @@ static void TestGetKeywordValuesForLocale(void) { +@@ -813,7 +813,7 @@ static void TestGetKeywordValuesForLocale(void) { { "und", "USD", "USN", NULL }, /* { "und_ZZ", "USD", NULL, NULL }, -- temporarily remove as this locale now has 15 entries */ { "en_US", "USD", "USN", NULL }, - { "en_029", "USD", "USN", NULL }, -+ /* MSFT Change: CLDR-MS adds en_029 locale with XCD currency */ + { "en_029", "XCD", NULL, NULL }, { "en_TH", "THB", NULL, NULL }, { "de", "EUR", NULL, NULL }, { "de_DE", "EUR", NULL, NULL }, -@@ -825,11 +826,13 @@ static void TestGetKeywordValuesForLocale(void) { +@@ -827,11 +827,11 @@ static void TestGetKeywordValuesForLocale(void) { { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL }, }; const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { - 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 -+ /* MSFT Change: CLDR-MS adds en_029 locale with XCD currency */ + 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 }; /* ucurr_forLocale results for same locales; "" if no result expected */ const char *FORLOCALE[PREFERRED_SIZE] = { - "", "", "USD", "", -+ /* MSFT Change: CLDR-MS adds en_029 locale with XCD currency */ + "", "", "USD", "XCD", "THB", "", "EUR", "", "ILS", "CAD", "ZZZ", "DEM", "THB", "USD", "CAD" -diff --git a/icu/icu4c/source/test/intltest/dtptngts.cpp b/icu/icu4c/source/test/intltest/dtptngts.cpp -index dc86355f93fa68f509a0023dc95fc17a548170c1..c83e27bb68c212c3e9569c71ed5b417a96b7f9de 100644 ---- a/icu/icu4c/source/test/intltest/dtptngts.cpp -+++ b/icu/icu4c/source/test/intltest/dtptngts.cpp -@@ -1408,7 +1408,8 @@ void IntlTestDateTimePatternGeneratorAPI::testJjMapping() { - uprv_strncmp(localeID, "ssy_ER", 6) == 0 || uprv_strncmp(localeID, "st_LS", 5) == 0 || - uprv_strncmp(localeID, "syr", 3) == 0 || uprv_strncmp(localeID, "syr_SY", 6) == 0 || - uprv_strncmp(localeID, "tig", 3) == 0 || uprv_strncmp(localeID, "tig_ER", 6) == 0 || -- uprv_strncmp(localeID, "wal", 3) == 0 || uprv_strncmp(localeID, "wal_ET", 6) == 0 -+ uprv_strncmp(localeID, "wal", 3) == 0 || uprv_strncmp(localeID, "wal_ET", 6) == 0 || -+ uprv_strncmp(localeID, "ks_Deva", 7) == 0 || uprv_strncmp(localeID, "ks_Deva_IN", 10) == 0 - ) { - logKnownIssue("0", "MSFT Change: skipping test for %s which has issues due to CLDR Seed data.", localeID); - } -diff --git a/icu/icu4c/source/test/intltest/numfmtst.cpp b/icu/icu4c/source/test/intltest/numfmtst.cpp -index bc072bd8e3775554b8a8f96a81baf850b5e8feb7..a63c329c8eabf287512b9c152ac91d862d333264 100644 ---- a/icu/icu4c/source/test/intltest/numfmtst.cpp -+++ b/icu/icu4c/source/test/intltest/numfmtst.cpp -@@ -8094,10 +8094,12 @@ void NumberFormatTest::TestAccountingCurrency() { - (Formattable)(double)-1000.5, UnicodeString("(\\uFFE51,000)").unescape(), FALSE, status); - expect(NumberFormat::createInstance("de_DE", style, status), - (Formattable)(double)-23456.7, UnicodeString("-23.456,70\\u00A0\\u20AC").unescape(), TRUE, status); -+ /* MSFT Change: We add a CLDR-MS locale en_ID */ - expect(NumberFormat::createInstance("en_ID", style, status), -- (Formattable)(double)0, UnicodeString("IDR\\u00A00.00").unescape(), TRUE, status); -+ (Formattable)(double)0, UnicodeString("IDR\\u00A00,00").unescape(), TRUE, status); - expect(NumberFormat::createInstance("en_ID", style, status), -- (Formattable)(double)-0.2, UnicodeString("(IDR\\u00A00.20)").unescape(), TRUE, status); -+ (Formattable)(double)-0.2, UnicodeString("(IDR\\u00A00,20)").unescape(), TRUE, status); -+ /* MSFT Change: End */ - expect(NumberFormat::createInstance("sh_ME", style, status), - (Formattable)(double)0, UnicodeString("0,00\\u00A0\\u20AC").unescape(), TRUE, status); - expect(NumberFormat::createInstance("sh_ME", style, status), diff --git a/icu-patches/patches/018-MSFT-Patch_ICU_toolutil_increase_string_store_for_extra_locales.patch b/icu-patches/patches/018-MSFT-Patch_ICU_toolutil_increase_string_store_for_extra_locales.patch index a41c47a5263..f9bfc6523d7 100644 --- a/icu-patches/patches/018-MSFT-Patch_ICU_toolutil_increase_string_store_for_extra_locales.patch +++ b/icu-patches/patches/018-MSFT-Patch_ICU_toolutil_increase_string_store_for_extra_locales.patch @@ -1,11 +1,14 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jeff Genovy <29107334+jefgen@users.noreply.github.com> -Date: Wed, 7 Apr 2021 20:47:31 -0700 -Subject: MSFT-PATCH: Increase the STRING_STORE_SIZE due to extra locales from CLDR-MS +From: Arvind Oruganti +Date: Tue, 19 May 2026 06:45:00 +0530 +Subject: MSFT-PATCH: Increase ICU string store for CLDR 48 extra locales +Increases STRING_STORE_SIZE for the larger CLDR 48 / CLDR-MS locale set. + +The original 120000 value was carried from the older patch, but this ICU 78 upgrade settled on 200000 before the CLDR data build. diff --git a/icu/icu4c/source/tools/toolutil/package.h b/icu/icu4c/source/tools/toolutil/package.h -index ea60c13a74a57b94057882e39b6aa05314c4ca1f..6c411ae5fd04c8463a089307efc056f4d2f622f9 100644 +index ea60c13a74a57b94057882e39b6aa05314c4ca1f..3a1d3cd23d9ee75ad2881d52c0f34413dbd554f1 100644 --- a/icu/icu4c/source/tools/toolutil/package.h +++ b/icu/icu4c/source/tools/toolutil/package.h @@ -27,7 +27,7 @@ @@ -13,7 +16,7 @@ index ea60c13a74a57b94057882e39b6aa05314c4ca1f..6c411ae5fd04c8463a089307efc056f4 // .dat package file representation ---------------------------------------- *** -#define STRING_STORE_SIZE 100000 -+#define STRING_STORE_SIZE 120000 ++#define STRING_STORE_SIZE 200000 #define MAX_PKG_NAME_LENGTH 64 typedef void CheckDependency(void *context, const char *itemName, const char *targetName); diff --git a/icu-patches/patches/020-MSFT-Patch_ICU_Add_uprefs_library_to_obtain_default_locale_as_full_BCP47_tag.patch b/icu-patches/patches/020-MSFT-Patch_ICU_Add_uprefs_library_to_obtain_default_locale_as_full_BCP47_tag.patch index 502beeb9f04..b6416bf2b47 100644 --- a/icu-patches/patches/020-MSFT-Patch_ICU_Add_uprefs_library_to_obtain_default_locale_as_full_BCP47_tag.patch +++ b/icu-patches/patches/020-MSFT-Patch_ICU_Add_uprefs_library_to_obtain_default_locale_as_full_BCP47_tag.patch @@ -1,61 +1,57 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Erik Torres <26077674+erik0686@users.noreply.github.com> -Date: Wed, 6 Oct 2021 15:06:30 -0700 -Subject: Add uprefs library to ICU to obtain the default locale as a full - BCP47 tag (#112) +From: Arvind Oruganti +Date: Tue, 19 May 2026 06:45:00 +0530 +Subject: MSFT-PATCH: Refresh uprefs default-locale library for ICU 78 -Currently, for many processes and tasks, ICU gets the default locale and caches it. This means that when needed, ICU will get something like "en-US" and that will not change even if you were to change your language or region in your device. -Furthermore, ICU has currently no way of getting other globalization settings such as currency, calendar, hour cycle, first day of week, sorting method and measurement system. -We have decided to add a way to solve these two problems. -By adding the uprefs library (only to the Windows implementation of uprv_getDefaultLocaleID()), we are adding the Uprefs_getBCP47Tag() internal API, which obtains a full, canonical and valid BCP47Tag containing all of the settings. +Refreshes the Windows uprefs library patch against the ICU 78 source tree. -This means we also change the way we get the default locale. We go from getting only the locale and region, to getting the full thing. +This records the final ICU 78 version of the project-file, putil, uconfig, source-list, and uprefstest changes instead of the stale ICU 72-era patch content. diff --git a/icu/icu4c/source/common/common.vcxproj b/icu/icu4c/source/common/common.vcxproj -index f8f28ad768ca2b4e7ec93893b213c3b426f294c1..305b705430837c9c928690bf1fd5aa46de81d5fd 100644 +index f0f13aa1e2ec1f953b4b0957763e50560ae3d0a1..aca55a102f96a8694e62c3e7b7affe4479e1a133 100644 --- a/icu/icu4c/source/common/common.vcxproj +++ b/icu/icu4c/source/common/common.vcxproj -@@ -282,6 +282,7 @@ - +@@ -286,6 +286,7 @@ + + -@@ -397,6 +398,7 @@ - +@@ -405,6 +406,7 @@ + + diff --git a/icu/icu4c/source/common/common_uwp.vcxproj b/icu/icu4c/source/common/common_uwp.vcxproj -index a57917292a7405b0a55fd8a34f9edd970c2951ef..0e346ccec772f6d37777505638ec7b242e21da5c 100644 +index 01906f3caf9a4c6f330b235c9b58b1b9179c82e0..113c241890217adcd4ebf14bc562e319a3e27c22 100644 --- a/icu/icu4c/source/common/common_uwp.vcxproj +++ b/icu/icu4c/source/common/common_uwp.vcxproj -@@ -404,6 +404,7 @@ - +@@ -409,6 +409,7 @@ + + -@@ -520,6 +521,7 @@ - +@@ -529,6 +530,7 @@ + + diff --git a/icu/icu4c/source/common/putil.cpp b/icu/icu4c/source/common/putil.cpp -index 3ed6a05d22d83972e3fdf2c356bc87a17babda27..4d80d514f84639e9aab7d1109ee28b45e2cf4d42 100644 +index ea15fdff0b0c67d09daf5a403f038be572cd1fbf..307b07d087de925095f6d6f976fbf37f21655b92 100644 --- a/icu/icu4c/source/common/putil.cpp +++ b/icu/icu4c/source/common/putil.cpp -@@ -71,6 +71,7 @@ +@@ -66,6 +66,7 @@ #include "locmap.h" #include "ucln_cmn.h" #include "charstr.h" @@ -63,7 +59,7 @@ index 3ed6a05d22d83972e3fdf2c356bc87a17babda27..4d80d514f84639e9aab7d1109ee28b45 /* Include standard headers. */ #include -@@ -1776,10 +1777,37 @@ The leftmost codepage (.xxx) wins. +@@ -1794,10 +1795,37 @@ The leftmost codepage (.xxx) wins. return posixID; #elif U_PLATFORM_USES_ONLY_WIN32_API @@ -102,7 +98,7 @@ index 3ed6a05d22d83972e3fdf2c356bc87a17babda27..4d80d514f84639e9aab7d1109ee28b45 // If we have already figured this out just use the cached value if (gCorrectedPOSIXLocale != nullptr) { return gCorrectedPOSIXLocale; -@@ -1821,11 +1849,11 @@ The leftmost codepage (.xxx) wins. +@@ -1839,11 +1867,11 @@ The leftmost codepage (.xxx) wins. } // Now normalize the resulting name @@ -116,7 +112,7 @@ index 3ed6a05d22d83972e3fdf2c356bc87a17babda27..4d80d514f84639e9aab7d1109ee28b45 if (U_SUCCESS(status)) { *(correctedPOSIXLocale + posixLen) = 0; -@@ -1839,6 +1867,7 @@ The leftmost codepage (.xxx) wins. +@@ -1857,6 +1885,7 @@ The leftmost codepage (.xxx) wins. } } } @@ -125,10 +121,10 @@ index 3ed6a05d22d83972e3fdf2c356bc87a17babda27..4d80d514f84639e9aab7d1109ee28b45 // If unable to find a locale we can agree upon, use en-US by default if (gCorrectedPOSIXLocale == nullptr) { diff --git a/icu/icu4c/source/common/sources.txt b/icu/icu4c/source/common/sources.txt -index e0410daaa475fad0b76587cec3e2dc4d124814f2..3ebc3c301130465cec837233540253110e8479cc 100644 +index 5b1c5e262eac42dc352f28b87033dff709376a2d..cfcfd95df56fac68a3cc224c4cd5a016a6099110 100644 --- a/icu/icu4c/source/common/sources.txt +++ b/icu/icu4c/source/common/sources.txt -@@ -157,6 +157,7 @@ unistr_titlecase_brkiter.cpp +@@ -163,6 +163,7 @@ unistr_titlecase_brkiter.cpp unorm.cpp unormcmp.cpp uobject.cpp @@ -137,10 +133,10 @@ index e0410daaa475fad0b76587cec3e2dc4d124814f2..3ebc3c301130465cec83723354025311 ures_cnv.cpp uresbund.cpp diff --git a/icu/icu4c/source/common/unicode/uconfig.h b/icu/icu4c/source/common/unicode/uconfig.h -index c4239fc9997028fb050be43740bb1cb368f514ba..da702d2d812fc4859ac6aa460bb8b0735ee28c29 100644 +index 3c1182886659252b44db3a0f28407dd994ca1447..f339dec982f4bcdfe7cff49130a84a1f5c4173f8 100644 --- a/icu/icu4c/source/common/unicode/uconfig.h +++ b/icu/icu4c/source/common/unicode/uconfig.h -@@ -390,6 +390,22 @@ +@@ -400,6 +400,22 @@ # define UCONFIG_USE_WINDOWS_LCID_MAPPING_API 1 #endif @@ -165,7 +161,7 @@ index c4239fc9997028fb050be43740bb1cb368f514ba..da702d2d812fc4859ac6aa460bb8b073 /* i18n library switches ---------------------------------------------------- */ diff --git a/icu/icu4c/source/common/uprefs.cpp b/icu/icu4c/source/common/uprefs.cpp new file mode 100644 -index 0000000000000000000000000000000000000000..b055cbe86f6ef16843444c1ea80667441a26bfa2 +index 0000000000000000000000000000000000000000..d9304a11de04e2a6416c40c8d957352be49b0a5e --- /dev/null +++ b/icu/icu4c/source/common/uprefs.cpp @@ -0,0 +1,553 @@ @@ -725,7 +721,7 @@ index 0000000000000000000000000000000000000000..b055cbe86f6ef16843444c1ea8066744 \ No newline at end of file diff --git a/icu/icu4c/source/common/uprefs.h b/icu/icu4c/source/common/uprefs.h new file mode 100644 -index 0000000000000000000000000000000000000000..2d77d0c9e7f8bdf9287b77d55741160f1c10a1fe +index 0000000000000000000000000000000000000000..08ecd86189bb626b6ff7b55098e0cfb28ff033f8 --- /dev/null +++ b/icu/icu4c/source/common/uprefs.h @@ -0,0 +1,29 @@ @@ -760,31 +756,31 @@ index 0000000000000000000000000000000000000000..2d77d0c9e7f8bdf9287b77d55741160f +#endif //UPREFS_H \ No newline at end of file diff --git a/icu/icu4c/source/test/intltest/Makefile.in b/icu/icu4c/source/test/intltest/Makefile.in -index 13d3ea86dc9bd7c17c944b2fb7b04a143879421f..5f8822cedac4a5ddc9428cb85941b668f612c5a0 100644 +index 2e448319243dcd56431ccdfd3ddfdbce3eb2566f..eab33ebb0b6beb95282d568bfb98e0346ad0150c 100644 --- a/icu/icu4c/source/test/intltest/Makefile.in +++ b/icu/icu4c/source/test/intltest/Makefile.in -@@ -69,7 +69,7 @@ string_segment_test.o \ - numbertest_parse.o numbertest_doubleconversion.o numbertest_skeletons.o \ - static_unisets_test.o numfmtdatadriventest.o numbertest_range.o erarulestest.o \ - formattedvaluetest.o formatted_string_builder_test.o numbertest_permutation.o \ --units_data_test.o units_router_test.o units_test.o -+units_data_test.o units_router_test.o units_test.o uprefstest.o +@@ -78,7 +78,7 @@ units_data_test.o units_router_test.o units_test.o displayoptions_test.o \ + numbertest_simple.o \ + cplusplus_header_api_build_test.o uchar_type_build_test.o \ + ucolheaderonlytest.o usetheaderonlytest.o utfiteratortest.o utfstringtest.o \ +-intltesttest.o ++intltesttest.o uprefstest.o DEPS = $(OBJECTS:.o=.d) diff --git a/icu/icu4c/source/test/intltest/intltest.vcxproj b/icu/icu4c/source/test/intltest/intltest.vcxproj -index 319c3ab58f68f70f3da6ead4ca6cf5ca81da617b..20da05e608aeb4f472ef378d222732c863ec04aa 100644 +index ce69ec0de410b2ef93cb2bbb45592b581597c93a..0ee503fcbe4ba68b6b487bfb7cd66808dc6ec3b1 100644 --- a/icu/icu4c/source/test/intltest/intltest.vcxproj +++ b/icu/icu4c/source/test/intltest/intltest.vcxproj -@@ -288,6 +288,7 @@ - - - +@@ -247,6 +247,7 @@ + + + + -@@ -419,6 +420,7 @@ +@@ -378,6 +379,7 @@ @@ -793,7 +789,7 @@ index 319c3ab58f68f70f3da6ead4ca6cf5ca81da617b..20da05e608aeb4f472ef378d222732c8 diff --git a/icu/icu4c/source/test/intltest/itutil.cpp b/icu/icu4c/source/test/intltest/itutil.cpp -index 228dbf2f218aa1a6ac6860ec54ed67303b243699..2f7ba22278596980f172617c2db9df55c28ee680 100644 +index 20c16389c0a071870de84b62f763eb80fa6b8e73..768507c632ad530359818716f82ad518423354da 100644 --- a/icu/icu4c/source/test/intltest/itutil.cpp +++ b/icu/icu4c/source/test/intltest/itutil.cpp @@ -33,6 +33,9 @@ @@ -805,8 +801,8 @@ index 228dbf2f218aa1a6ac6860ec54ed67303b243699..2f7ba22278596980f172617c2db9df55 +#endif extern IntlTest *createBytesTrieTest(); - extern IntlTest *createLocaleMatcherTest(); -@@ -67,6 +70,9 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* & + #if !UCONFIG_NO_COLLATION +@@ -76,6 +79,9 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* & TESTCASE_AUTO_CLASS(LocaleAliasTest); TESTCASE_AUTO_CLASS(UnicodeSetTest); TESTCASE_AUTO_CLASS(ErrorCodeTest); @@ -818,10 +814,10 @@ index 228dbf2f218aa1a6ac6860ec54ed67303b243699..2f7ba22278596980f172617c2db9df55 TESTCASE_AUTO_CREATE_CLASS(UCharsTrieTest); diff --git a/icu/icu4c/source/test/intltest/uprefstest.cpp b/icu/icu4c/source/test/intltest/uprefstest.cpp new file mode 100644 -index 0000000000000000000000000000000000000000..f76997c66c45a694398c62ed23e94d0d1d509561 +index 0000000000000000000000000000000000000000..69c5265eed1c66bb29a1d5af840da5925cb57440 --- /dev/null +++ b/icu/icu4c/source/test/intltest/uprefstest.cpp -@@ -0,0 +1,437 @@ +@@ -0,0 +1,438 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +#include "uprefstest.h" @@ -829,12 +825,12 @@ index 0000000000000000000000000000000000000000..f76997c66c45a694398c62ed23e94d0d + +#define ARRAY_SIZE 512 + -+ std::wstring UPrefsTest::language = L""; -+ std::wstring UPrefsTest::currency = L""; -+ std::wstring UPrefsTest::hourCycle = L""; -+ int32_t UPrefsTest::firstday = 0; -+ int32_t UPrefsTest::measureSystem = 0; -+ CALID UPrefsTest::calendar = 0; ++std::wstring UPrefsTest::language = L""; ++std::wstring UPrefsTest::currency = L""; ++std::wstring UPrefsTest::hourCycle = L""; ++int32_t UPrefsTest::firstday = 0; ++int32_t UPrefsTest::measureSystem = 0; ++CALID UPrefsTest::calendar = 0; + +void UPrefsTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) +{ @@ -856,7 +852,8 @@ index 0000000000000000000000000000000000000000..f76997c66c45a694398c62ed23e94d0d + TESTCASE_AUTO_END; +} + -+int32_t UPrefsTest::MockGetLocaleInfoEx(LPCWSTR lpLocaleName, LCTYPE LCType, LPWSTR lpLCData, int cchData, UErrorCode* status) ++int32_t UPrefsTest::MockGetLocaleInfoEx(LPCWSTR lpLocaleName, LCTYPE LCType, LPWSTR lpLCData, ++ int cchData, UErrorCode *status) +{ + switch (LCType) + { @@ -1237,7 +1234,7 @@ index 0000000000000000000000000000000000000000..f76997c66c45a694398c62ed23e94d0d + } +} + -+void UPrefsTest::Get12HourCycle2() ++void UPrefsTest::Get12HourCycle2() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"ja-JP"; @@ -1249,11 +1246,11 @@ index 0000000000000000000000000000000000000000..f76997c66c45a694398c62ed23e94d0d + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "ja-JP-u-ca-buddhist-cu-mxn-fw-tue-hc-h12-ms-metric"; + -+ if (uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) ++ if (uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n", uprv_strlen(languageBuffer)); + } -+ if (uprv_strcmp(expectedValue, languageBuffer) != 0) ++ if (uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } @@ -1262,7 +1259,7 @@ index 0000000000000000000000000000000000000000..f76997c66c45a694398c62ed23e94d0d \ No newline at end of file diff --git a/icu/icu4c/source/test/intltest/uprefstest.h b/icu/icu4c/source/test/intltest/uprefstest.h new file mode 100644 -index 0000000000000000000000000000000000000000..d87452e6bbde65a03df43d549e01abd3890c557c +index 0000000000000000000000000000000000000000..2f3e6515b060f962bc6afd4731aaf0033c062852 --- /dev/null +++ b/icu/icu4c/source/test/intltest/uprefstest.h @@ -0,0 +1,50 @@ diff --git a/icu-patches/patches/021-MSFT-Patch_ICU_Cldr2Icu_remove_icu4j_directory_validation.patch b/icu-patches/patches/021-MSFT-Patch_ICU_Cldr2Icu_remove_icu4j_directory_validation.patch new file mode 100644 index 00000000000..51be7eba985 --- /dev/null +++ b/icu-patches/patches/021-MSFT-Patch_ICU_Cldr2Icu_remove_icu4j_directory_validation.patch @@ -0,0 +1,20 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Arvind Oruganti +Date: Thu, 14 May 2026 14:30:00 +0530 +Subject: MSFT-PATCH: Remove icu4j directory validation from Cldr2Icu (icu4c-only fork) + +diff --git a/icu/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/Cldr2IcuCliOptions.java b/icu/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/Cldr2IcuCliOptions.java +index d9b46014438..9ff85b38d86 100644 +--- a/icu/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/Cldr2IcuCliOptions.java ++++ b/icu/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/Cldr2IcuCliOptions.java +@@ -380,7 +380,9 @@ private void validateEnvironment() { + + if (!new File(icuDir).isDirectory() + || ! new File(icuDir, "icu4c").isDirectory() +- || ! new File(icuDir, "icu4j").isDirectory() ++ // MSFT-Change: microsoft/icu fork is icu4c-only; no icu4j source tree. ++ // The Maven dependency on icu4j (used by TransformsMapper) is still ++ // resolved from ~/.m2 at runtime, so source-tree absence is harmless. + || ! new File(icuDir, "tools/cldr/cldr-to-icu").isDirectory() + || ! new File(icuDir, "tools/cldr/cldr-to-icu/pom.xml").isFile()) { + System.err.println("The `" + icuDir + "` directory does not look like a valid icu root."); diff --git a/icu-patches/patches/022-MSFT-Patch-ICU_keep_generated_test_and_shell_artifacts_LF_only.patch b/icu-patches/patches/022-MSFT-Patch-ICU_keep_generated_test_and_shell_artifacts_LF_only.patch new file mode 100644 index 00000000000..919badbd3d1 --- /dev/null +++ b/icu-patches/patches/022-MSFT-Patch-ICU_keep_generated_test_and_shell_artifacts_LF_only.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Arvind Oruganti +Date: Tue, 19 May 2026 06:45:00 +0530 +Subject: MSFT-PATCH: Keep generated ICU test and shell artifacts LF-only + +Adds checkout EOL rules for byte-compared codepoint trie TOML goldens and generated icu-config shell fragments. + +These files are consumed by Linux/WSL test paths, where CRLF checkout breaks byte comparisons or executable shell-script behavior. + +diff --git a/.gitattributes b/.gitattributes +index e7e0adbc65558ba2cc97a1d29a2a9a0aa378410b..976273bf156cbeb81e0ab0f5b8db4173fa46a1eb 100644 +--- a/.gitattributes ++++ b/.gitattributes +@@ -87,3 +87,12 @@ configure text + # Use JSONC for syntax highlighting on GitHub.com + *.json linguist-language=jsonc + ++# Codepoint trie golden tests compare bytes; keep generated TOML line endings stable. ++icu/icu4c/source/test/testdata/codepointtrie/*.toml text eol=lf ++ ++# Shell script fragments assembled into icu-config (an executable shell script). ++# They must have LF line endings so WSL/Linux can execute the generated file. ++icu/icu4c/source/config/icu-config-top text eol=lf ++icu/icu4c/source/config/icu-config-bottom text eol=lf ++icu/icu4c/source/config/mh-* text eol=lf ++ diff --git a/icu-patches/patches/023-MSFT-Patch_ICU_override_ar-SA_Saudi_Riyal_symbol.patch b/icu-patches/patches/023-MSFT-Patch_ICU_override_ar-SA_Saudi_Riyal_symbol.patch new file mode 100644 index 00000000000..43e0fdf7563 --- /dev/null +++ b/icu-patches/patches/023-MSFT-Patch_ICU_override_ar-SA_Saudi_Riyal_symbol.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Arvind Oruganti +Date: Tue, 19 May 2026 13:59:57 +0530 +Subject: MSFT-PATCH: Override ar-SA Saudi Riyal symbol + +Use the Unicode U+20C1 SAUDI RIYAL SIGN for the ar-SA SAR currency symbol and add a C API regression test for the locale-specific override. + +Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> + +diff --git a/icu/icu4c/source/data/curr/ar_SA.txt b/icu/icu4c/source/data/curr/ar_SA.txt +index 32526c8458fe1a225180d35019a84f4ea40603fe..2d969daeb3b8debcb9321dbff9598db33b673f82 100644 +--- a/icu/icu4c/source/data/curr/ar_SA.txt ++++ b/icu/icu4c/source/data/curr/ar_SA.txt +@@ -1,9 +1,11 @@ + // © 2016 and later: Unicode, Inc. and others. + // License & terms of use: http://www.unicode.org/copyright.html + // Generated using tools/cldr/cldr-to-icu/ +-/** +- * generated alias target +- */ + ar_SA{ +- ___{""} ++ Currencies{ ++ SAR{ ++ "⃁", ++ "ريال سعودي", ++ } ++ } + } +diff --git a/icu/icu4c/source/test/cintltst/currtest.c b/icu/icu4c/source/test/cintltst/currtest.c +index d8355133a18bf24410a3a99eed8b27f2657b0d76..51dff0eb0b33653ae0e9d53bf4ceeb5677d50d4c 100644 +--- a/icu/icu4c/source/test/cintltst/currtest.c ++++ b/icu/icu4c/source/test/cintltst/currtest.c +@@ -298,6 +298,26 @@ static void TestNumericCode(void) { + } + } + ++static void TestSaudiRiyalSymbol(void) { ++ UErrorCode status = U_ZERO_ERROR; ++ UChar currency[4]; ++ UBool isChoiceFormat = false; ++ int32_t len = 0; ++ static const UChar expectedSymbol[] = {0x20C1, 0}; ++ const UChar* symbol; ++ ++ u_charsToUChars("SAR", currency, UPRV_LENGTHOF(currency)); ++ symbol = ucurr_getName(currency, "ar_SA", UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &status); ++ if (U_FAILURE(status)) { ++ log_data_err("Error: ucurr_getName returned %s (Are you missing data?)\n", u_errorName(status)); ++ return; ++ } ++ if (isChoiceFormat || len != 1 || symbol == NULL || u_strncmp(symbol, expectedSymbol, len) != 0) { ++ log_err("Error: SAR symbol for ar_SA should be U+20C1. Got length=%d first=U+%04X choice=%s\n", ++ len, (len > 0 && symbol != NULL) ? symbol[0] : 0, isChoiceFormat ? "true" : "false"); ++ } ++} ++ + void addCurrencyTest(TestNode** root); + + #define TESTCASE(x) addTest(root, &x, "tsformat/currtest/" #x) +@@ -310,6 +330,7 @@ void addCurrencyTest(TestNode** root) + TESTCASE(TestFractionDigitOverride); + TESTCASE(TestPrefixSuffix); + TESTCASE(TestNumericCode); ++ TESTCASE(TestSaudiRiyalSymbol); + } + + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu/icu4c/source/common/common.vcxproj b/icu/icu4c/source/common/common.vcxproj index 81f7d0c20f9..aca55a102f9 100644 --- a/icu/icu4c/source/common/common.vcxproj +++ b/icu/icu4c/source/common/common.vcxproj @@ -41,7 +41,8 @@ $(OutDir)/icuuc.pch $(OutDir)/ $(OutDir)/ - $(OutDir)/icuuc.pdb + + $(OutDir)/icuuc$(IcuMajorVersion).pdb @@ -53,24 +54,34 @@ RBBI_DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebugDLL + + MultiThreadedDebug ..\..\$(IcuBinOutputDir)\icuuc$(IcuMajorVersion)d.dll - .\..\..\$(IcuLibOutputDir)\icuucd.pdb + + .\..\..\$(IcuLibOutputDir)\icuuc$(IcuMajorVersion)d.pdb ..\..\$(IcuLibOutputDir)\icuucd.lib + + libucrtd.lib;libucrt.lib + /DEFAULTLIB:ucrtd.lib %(AdditionalOptions) - MultiThreadedDLL + + MultiThreaded true ..\..\$(IcuBinOutputDir)\icuuc$(IcuMajorVersion).dll - .\..\..\$(IcuLibOutputDir)\icuuc.pdb + + .\..\..\$(IcuLibOutputDir)\icuuc$(IcuMajorVersion).pdb ..\..\$(IcuLibOutputDir)\icuuc.lib + + libucrtd.lib;libucrt.lib + /DEFAULTLIB:ucrt.lib %(AdditionalOptions) @@ -275,6 +286,7 @@ + @@ -394,6 +406,7 @@ + diff --git a/icu/icu4c/source/common/common_uwp.vcxproj b/icu/icu4c/source/common/common_uwp.vcxproj index 01906f3caf9..113c2418902 100644 --- a/icu/icu4c/source/common/common_uwp.vcxproj +++ b/icu/icu4c/source/common/common_uwp.vcxproj @@ -409,6 +409,7 @@ + @@ -529,6 +530,7 @@ + diff --git a/icu/icu4c/source/common/loclikely.cpp b/icu/icu4c/source/common/loclikely.cpp index 1c9447fa2bf..96a0c6baf4e 100644 --- a/icu/icu4c/source/common/loclikely.cpp +++ b/icu/icu4c/source/common/loclikely.cpp @@ -462,8 +462,8 @@ namespace { // test/intltest/regiontst.cpp from the resource data while // the test failed. const uint32_t gValidRegionMap[] = { - 0xeedf597c, 0xdeddbdef, 0x15943f3f, 0x0e00d580, - 0xb0095c00, 0x0015fb9f, 0x781c068d, 0x0340400f, + 0xeedf597c, 0xdeddbdef, 0x15843f3f, 0x0e005480, + 0xb0095c00, 0x0015fb9f, 0x7818068d, 0x0340400f, 0xf42b1d00, 0xfd4f8141, 0x25d7fffc, 0x0100084b, 0x538f3c40, 0x40000001, 0xfdf15100, 0x9fbb7ae7, 0x0410419a, 0x00408557, 0x00004002, 0x00100001, diff --git a/icu/icu4c/source/common/putil.cpp b/icu/icu4c/source/common/putil.cpp index ea15fdff0b0..307b07d087d 100644 --- a/icu/icu4c/source/common/putil.cpp +++ b/icu/icu4c/source/common/putil.cpp @@ -66,6 +66,7 @@ #include "locmap.h" #include "ucln_cmn.h" #include "charstr.h" +#include "uprefs.h" /* Include standard headers. */ #include @@ -1794,10 +1795,37 @@ The leftmost codepage (.xxx) wins. return posixID; #elif U_PLATFORM_USES_ONLY_WIN32_API -#define POSIX_LOCALE_CAPACITY 64 UErrorCode status = U_ZERO_ERROR; char *correctedPOSIXLocale = nullptr; +#if UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY + + int32_t neededBufferSize = uprefs_getBCP47Tag(nullptr, 0, &status); + MaybeStackArray windowsLocale(neededBufferSize, status); + int32_t length = uprefs_getBCP47Tag(windowsLocale.getAlias(), neededBufferSize, &status); + + if (length > 0) // If length is 0, then the call to uprefs_getBCP47Tag failed. + { + // Now normalize the resulting name + correctedPOSIXLocale = static_cast(uprv_malloc(length * 2)); + /* TODO: Should we just exit on memory allocation failure? */ + if (correctedPOSIXLocale) + { + int32_t posixLen = uloc_canonicalize(windowsLocale.getAlias(), correctedPOSIXLocale, length * 2, &status); + if (U_SUCCESS(status)) + { + *(correctedPOSIXLocale + posixLen) = 0; + gCorrectedPOSIXLocale = correctedPOSIXLocale; + gCorrectedPOSIXLocaleHeapAllocated = true; + ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup); + } + else + { + uprv_free(correctedPOSIXLocale); + } + } + } +#else // If we have already figured this out just use the cached value if (gCorrectedPOSIXLocale != nullptr) { return gCorrectedPOSIXLocale; @@ -1839,11 +1867,11 @@ The leftmost codepage (.xxx) wins. } // Now normalize the resulting name - correctedPOSIXLocale = static_cast(uprv_malloc(POSIX_LOCALE_CAPACITY + 1)); + correctedPOSIXLocale = static_cast(uprv_malloc(length * 2)); /* TODO: Should we just exit on memory allocation failure? */ if (correctedPOSIXLocale) { - int32_t posixLen = uloc_canonicalize(modifiedWindowsLocale, correctedPOSIXLocale, POSIX_LOCALE_CAPACITY, &status); + int32_t posixLen = uloc_canonicalize(modifiedWindowsLocale, correctedPOSIXLocale, length * 2, &status); if (U_SUCCESS(status)) { *(correctedPOSIXLocale + posixLen) = 0; @@ -1857,6 +1885,7 @@ The leftmost codepage (.xxx) wins. } } } +#endif // If unable to find a locale we can agree upon, use en-US by default if (gCorrectedPOSIXLocale == nullptr) { diff --git a/icu/icu4c/source/common/sources.txt b/icu/icu4c/source/common/sources.txt index 5b1c5e262ea..cfcfd95df56 100644 --- a/icu/icu4c/source/common/sources.txt +++ b/icu/icu4c/source/common/sources.txt @@ -163,6 +163,7 @@ unistr_titlecase_brkiter.cpp unorm.cpp unormcmp.cpp uobject.cpp +uprefs.cpp uprops.cpp ures_cnv.cpp uresbund.cpp diff --git a/icu/icu4c/source/common/ucln_cmn.cpp b/icu/icu4c/source/common/ucln_cmn.cpp index c63bd221929..6d7d2536381 100644 --- a/icu/icu4c/source/common/ucln_cmn.cpp +++ b/icu/icu4c/source/common/ucln_cmn.cpp @@ -36,8 +36,9 @@ static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON]; The cleanup order is important in this function. Please be sure that you have read ucln.h ************************************************/ +// MSFT-Change: Make u_cleanup a no-op for the Windows OS ICU version. U_CAPI void U_EXPORT2 -u_cleanup() +uprv_u_cleanup() { UTRACE_ENTRY_OC(UTRACE_U_CLEANUP); icu::umtx_lock(nullptr); /* Force a memory barrier, so that we are sure to see */ @@ -52,6 +53,31 @@ u_cleanup() /*#endif*/ } +U_CAPI void U_EXPORT2 +u_cleanup() +{ +// When ICU is built as an OS component for Windows, we make the public function u_cleanup +// effectively a no-op because of the following: +// - It is not thread-safe and *forcefully* unloads the ICU data file. +// - The ICU library can simultaneously be used by other threads when this happens, +// either by Windows.Globalization, or by sorting functions when ICU sorting is default. +// - This means an App can call the function at any time, which will cause random crashes. :( +// +// We don't completely remove the functionality though, as we still want/need to be able to +// unload resources when the ICU DLL is unloaded. Instead we make it a private (uprv) function +// so that the combined DLL can still call it, and we don't export it in the DEF file. +// +// Note: We don't unconditionally do this though, as we don't want to alter the behavior of the +// public function when ICU when used/consumed in a Nuget package (for example). +// +#if defined(ICU_DATA_DIR_WINDOWS) + ((void)0); // no-op. + return; +#else + uprv_u_cleanup(); +#endif +} + U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType libType) { if (gLibCleanupFunctions[libType]) diff --git a/icu/icu4c/source/common/ucmndata.h b/icu/icu4c/source/common/ucmndata.h index 486b4fd7b5f..36f82f6f9ea 100644 --- a/icu/icu4c/source/common/ucmndata.h +++ b/icu/icu4c/source/common/ucmndata.h @@ -30,8 +30,12 @@ #include "unicode/udata.h" #include "umapfile.h" - -#define COMMON_DATA_NAME U_ICUDATA_NAME +// MSFT-Change: In the Windows OS ICU build, we only have one data package, and we use a versionless name in filename. +#if defined(ICU_DATA_DIR_WINDOWS) +# define COMMON_DATA_NAME "icudtl" +#else +# define COMMON_DATA_NAME U_ICUDATA_NAME +#endif typedef struct { uint16_t headerSize; diff --git a/icu/icu4c/source/common/udata.cpp b/icu/icu4c/source/common/udata.cpp index b9b737f177e..38a501719e3 100644 --- a/icu/icu4c/source/common/udata.cpp +++ b/icu/icu4c/source/common/udata.cpp @@ -809,6 +809,16 @@ openCommonData(const char *path, /* Path from OpenChoice? */ *----------------------------------------------------------------------*/ static UBool extendICUData(UErrorCode *pErr) { +// MSFT-Change: For the Windows OS build of ICU, we only have one data file +// and we don't use the extended data at all. We make this function a no-op +// in order to save a few cycles for perf, but more importantly so that +// we don't try to load a versioned data file (ex: icudt78l.dat) after +// already loading the non-versioned common data file. +#if defined(ICU_DATA_DIR_WINDOWS) + (void)pErr; // suppress unused variable. + return false; +#endif + UDataMemory *pData; UDataMemory copyPData; UBool didUpdate = false; diff --git a/icu/icu4c/source/common/unicode/putil.h b/icu/icu4c/source/common/unicode/putil.h index 500c21252fc..c0b34556ebc 100644 --- a/icu/icu4c/source/common/unicode/putil.h +++ b/icu/icu4c/source/common/unicode/putil.h @@ -42,6 +42,9 @@ * functions may have to be re-implemented. */ +//IGNORE_WINDOWS_HEADERS_START +// MSFT-Change: The Windows OS version of ICU uses a single fixed data file. + /** * Return the ICU data directory. * The data directory is where common format ICU data files (.dat files) @@ -112,7 +115,7 @@ U_CAPI const char * U_EXPORT2 u_getTimeZoneFilesDirectory(UErrorCode *status); U_CAPI void U_EXPORT2 u_setTimeZoneFilesDirectory(const char *path, UErrorCode *status); #endif /* U_HIDE_INTERNAL_API */ - +// MSFT-TODO: Should these be considered for Windows? /** * @{ * Filesystem file and path separator characters. @@ -134,6 +137,7 @@ U_CAPI void U_EXPORT2 u_setTimeZoneFilesDirectory(const char *path, UErrorCode * # define U_FILE_ALT_SEP_STRING "/" # define U_PATH_SEP_STRING ":" #endif +//IGNORE_WINDOWS_HEADERS_END /** @} */ diff --git a/icu/icu4c/source/common/unicode/uchar.h b/icu/icu4c/source/common/unicode/uchar.h index d33b8cf7f3c..047d61c8122 100644 --- a/icu/icu4c/source/common/unicode/uchar.h +++ b/icu/icu4c/source/common/unicode/uchar.h @@ -49,6 +49,10 @@ typedef struct USet USet; U_CDECL_BEGIN +//IGNORE_WINDOWS_HEADERS_START +// MSFT-Change: The value of these macros can change at runtime, so the API u_getUnicodeVersion +// should be used instead of any version macro. + /*==========================================================================*/ /* Unicode version number */ /*==========================================================================*/ @@ -63,6 +67,8 @@ U_CDECL_BEGIN */ #define U_UNICODE_VERSION "17.0" +//IGNORE_WINDOWS_HEADERS_END + /** * \file * \brief C API: Unicode Properties diff --git a/icu/icu4c/source/common/unicode/uconfig.h b/icu/icu4c/source/common/unicode/uconfig.h index c0488d502bf..f339dec982f 100644 --- a/icu/icu4c/source/common/unicode/uconfig.h +++ b/icu/icu4c/source/common/unicode/uconfig.h @@ -45,6 +45,10 @@ * @stable ICU 2.4 */ +//IGNORE_WINDOWS_HEADERS_START +// MSFT-Change: Since these are compile time settings, it doesn't make sense to +// load a user config header in the Windows OS SDK version. + /** * If this switch is defined, ICU will attempt to load a header file named "uconfig_local.h" * prior to determining default settings for uconfig variables. @@ -55,6 +59,8 @@ #include "uconfig_local.h" #endif +//IGNORE_WINDOWS_HEADERS_END + /** * \def U_DEBUG * Determines whether to include debugging code. @@ -379,6 +385,9 @@ # define UCONFIG_MSGPAT_DEFAULT_APOSTROPHE_MODE UMSGPAT_APOS_DOUBLE_OPTIONAL #endif +//IGNORE_WINDOWS_HEADERS_START +// MSFT-Change: We always use the OS LCID mapping API for the Windows OS build of ICU. + /** * \def UCONFIG_USE_WINDOWS_LCID_MAPPING_API * On platforms where U_PLATFORM_HAS_WIN32_API is true, this switch determines @@ -391,6 +400,24 @@ # define UCONFIG_USE_WINDOWS_LCID_MAPPING_API 1 #endif +/** + * \def UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY + * On Windows platforms (ie: U_PLATFORM_HAS_WIN32_API is true), this switch enables ICU to + * detect additional user preferences by setting BCP47 Unicode extension within the default locale. + * This includes information such as calendar, currency, hour cycle, among others. + * + * If this switch is off (or set to 0) then the default behavior of only detecting the language + * and country/region occurs. + * + * For example, the default locale may be detected as "es-MX-u-hc-h24", instead of "es-MX", + * if the user has selected a 24 hour clock option. +*/ +#ifndef UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY +# define UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY 1 +#endif + +//IGNORE_WINDOWS_HEADERS_END + /* i18n library switches ---------------------------------------------------- */ /** diff --git a/icu/icu4c/source/common/unicode/unistr.h b/icu/icu4c/source/common/unicode/unistr.h index 161b84527a6..145bb8ea3ef 100644 --- a/icu/icu4c/source/common/unicode/unistr.h +++ b/icu/icu4c/source/common/unicode/unistr.h @@ -60,6 +60,9 @@ class Edits; U_NAMESPACE_END +//IGNORE_WINDOWS_HEADERS_START +// MSFT-Change: Hiding the @internal API below, since we don't expose the C++ UnicodeString. + // Not #ifndef U_HIDE_INTERNAL_API because UnicodeString needs the UStringCaseMapper. /** * Internal string case mapping function type. @@ -77,6 +80,8 @@ UStringCaseMapper(int32_t caseLocale, uint32_t options, icu::Edits *edits, UErrorCode &errorCode); +//IGNORE_WINDOWS_HEADERS_END + U_NAMESPACE_BEGIN class Locale; // unicode/locid.h diff --git a/icu/icu4c/source/common/unicode/utypes.h b/icu/icu4c/source/common/unicode/utypes.h index f53b7536f20..0f6bc70fd54 100644 --- a/icu/icu4c/source/common/unicode/utypes.h +++ b/icu/icu4c/source/common/unicode/utypes.h @@ -104,6 +104,11 @@ /** @} */ +//IGNORE_WINDOWS_HEADERS_START +// MSFT-Change: For the Windows OS version of ICU, it doesn't make sense to expose these +// constants which are only for loading the main ICU data file. We also don't +// support using a data DLL either, so omit them from the Windows SDK header. + /*===========================================================================*/ /* ICUDATA naming scheme */ /*===========================================================================*/ @@ -191,6 +196,8 @@ #endif #endif /* U_HIDE_INTERNAL_API */ +//IGNORE_WINDOWS_HEADERS_END + /** * \def NULL * Define NULL if necessary, to nullptr for C++ and to ((void *)0) for C. diff --git a/icu/icu4c/source/common/unicode/uversion.h b/icu/icu4c/source/common/unicode/uversion.h index 450794ac1ba..dc5ed687cf5 100644 --- a/icu/icu4c/source/common/unicode/uversion.h +++ b/icu/icu4c/source/common/unicode/uversion.h @@ -58,6 +58,10 @@ */ typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH]; +//IGNORE_WINDOWS_HEADERS_START +// MSFT-Change: Since the Windows OS ICU headers are for C APIs only, we don't +// need or want any C++ namespace support. + /*===========================================================================*/ /* C++ namespace if supported. Versioned unless versioning is disabled. */ /*===========================================================================*/ @@ -184,6 +188,8 @@ namespace U_HEADER_ONLY_NAMESPACE {} #endif /* __cplusplus */ +//IGNORE_WINDOWS_HEADERS_END + /*===========================================================================*/ /* General version helper functions. Definitions in putil.c */ /*===========================================================================*/ diff --git a/icu/icu4c/source/common/uprefs.cpp b/icu/icu4c/source/common/uprefs.cpp new file mode 100644 index 00000000000..d9304a11de0 --- /dev/null +++ b/icu/icu4c/source/common/uprefs.cpp @@ -0,0 +1,553 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "uprefs.h" +#if U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY +#include "unicode/ustring.h" +#include "cmemory.h" +#include "charstr.h" +#include "cstring.h" +#include "cwchar.h" +#include + +U_NAMESPACE_USE + +// Older versions of the Windows SDK don’t have definitions for calendar types that were added later on. +// (For example, the Windows 7 SDK doesn’t have CAL_PERSIAN). +// So we’ll need to provide our own definitions for some of them. +// Note that on older versions of the OS these values won't ever be returned by the platform APIs, so providing our own definitions is fine. +#ifndef CAL_PERSIAN +#define CAL_PERSIAN 22 // Persian (Solar Hijri) calendar +#endif + +#define RETURN_FAILURE_STRING_WITH_STATUS_IF(condition, error, status) \ + if (condition) \ + { \ + *status = error; \ + return CharString(); \ + } + +#define RETURN_FAILURE_WITH_STATUS_IF(condition, error, status) \ + if (condition) \ + { \ + *status = error; \ + return 0; \ + } + +#define RETURN_VALUE_IF(condition, value) \ + if (condition) \ + { \ + return value; \ + } + +#define RETURN_WITH_ALLOCATION_ERROR_IF_FAILED(status) \ + if (U_FAILURE(*status)) \ + { \ + *status = U_MEMORY_ALLOCATION_ERROR; \ + return CharString(); \ + } \ +// ------------------------------------------------------- +// ----------------- MAPPING FUNCTIONS-------------------- +// ------------------------------------------------------- + +// Maps from a NLS Calendar ID (CALID) to a BCP47 Unicode Extension calendar identifier. +// +// We map the NLS CALID from GetLocaleInfoEx to the calendar identifier +// used in BCP47 tag with Unicode Extensions. +// +// This does not return a full nor valid BCP47Tag, it only returns the option that the BCP47 tag +// would return after the "ca-" part +// +// For example: +// CAL_GREGORIAN would return "gregory". +// CAL_HIJRI would return "islamic". +// +// These could be used in a BCP47 tag like this: "en-US-u-ca-gregory". +// Note that there are some NLS calendars that are not supported with the BCP47 U extensions, +// and vice-versa. +// +// NLS CALID reference:https://docs.microsoft.com/en-us/windows/win32/intl/calendar-identifiers +CharString getCalendarBCP47FromNLSType(int32_t calendar, UErrorCode* status) +{ + switch(calendar) + { + case CAL_GREGORIAN: + case CAL_GREGORIAN_US: + case CAL_GREGORIAN_ME_FRENCH: + case CAL_GREGORIAN_ARABIC: + case CAL_GREGORIAN_XLIT_ENGLISH: + case CAL_GREGORIAN_XLIT_FRENCH: + return CharString("gregory", *status); + + case CAL_JAPAN: + return CharString("japanese", *status); + + case CAL_TAIWAN: + return CharString("roc", *status); + + case CAL_KOREA: + return CharString("dangi", *status); + + case CAL_HIJRI: + return CharString("islamic", *status); + + case CAL_THAI: + return CharString("buddhist", *status); + + case CAL_HEBREW: + return CharString("hebrew", *status); + + case CAL_PERSIAN: + return CharString("persian", *status); + + case CAL_UMALQURA: + return CharString("islamic-umalqura", *status); + + default: + return CharString(); + } +} + +// Maps from a NLS Alternate sorting system to a BCP47 U extension sorting system. +// +// We map the alternate sorting method from GetLocaleInfoEx to the sorting method +// used in BCP47 tag with Unicode Extensions. +// +// This does not return a full nor valid BCP47Tag, it only returns the option that the BCP47 tag +// would return after the "co-" part +// +// For example: +// "phoneb" (parsed from "de-DE_phoneb") would return "phonebk". +// "radstr" (parsed from "ja-JP_radstr") would return "unihan". +// +// These could be used in a BCP47 tag like this: "de-DE-u-co-phonebk". +// Note that there are some NLS Alternate sort methods that are not supported with the BCP47 U extensions, +// and vice-versa. +CharString getSortingSystemBCP47FromNLSType(const wchar_t* sortingSystem, UErrorCode* status) +{ + if (wcscmp(sortingSystem, L"phoneb") == 0) // Phonebook style ordering (such as in German) + { + return CharString("phonebk", *status); + } + else if (wcscmp(sortingSystem, L"tradnl") == 0) // Traditional style ordering (such as in Spanish) + { + return CharString("trad", *status); + } + else if (wcscmp(sortingSystem, L"stroke") == 0) // Pinyin ordering for Latin, stroke order for CJK characters (used in Chinese) + { + return CharString("stroke", *status); + } + else if (wcscmp(sortingSystem, L"radstr") == 0) // Pinyin ordering for Latin, Unihan radical-stroke ordering for CJK characters (used in Chinese) + { + return CharString("unihan", *status); + } + else if (wcscmp(sortingSystem, L"pronun") == 0) // Phonetic ordering (sorting based on pronunciation) + { + return CharString("phonetic", *status); + } + else + { + return CharString(); + } +} + +// Maps from a NLS first day of week value to a BCP47 U extension first day of week. +// +// NLS defines: +// 0 -> Monday, 1 -> Tuesday, ... 5 -> Saturday, 6 -> Sunday +// +// We map the first day of week from GetLocaleInfoEx to the first day of week +// used in BCP47 tag with Unicode Extensions. +// +// This does not return a full nor valid BCP47Tag, it only returns the option that the BCP47 tag +// would return after the "fw-" part +// +// For example: +// 1 (Tuesday) would return "tue". +// 6 (Sunday) would return "sun". +// +// These could be used in a BCP47 tag like this: "en-US-u-fw-sun". +CharString getFirstDayBCP47FromNLSType(int32_t firstday, UErrorCode* status) +{ + switch(firstday) + { + case 0: + return CharString("mon", *status); + + case 1: + return CharString("tue", *status); + + case 2: + return CharString("wed", *status); + + case 3: + return CharString("thu", *status); + + case 4: + return CharString("fri", *status); + + case 5: + return CharString("sat", *status); + + case 6: + return CharString("sun", *status); + + default: + return CharString(); + } +} + +// Maps from a NLS Measurement system to a BCP47 U extension measurement system. +// +// NLS defines: +// 0 -> Metric system, 1 -> U.S. System +// +// This does not return a full nor valid BCP47Tag, it only returns the option that the BCP47 tag +// would return after the "ms-" part +// +// For example: +// 0 (Metric) would return "metric". +// 6 (U.S. System) would return "ussystem". +// +// These could be used in a BCP47 tag like this: "en-US-u-ms-metric". +CharString getMeasureSystemBCP47FromNLSType(int32_t measureSystem, UErrorCode *status) +{ + switch(measureSystem) + { + case 0: + return CharString("metric", *status); + case 1: + return CharString("ussystem", *status); + default: + return CharString(); + } +} + +// ------------------------------------------------------- +// --------------- END OF MAPPING FUNCTIONS -------------- +// ------------------------------------------------------- + +// ------------------------------------------------------- +// ------------------ HELPER FUCTIONS ------------------- +// ------------------------------------------------------- + +// Return the CLDR "h12" or "h23" format for the 12 or 24 hour clock. +// NLS only gives us a "time format" of a form similar to "h:mm:ss tt" +// The NLS "h" is 12 hour, and "H" is 24 hour, so we'll scan for the +// first h or H. +// Note that the NLS string could have sections escaped with single +// quotes, so be sure to skip those parts. Eg: "'Hours:' h:mm:ss" +// would skip the "H" in 'Hours' and use the h in the actual pattern. +CharString get12_or_24hourFormat(wchar_t* hourFormat, UErrorCode* status) +{ + bool isInEscapedString = false; + const int32_t hourLength = static_cast(uprv_wcslen(hourFormat)); + for (int32_t i = 0; i < hourLength; i++) + { + // Toggle escaped flag if in ' quoted portion + if (hourFormat[i] == L'\'') + { + isInEscapedString = !isInEscapedString; + } + + if (!isInEscapedString) + { + // Check for both so we can escape early + if (hourFormat[i] == L'H') + { + return CharString("h23", *status); + } + + if (hourFormat[i] == L'h') + { + return CharString("h12", *status); + } + } + } + // default to a 24 hour clock as that's more common worldwide + return CharString("h23", *status); +} + +UErrorCode getUErrorCodeFromLastError() +{ + DWORD error = GetLastError(); + switch(error) + { + case ERROR_INSUFFICIENT_BUFFER: + return U_BUFFER_OVERFLOW_ERROR; + + case ERROR_INVALID_FLAGS: + case ERROR_INVALID_PARAMETER: + return U_ILLEGAL_ARGUMENT_ERROR; + + case ERROR_OUTOFMEMORY: + return U_MEMORY_ALLOCATION_ERROR; + + default: + return U_INTERNAL_PROGRAM_ERROR; + } +} + +int32_t GetLocaleInfoExWrapper(LPCWSTR lpLocaleName, LCTYPE LCType, LPWSTR lpLCData, int cchData, UErrorCode* status) +{ + RETURN_VALUE_IF(U_FAILURE(*status), 0); + +#ifndef UPREFS_TEST + *status = U_ZERO_ERROR; + int32_t result = GetLocaleInfoEx(lpLocaleName, LCType, lpLCData, cchData); + + if (result == 0) + { + *status = getUErrorCodeFromLastError(); + } + return result; +#else + #include "uprefstest.h" + UPrefsTest prefTests; + return prefTests.MockGetLocaleInfoEx(lpLocaleName, LCType, lpLCData, cchData, status); +#endif +} + +// Copies a string to a buffer if its size allows it and returns the size. +// The returned needed buffer size includes the terminating \0 null character. +// If the buffer's size is set to 0, the needed buffer size is returned before copying the string. +int32_t checkBufferCapacityAndCopy(const char* uprefsString, char* uprefsBuffer, int32_t bufferSize, UErrorCode* status) +{ + int32_t neededBufferSize = static_cast(uprv_strlen(uprefsString) + 1); + + RETURN_VALUE_IF(bufferSize == 0, neededBufferSize); + RETURN_FAILURE_WITH_STATUS_IF(neededBufferSize > bufferSize, U_BUFFER_OVERFLOW_ERROR, status); + + uprv_strcpy(uprefsBuffer, uprefsString); + + return neededBufferSize; +} + +CharString getLocaleBCP47Tag_impl(UErrorCode* status, bool getSorting) +{ + // First part of a bcp47 tag looks like an NLS user locale, so we get the NLS user locale. + int32_t neededBufferSize = GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, nullptr, 0, status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + MaybeStackArray NLSLocale(neededBufferSize, *status); + RETURN_WITH_ALLOCATION_ERROR_IF_FAILED(status); + + int32_t result = GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, NLSLocale.getAlias(), neededBufferSize, status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + if (getSorting) //We determine if we want the locale (for example, en-US) or the sorting method (for example, phonebk) + { + // We use LOCALE_SNAME to get the sorting method (if any). So we need to keep + // only the sorting bit after the _, removing the locale name. + // Example: from "de-DE_phoneb" we only want "phoneb" + const wchar_t * startPosition = wcschr(NLSLocale.getAlias(), L'_'); + + // Note: not finding a "_" is not an error, it means the user has not selected an alternate sorting method, which is fine. + if (startPosition != nullptr) + { + CharString sortingSystem = getSortingSystemBCP47FromNLSType(startPosition + 1, status); + + if (sortingSystem.length() == 0) + { + *status = U_UNSUPPORTED_ERROR; + return CharString(); + } + return sortingSystem; + } + } + else + { + // The NLS locale may include a non-default sort, such as de-DE_phoneb. We only want the locale name before the _. + wchar_t * position = wcschr(NLSLocale.getAlias(), L'_'); + if (position != nullptr) + { + *position = L'\0'; + } + + CharString languageTag; + int32_t resultCapacity = 0; + languageTag.getAppendBuffer(neededBufferSize, neededBufferSize, resultCapacity, *status); + RETURN_WITH_ALLOCATION_ERROR_IF_FAILED(status); + + int32_t unitsWritten = 0; + u_strToUTF8(languageTag.data(), neededBufferSize, &unitsWritten, reinterpret_cast(NLSLocale.getAlias()), neededBufferSize, status); + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + return languageTag; + } + + return CharString(); +} + +CharString getCalendarSystem_impl(UErrorCode* status) +{ + int32_t NLSCalendar = 0; + + GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER, reinterpret_cast(&NLSCalendar), sizeof(NLSCalendar) / sizeof(wchar_t), status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + CharString calendar(getCalendarBCP47FromNLSType(NLSCalendar, status), *status); + RETURN_FAILURE_STRING_WITH_STATUS_IF(calendar.length() == 0, U_UNSUPPORTED_ERROR, status); + + return calendar; +} + +CharString getCurrencyCode_impl(UErrorCode* status) +{ + int32_t neededBufferSize = GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_SINTLSYMBOL, nullptr, 0, status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + MaybeStackArray NLScurrencyData(neededBufferSize, *status); + RETURN_WITH_ALLOCATION_ERROR_IF_FAILED(status); + + int32_t result = GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_SINTLSYMBOL, NLScurrencyData.getAlias(), neededBufferSize, status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + MaybeStackArray currency(neededBufferSize, *status); + RETURN_WITH_ALLOCATION_ERROR_IF_FAILED(status); + + int32_t unitsWritten = 0; + u_strToUTF8(currency.getAlias(), neededBufferSize, &unitsWritten, reinterpret_cast(NLScurrencyData.getAlias()), neededBufferSize, status); + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + if (unitsWritten == 0) + { + *status = U_INTERNAL_PROGRAM_ERROR; + return CharString(); + } + + // Since we retreived the currency code in caps, we need to make it lowercase for it to be in CLDR BCP47 U extensions format. + T_CString_toLowerCase(currency.getAlias()); + + return CharString(currency.getAlias(), neededBufferSize, *status); +} + +CharString getFirstDayOfWeek_impl(UErrorCode* status) +{ + int32_t NLSfirstDay = 0; + GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER, reinterpret_cast(&NLSfirstDay), sizeof(NLSfirstDay) / sizeof(wchar_t), status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + CharString firstDay = getFirstDayBCP47FromNLSType(NLSfirstDay, status); + RETURN_FAILURE_STRING_WITH_STATUS_IF(firstDay.length() == 0, U_UNSUPPORTED_ERROR, status); + + return firstDay; +} + +CharString getHourCycle_impl(UErrorCode* status) +{ + int32_t neededBufferSize = GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_STIMEFORMAT, nullptr, 0, status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + MaybeStackArray NLShourCycle(neededBufferSize, *status); + RETURN_WITH_ALLOCATION_ERROR_IF_FAILED(status); + + int32_t result = GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_STIMEFORMAT, NLShourCycle.getAlias(), neededBufferSize, status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + CharString hourCycle = get12_or_24hourFormat(NLShourCycle.getAlias(), status); + if (hourCycle.length() == 0) + { + *status = U_INTERNAL_PROGRAM_ERROR; + return CharString(); + } + return hourCycle; +} + +CharString getMeasureSystem_impl(UErrorCode* status) +{ + int32_t NLSmeasureSystem = 0; + GetLocaleInfoExWrapper(LOCALE_NAME_USER_DEFAULT, LOCALE_IMEASURE | LOCALE_RETURN_NUMBER, reinterpret_cast(&NLSmeasureSystem), sizeof(NLSmeasureSystem) / sizeof(wchar_t), status); + + RETURN_VALUE_IF(U_FAILURE(*status), CharString()); + + CharString measureSystem = getMeasureSystemBCP47FromNLSType(NLSmeasureSystem, status); + RETURN_FAILURE_STRING_WITH_STATUS_IF(measureSystem.length() == 0, U_UNSUPPORTED_ERROR, status); + + return measureSystem; +} + +void appendIfDataNotEmpty(CharString& dest, const char* firstData, const char* secondData, bool& warningGenerated, UErrorCode* status) +{ + if (*status == U_UNSUPPORTED_ERROR) + { + warningGenerated = true; + *status = U_ZERO_ERROR; + } + + if (uprv_strlen(secondData) != 0) + { + dest.append(firstData, *status); + dest.append(secondData, *status); + } +} +// ------------------------------------------------------- +// --------------- END OF HELPER FUNCTIONS --------------- +// ------------------------------------------------------- + + +// ------------------------------------------------------- +// ---------------------- APIs --------------------------- +// ------------------------------------------------------- + +// Gets the valid and canonical BCP47 tag with the user settings for Language, Calendar, Sorting, Currency, +// First day of week, Hour cycle, and Measurement system. +// Calls all of the other APIs +// Returns the needed buffer size for the BCP47 Tag. +int32_t uprefs_getBCP47Tag(char* uprefsBuffer, int32_t bufferSize, UErrorCode* status) +{ + RETURN_FAILURE_WITH_STATUS_IF(uprefsBuffer == nullptr && bufferSize != 0, U_ILLEGAL_ARGUMENT_ERROR, status); + + *status = U_ZERO_ERROR; + CharString BCP47Tag; + bool warningGenerated = false; + + CharString languageTag = getLocaleBCP47Tag_impl(status, false); + RETURN_VALUE_IF(U_FAILURE(*status), 0); + BCP47Tag.append(languageTag.data(), *status); + BCP47Tag.append("-u", *status); + + CharString calendar = getCalendarSystem_impl(status); + RETURN_VALUE_IF(U_FAILURE(*status) && *status != U_UNSUPPORTED_ERROR, 0); + appendIfDataNotEmpty(BCP47Tag, "-ca-", calendar.data(), warningGenerated, status); + + CharString sortingSystem = getLocaleBCP47Tag_impl(status, true); + RETURN_VALUE_IF(U_FAILURE(*status) && *status != U_UNSUPPORTED_ERROR, 0); + appendIfDataNotEmpty(BCP47Tag, "-co-", sortingSystem.data(), warningGenerated, status); + + CharString currency = getCurrencyCode_impl(status); + RETURN_VALUE_IF(U_FAILURE(*status) && *status != U_UNSUPPORTED_ERROR, 0); + appendIfDataNotEmpty(BCP47Tag, "-cu-", currency.data(), warningGenerated, status); + + CharString firstDay = getFirstDayOfWeek_impl(status); + RETURN_VALUE_IF(U_FAILURE(*status) && *status != U_UNSUPPORTED_ERROR, 0); + appendIfDataNotEmpty(BCP47Tag, "-fw-", firstDay.data(), warningGenerated, status); + + CharString hourCycle = getHourCycle_impl(status); + RETURN_VALUE_IF(U_FAILURE(*status) && *status != U_UNSUPPORTED_ERROR, 0); + appendIfDataNotEmpty(BCP47Tag, "-hc-", hourCycle.data(), warningGenerated, status); + + CharString measureSystem = getMeasureSystem_impl(status); + RETURN_VALUE_IF(U_FAILURE(*status) && *status != U_UNSUPPORTED_ERROR, 0); + appendIfDataNotEmpty(BCP47Tag, "-ms-", measureSystem.data(), warningGenerated, status); + + if (warningGenerated) + { + *status = U_USING_FALLBACK_WARNING; + } + + return checkBufferCapacityAndCopy(BCP47Tag.data(), uprefsBuffer, bufferSize, status); +} + +// ------------------------------------------------------- +// ---------------------- END OF APIs -------------------- +// ------------------------------------------------------- + +#endif // U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY \ No newline at end of file diff --git a/icu/icu4c/source/common/uprefs.h b/icu/icu4c/source/common/uprefs.h new file mode 100644 index 00000000000..08ecd86189b --- /dev/null +++ b/icu/icu4c/source/common/uprefs.h @@ -0,0 +1,29 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#ifndef UPREFS_H +#define UPREFS_H + +#include "unicode/platform.h" +#include "unicode/utypes.h" +#if U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY + +/** +* Gets the valid and canonical BCP47 tag with the user settings for Language, Calendar, Sorting, Currency, +* First day of week, Hour cycle, and Measurement system when available. +* +* @param uprefsBuffer Pointer to a buffer in which this function retrieves the BCP47 tag. +* This pointer is not used if bufferSize is set to 0. +* @param bufferSize Size, in characters, of the data buffer indicated by uprefsBuffer. Alternatively, the application +* can set this parameter to 0. In this case, the function does not use the uprefsBuffer parameter +* and returns the required buffer size, including the terminating null character. +* @param status: Pointer to a UErrorCode. The resulting value will be U_ZERO_ERROR if the call was successful or will +* contain an error or warning code. If the status is U_USING_FALLBACK_WARNING, it means at least one of the + settings was not succesfully mapped between NLS and CLDR, so it will not be shown on the BCP47 tag. +* @return The needed buffer size, including the terminating \0 null character if the call was successful, should be ignored +* if status was not U_ZERO_ERROR. +*/ +int32_t uprefs_getBCP47Tag(char* uprefsBuffer, int32_t bufferSize, UErrorCode* status); + +#endif //U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY +#endif //UPREFS_H \ No newline at end of file diff --git a/icu/icu4c/source/config/dist.mk b/icu/icu4c/source/config/dist.mk index a8bda27d8cd..319470143c6 100644 --- a/icu/icu4c/source/config/dist.mk +++ b/icu/icu4c/source/config/dist.mk @@ -37,7 +37,9 @@ DISTY_DATA_ZIP=$(DISTY_FILE_DIR)/$(DISTY_PREFIX)-data.zip DISTY_DAT:=$(firstword $(wildcard data/out/tmp/icudt$(SO_TARGET_VERSION_MAJOR)*.dat)) DISTY_FILES_SRC=$(DISTY_FILE_TGZ) $(DISTY_FILE_ZIP) -DISTY_FILES=$(DISTY_FILES_SRC) $(DISTY_DOC_ZIP) +# MSFT-Change: We only want the tgz for now, as we don't currently build the docs. +#DISTY_FILES=$(DISTY_FILES_SRC) $(DISTY_DOC_ZIP) +DISTY_FILES=$(DISTY_FILES_SRC) # colon-equals because we want to run this once! EXCLUDES_FILE:=$(shell mktemp) @@ -66,7 +68,8 @@ $(DISTY_FILE_TGZ) $(DISTY_FILE_ZIP) $(DISTY_DATA_ZIP): $(DISTY_DAT) $(DISTY_TMP @echo Export icu4c@$(GITVER) to "$(DISTY_TMP)/icu" -$(RMV) $(DISTY_FILE) $(DISTY_TMP) $(MKINSTALLDIRS) $(DISTY_TMP) - ( cd $(ICU4CTOP)/.. && git archive --format=tar --prefix=icu/ HEAD:icu4c/ ) | ( cd "$(DISTY_TMP)" && tar xf - ) + # MSFT-Change: Adjust the path for the GitHub repo location. + ( cd $(ICU4CTOP)/../.. && git archive --format=tar --prefix=icu/ HEAD:icu/icu4c/ ) | ( cd "$(DISTY_TMP)" && tar xf - ) # special handling for LICENSE file. The symlinks will be included as files by tar and zip. cp -fv $(ICU4CTOP)/LICENSE "$(DISTY_TMP)/LICENSE" # Copy top-level testdata directory so it's a sibling of the source/ directory diff --git a/icu/icu4c/source/data/build.xml b/icu/icu4c/source/data/build.xml index a7efc0675b1..3e3c0425703 100644 --- a/icu/icu4c/source/data/build.xml +++ b/icu/icu4c/source/data/build.xml @@ -43,7 +43,8 @@ - + + diff --git a/icu/icu4c/source/data/curr/ar_SA.txt b/icu/icu4c/source/data/curr/ar_SA.txt index 32526c8458f..2d969daeb3b 100644 --- a/icu/icu4c/source/data/curr/ar_SA.txt +++ b/icu/icu4c/source/data/curr/ar_SA.txt @@ -1,9 +1,11 @@ // © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html // Generated using tools/cldr/cldr-to-icu/ -/** - * generated alias target - */ ar_SA{ - ___{""} + Currencies{ + SAR{ + "⃁", + "ريال سعودي", + } + } } diff --git a/icu/icu4c/source/data/misc/supplementalData.txt b/icu/icu4c/source/data/misc/supplementalData.txt index 5c462722703..ecac0693388 100644 --- a/icu/icu4c/source/data/misc/supplementalData.txt +++ b/icu/icu4c/source/data/misc/supplementalData.txt @@ -11530,17 +11530,14 @@ supplementalData:table(nofallback){ "cyzzzz", "czzzzz", "dezzzz", - "dgzzzz", "djzzzz", "dkzzzz", "dmzzzz", "dozzzz", "dzzzzz", - "eazzzz", "eczzzz", "eezzzz", "egzzzz", - "ehzzzz", "erzzzz", "eszzzz", "etzzzz", @@ -11575,7 +11572,6 @@ supplementalData:table(nofallback){ "hrzzzz", "htzzzz", "huzzzz", - "iczzzz", "idzzzz", "iezzzz", "ilzzzz", diff --git a/icu/icu4c/source/i18n/i18n.vcxproj b/icu/icu4c/source/i18n/i18n.vcxproj index 9803e1d1d5b..2a674773021 100644 --- a/icu/icu4c/source/i18n/i18n.vcxproj +++ b/icu/icu4c/source/i18n/i18n.vcxproj @@ -42,7 +42,8 @@ $(OutDir)/icuin.pch $(OutDir)/ $(OutDir)/ - $(OutDir)/icuin.pdb + + $(OutDir)/icuin$(IcuMajorVersion).pdb ../common;%(AdditionalIncludeDirectories) @@ -54,26 +55,36 @@ - MultiThreadedDebugDLL + + MultiThreadedDebug icuucd.lib;%(AdditionalDependencies) ..\..\$(IcuBinOutputDir)\icuin$(IcuMajorVersion)d.dll - .\..\..\$(IcuLibOutputDir)\icuind.pdb + + .\..\..\$(IcuLibOutputDir)\icuin$(IcuMajorVersion)d.pdb ..\..\$(IcuLibOutputDir)\icuind.lib + + libucrtd.lib;libucrt.lib + /DEFAULTLIB:ucrtd.lib %(AdditionalOptions) - MultiThreadedDLL + + MultiThreaded true icuuc.lib;%(AdditionalDependencies) ..\..\$(IcuBinOutputDir)\icuin$(IcuMajorVersion).dll - .\..\..\$(IcuLibOutputDir)\icuin.pdb + + .\..\..\$(IcuLibOutputDir)\icuin$(IcuMajorVersion).pdb ..\..\$(IcuLibOutputDir)\icuin.lib + + libucrtd.lib;libucrt.lib + /DEFAULTLIB:ucrt.lib %(AdditionalOptions) diff --git a/icu/icu4c/source/stubdata/stubdata.vcxproj b/icu/icu4c/source/stubdata/stubdata.vcxproj index 0b2c61cb06b..9c147a57a14 100644 --- a/icu/icu4c/source/stubdata/stubdata.vcxproj +++ b/icu/icu4c/source/stubdata/stubdata.vcxproj @@ -42,7 +42,8 @@ $(OutDir)/icudt.pch $(OutDir)/ $(OutDir)/ - $(OutDir)/icudt.pdb + + $(OutDir)/icudt$(IcuMajorVersion).pdb STUBDATA_BUILD;%(PreprocessorDefinitions) @@ -56,7 +57,8 @@ true ..\..\$(IcuBinOutputDir)\icudt$(IcuMajorVersion).dll - .\..\..\$(IcuLibOutputDir)\icudt.pdb + + .\..\..\$(IcuLibOutputDir)\icudt$(IcuMajorVersion).pdb ..\..\$(IcuLibOutputDir)\icudt.lib diff --git a/icu/icu4c/source/test/cintltst/ccaltst.c b/icu/icu4c/source/test/cintltst/ccaltst.c index 235eff26d1e..50e0dca83e9 100644 --- a/icu/icu4c/source/test/cintltst/ccaltst.c +++ b/icu/icu4c/source/test/cintltst/ccaltst.c @@ -724,7 +724,7 @@ static void TestGetSetDateAPI(void) /*Testing if setDate works fine */ log_verbose("\nTesting the ucal_setDate() function \n"); - u_strcpy(temp, u"Dec 17, 1971, 11:05:28\u202FPM"); + u_strcpy(temp, u"Dec 17, 1971, 11:05:28 PM"); ucal_setDate(caldef,1971, UCAL_DECEMBER, 17, &status); if(U_FAILURE(status)){ log_err("error in setting the calendar date : %s\n", u_errorName(status)); @@ -755,7 +755,7 @@ static void TestGetSetDateAPI(void) /*Testing if setDateTime works fine */ log_verbose("\nTesting the ucal_setDateTime() function \n"); - u_strcpy(temp, u"May 3, 1972, 4:30:42\u202FPM"); + u_strcpy(temp, u"May 3, 1972, 4:30:42 PM"); ucal_setDateTime(caldef,1972, UCAL_MAY, 3, 16, 30, 42, &status); if(U_FAILURE(status)){ log_err("error in setting the calendar date : %s\n", u_errorName(status)); diff --git a/icu/icu4c/source/test/cintltst/cdateintervalformattest.c b/icu/icu4c/source/test/cintltst/cdateintervalformattest.c index 298dcae4247..a4ecc7dc2eb 100644 --- a/icu/icu4c/source/test/cintltst/cdateintervalformattest.c +++ b/icu/icu4c/source/test/cintltst/cdateintervalformattest.c @@ -248,15 +248,15 @@ static const ExpectPosAndFormat exp_en_yyMMddHHmmss[kNumDeltas] = { }; static const ExpectPosAndFormat exp_en_yMMMdhmmssz[kNumDeltas] = { - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT" }, - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT" }, - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u20099:00:20\\u202FAM GMT" }, - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u20099:20:00\\u202FAM GMT" }, - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u200911:00:00\\u202FAM GMT" }, - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u20099:00:00\\u202FPM GMT" }, - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u2009Nov 28, 2014, 9:00:00\\u202FAM GMT" }, - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u2009Dec 6, 2014, 9:00:00\\u202FAM GMT" }, - { 16, 18, "Nov 20, 2014, 9:00:00\\u202FAM GMT\\u2009\\u2013\\u2009Feb 28, 2015, 9:00:00\\u202FAM GMT" } + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT" }, + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT" }, + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u20099:00:20 AM GMT" }, + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u20099:20:00 AM GMT" }, + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u200911:00:00 AM GMT" }, + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u20099:00:00 PM GMT" }, + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u2009Nov 28, 2014, 9:00:00 AM GMT" }, + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u2009Dec 6, 2014, 9:00:00 AM GMT" }, + { 16, 18, "Nov 20, 2014, 9:00:00 AM GMT\\u2009\\u2013\\u2009Feb 28, 2015, 9:00:00 AM GMT" } }; static const ExpectPosAndFormat exp_ja_yyMMddHHmm[kNumDeltas] = { diff --git a/icu/icu4c/source/test/cintltst/cdattst.c b/icu/icu4c/source/test/cintltst/cdattst.c index e17ac06f064..6f27ba32a72 100644 --- a/icu/icu4c/source/test/cintltst/cdattst.c +++ b/icu/icu4c/source/test/cintltst/cdattst.c @@ -176,7 +176,7 @@ static void TestDateFormat(void) /*Testing udat_format()*/ log_verbose("\nTesting the udat_format() function of date format\n"); - u_strcpy(temp, u"7/10/96, 4:05\u202FPM"); + u_strcpy(temp, u"7/10/96, 4:05 PM"); /*format using def */ resultlength=0; resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status); @@ -245,7 +245,7 @@ static void TestDateFormat(void) /*Testing parsing using udat_parse()*/ log_verbose("\nTesting parsing using udat_parse()\n"); - u_strcpy(temp, u"2/3/76, 2:50\u202FAM"); + u_strcpy(temp, u"2/3/76, 2:50 AM"); parsepos=0; status=U_ZERO_ERROR; @@ -966,7 +966,7 @@ static void TestDateFormatCalendar(void) { u_errorName(ec)); goto FAIL; } - u_strcpy(uExpected, u"5:45\u202FPM"); + u_strcpy(uExpected, u"5:45 PM"); u_austrcpy(cbuf, uExpected); if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) { log_err("FAIL: udat_formatCalendar(17:45), expected: %s", cbuf); @@ -2101,10 +2101,10 @@ static void TestHourCycle(void) { static const UDate date = -845601267742; // March 16, 1943 at 3:45 PM const UChar* testCases[] = { // test some locales for which we have data - u"en_US", u"Tuesday, March 16, 1943 at 3:45:32 PM", - u"en_CA", u"Tuesday, March 16, 1943 at 3:45:32 p.m.", + u"en_US", u"Tuesday, March 16, 1943 at 3:45:32 PM", + u"en_CA", u"Tuesday, March 16, 1943 at 3:45:32 p.m.", u"en_GB", u"Tuesday, 16 March 1943 at 15:45:32", - u"en_AU", u"Tuesday, 16 March 1943 at 3:45:32 pm", + u"en_AU", u"Tuesday, 16 March 1943 at 3:45:32 pm", // test a couple locales for which we don't have specific locale files (we should still get the correct hour cycle) u"en_CO", u"Tuesday, March 16, 1943 at 3:45:32 PM", u"en_MX", u"Tuesday, March 16, 1943 at 3:45:32 PM", @@ -2112,12 +2112,12 @@ static void TestHourCycle(void) { u"en_US@rg=GBzzzz", u"Tuesday, March 16, 1943 at 15:45:32", u"en_US@rg=CAzzzz", u"Tuesday, March 16, 1943 at 3:45:32 PM", u"en_CA@rg=USzzzz", u"Tuesday, March 16, 1943 at 3:45:32 p.m.", - u"en_GB@rg=USzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", - u"en_GB@rg=CAzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", - u"en_GB@rg=AUzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", + u"en_GB@rg=USzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", + u"en_GB@rg=CAzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", + u"en_GB@rg=AUzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm", // test that the hc ("hours") subtag does the right thing u"en_US@hours=h23", u"Tuesday, March 16, 1943 at 15:45:32", - u"en_GB@hours=h12", u"Tuesday, 16 March 1943 at 3:45:32 pm", + u"en_GB@hours=h12", u"Tuesday, 16 March 1943 at 3:45:32 pm", // test that the rg and hc subtags do the right thing when used together u"en_US@rg=GBzzzz;hours=h12", u"Tuesday, March 16, 1943 at 3:45:32 PM", u"en_GB@rg=USzzzz;hours=h23", u"Tuesday, 16 March 1943 at 15:45:32", diff --git a/icu/icu4c/source/test/cintltst/cdtrgtst.c b/icu/icu4c/source/test/cintltst/cdtrgtst.c index 54bdc7228fd..13aa8cfb67c 100644 --- a/icu/icu4c/source/test/cintltst/cdtrgtst.c +++ b/icu/icu4c/source/test/cintltst/cdtrgtst.c @@ -516,7 +516,7 @@ void Test714(void) UErrorCode status = U_ZERO_ERROR; UDateFormat *fmt; UChar *result; - const UChar* expect = u"7:25:43\u202FAM"; + const UChar* expect = u"7:25:43 AM"; ctest_setTimeZone(NULL, &status); diff --git a/icu/icu4c/source/test/cintltst/cldrtest.c b/icu/icu4c/source/test/cintltst/cldrtest.c index e014a1e1d59..8cf8e5dc1ba 100644 --- a/icu/icu4c/source/test/cintltst/cldrtest.c +++ b/icu/icu4c/source/test/cintltst/cldrtest.c @@ -1122,7 +1122,7 @@ static void VerifyTranslation(void) { if (U_FAILURE(errorCode)) { log_err("ulocdata_getMeasurementSystem failed for locale %s with error: %s \n", currLoc, u_errorName(errorCode)); } else { - if ( strstr(fullLoc, "_US")!=NULL || strstr(fullLoc, "_LR")!=NULL ) { + if ( strstr(fullLoc, "_US")!=NULL || strstr(fullLoc, "_LR")!=NULL || strstr(fullLoc, "_029")!=NULL ) { if(measurementSystem != UMS_US){ log_err("ulocdata_getMeasurementSystem did not return expected data for locale %s \n", currLoc); } @@ -1143,7 +1143,7 @@ static void VerifyTranslation(void) { if ( strstr(fullLoc, "_US")!=NULL || strstr(fullLoc, "_BZ")!=NULL || strstr(fullLoc, "_CA")!=NULL || strstr(fullLoc, "_CL")!=NULL || strstr(fullLoc, "_CO")!=NULL || strstr(fullLoc, "_CR")!=NULL || strstr(fullLoc, "_GT")!=NULL || strstr(fullLoc, "_MX")!=NULL || strstr(fullLoc, "_NI")!=NULL || strstr(fullLoc, "_PA")!=NULL || strstr(fullLoc, "_PH")!=NULL || strstr(fullLoc, "_PR")!=NULL || - strstr(fullLoc, "_SV")!=NULL || strstr(fullLoc, "_VE")!=NULL ) { + strstr(fullLoc, "_SV")!=NULL || strstr(fullLoc, "_VE")!=NULL || strstr(fullLoc, "_029")!=NULL ) { if (height != 279 || width != 216) { log_err("ulocdata_getPaperSize did not return expected data for locale %s \n", currLoc); } diff --git a/icu/icu4c/source/test/cintltst/cloctst.c b/icu/icu4c/source/test/cintltst/cloctst.c index 94f452aa561..37cf24ded00 100644 --- a/icu/icu4c/source/test/cintltst/cloctst.c +++ b/icu/icu4c/source/test/cintltst/cloctst.c @@ -1268,8 +1268,8 @@ typedef struct { static const DisplayNameBracketsItem displayNameBracketsItems[] = { { "en", "CC", "en_CC", "Cocos (Keeling) Islands", "English (Cocos [Keeling] Islands)" }, - { "en", "MM", "my_MM", "Myanmar (Burma)", "Burmese (Myanmar [Burma])" }, - { "en", "MM", "my_Mymr_MM", "Myanmar (Burma)", "Burmese (Myanmar, Myanmar [Burma])" }, + { "en", "MM", "my_MM", "Myanmar", "Burmese (Myanmar)" }, + { "en", "MM", "my_Mymr_MM", "Myanmar", "Burmese (Myanmar, Myanmar)" }, { "zh", "CC", "en_CC", "\\u79D1\\u79D1\\u65AF\\uFF08\\u57FA\\u6797\\uFF09\\u7FA4\\u5C9B", "\\u82F1\\u8BED\\uFF08\\u79D1\\u79D1\\u65AF\\uFF3B\\u57FA\\u6797\\uFF3D\\u7FA4\\u5C9B\\uFF09" }, { "zh", "CG", "fr_CG", "\\u521A\\u679C\\uFF08\\u5E03\\uFF09", "\\u6CD5\\u8BED\\uFF08\\u521A\\u679C\\uFF3B\\u5E03\\uFF3D\\uFF09" }, { NULL, NULL, NULL, NULL, NULL } @@ -7163,11 +7163,11 @@ static const UldnItem en_StdMidLong[] = { { "en", TEST_ULOC_LANGUAGE, u"English" }, // https://unicode-org.atlassian.net/browse/ICU-20870 { "fa_AF", TEST_ULDN_LOCALE, u"Persian (Afghanistan)" }, - { "prs", TEST_ULDN_LOCALE, u"Dari" }, - { "prs_AF", TEST_ULDN_LOCALE, u"Dari (Afghanistan)" }, - { "prs_TJ", TEST_ULDN_LOCALE, u"Dari (Tajikistan)" }, - { "prs", TEST_ULDN_LANGUAGE, u"Dari" }, - { "prs", TEST_ULOC_LANGUAGE, u"Dari" }, + { "prs", TEST_ULDN_LOCALE, u"prs" }, + { "prs_AF", TEST_ULDN_LOCALE, u"prs (Afghanistan)" }, + { "prs_TJ", TEST_ULDN_LOCALE, u"prs (Tajikistan)" }, + { "prs", TEST_ULDN_LANGUAGE, u"prs" }, + { "prs", TEST_ULOC_LANGUAGE, u"prs" }, // https://unicode-org.atlassian.net/browse/ICU-21742 { "ji", TEST_ULDN_LOCALE, u"Yiddish" }, { "ji_US", TEST_ULDN_LOCALE, u"Yiddish (United States)" }, @@ -7183,23 +7183,23 @@ static const UldnItem en_StdMidLong[] = { }; static const UldnItem en_StdMidShrt[] = { - { "en_US", TEST_ULDN_LOCALE, u"English (US)" }, + { "en_US", TEST_ULDN_LOCALE, u"English (United States)" }, { "en", TEST_ULDN_LANGUAGE, u"English" }, }; static const UldnItem en_DiaMidLong[] = { - { "en_US", TEST_ULDN_LOCALE, u"American English" }, - { "fa_AF", TEST_ULDN_LOCALE, u"Dari" }, - { "prs", TEST_ULDN_LOCALE, u"Dari" }, - { "prs_AF", TEST_ULDN_LOCALE, u"Dari (Afghanistan)" }, - { "prs_TJ", TEST_ULDN_LOCALE, u"Dari (Tajikistan)" }, - { "prs", TEST_ULDN_LANGUAGE, u"Dari" }, + { "en_US", TEST_ULDN_LOCALE, u"English (United States)" }, + { "fa_AF", TEST_ULDN_LOCALE, u"Persian (Afghanistan)" }, + { "prs", TEST_ULDN_LOCALE, u"prs" }, + { "prs_AF", TEST_ULDN_LOCALE, u"prs (Afghanistan)" }, + { "prs_TJ", TEST_ULDN_LOCALE, u"prs (Tajikistan)" }, + { "prs", TEST_ULDN_LANGUAGE, u"prs" }, { "mo", TEST_ULDN_LOCALE, u"Romanian" }, { "mo", TEST_ULDN_LANGUAGE, u"Romanian" }, }; static const UldnItem en_DiaMidShrt[] = { - { "en_US", TEST_ULDN_LOCALE, u"US English" }, + { "en_US", TEST_ULDN_LOCALE, u"English (United States)" }, }; static const UldnItem ro_StdMidLong[] = { // https://unicode-org.atlassian.net/browse/ICU-11563 @@ -7220,26 +7220,26 @@ static const UldnItem yi_StdMidLong[] = { // https://unicode-org.atlassian.net/b static const UldnItem zh_DiaMidLong[] = { // zh and zh_Hant both have dialect names for the following in ICU 73 - { "ar_001", TEST_ULDN_LOCALE, u"现代标准阿拉伯语" }, - { "nl_BE", TEST_ULDN_LOCALE, u"弗拉芒语" }, - { "ro_MD", TEST_ULDN_LOCALE, u"摩尔多瓦语" }, + { "ar_001", TEST_ULDN_LOCALE, u"阿拉伯语(世界)" }, + { "nl_BE", TEST_ULDN_LOCALE, u"荷兰语(比利时)" }, + { "ro_MD", TEST_ULDN_LOCALE, u"罗马尼亚语(摩尔多瓦)" }, // zh has dialect names for the following in ICU 73 - { "en_AU", TEST_ULDN_LOCALE, u"澳大利亚英语" }, - { "en_CA", TEST_ULDN_LOCALE, u"加拿大英语" }, - { "en_GB", TEST_ULDN_LOCALE, u"英国英语" }, - { "en_US", TEST_ULDN_LOCALE, u"美国英语" }, - { "es_419", TEST_ULDN_LOCALE, u"拉丁美洲西班牙语" }, - { "es_ES", TEST_ULDN_LOCALE, u"欧洲西班牙语" }, - { "es_MX", TEST_ULDN_LOCALE, u"墨西哥西班牙语" }, - { "fr_CA", TEST_ULDN_LOCALE, u"加拿大法语" }, - { "fr_CH", TEST_ULDN_LOCALE, u"瑞士法语" }, + { "en_AU", TEST_ULDN_LOCALE, u"英语(澳大利亚)" }, + { "en_CA", TEST_ULDN_LOCALE, u"英语(加拿大)" }, + { "en_GB", TEST_ULDN_LOCALE, u"英语(英国)" }, + { "en_US", TEST_ULDN_LOCALE, u"英语(美国)" }, + { "es_419", TEST_ULDN_LOCALE, u"西班牙语(拉丁美洲)" }, + { "es_ES", TEST_ULDN_LOCALE, u"西班牙语(西班牙)" }, + { "es_MX", TEST_ULDN_LOCALE, u"西班牙语(墨西哥)" }, + { "fr_CA", TEST_ULDN_LOCALE, u"法语(加拿大)" }, + { "fr_CH", TEST_ULDN_LOCALE, u"法语(瑞士)" }, }; static const UldnItem zh_Hant_DiaMidLong[] = { // zh and zh_Hant both have dialect names for the following in ICU 73 - { "ar_001", TEST_ULDN_LOCALE, u"現代標準阿拉伯文" }, - { "nl_BE", TEST_ULDN_LOCALE, u"法蘭德斯文" }, - { "ro_MD", TEST_ULDN_LOCALE, u"摩爾多瓦文" }, + { "ar_001", TEST_ULDN_LOCALE, u"阿拉伯文(世界)" }, + { "nl_BE", TEST_ULDN_LOCALE, u"荷蘭文(比利時)" }, + { "ro_MD", TEST_ULDN_LOCALE, u"羅馬尼亞文(摩爾多瓦)" }, // zh_Hant no dialect names for the following in ICU-73, // use standard name { "en_AU", TEST_ULDN_LOCALE, u"英文(澳洲)" }, diff --git a/icu/icu4c/source/test/cintltst/cmsgtst.c b/icu/icu4c/source/test/cintltst/cmsgtst.c index 16263b5c7f4..ed20cf23ce0 100644 --- a/icu/icu4c/source/test/cintltst/cmsgtst.c +++ b/icu/icu4c/source/test/cintltst/cmsgtst.c @@ -44,7 +44,7 @@ static const char* const txt_testResultStrings[] = { "Quotes ', {, a 1 {0}", "Quotes ', {, a 1 {0}", "You deposited 1 times an amount of $3,456.00 on 1/12/70", - "{2,time,full}, for 3,456, 1 is 5:46:40\\u202FAM Pacific Standard Time and full date is Monday, January 12, 1970", + "{2,time,full}, for 3,456, 1 is 5:46:40 AM Pacific Standard Time and full date is Monday, January 12, 1970", "{1,number,percent} for 1 is 345,600%" }; diff --git a/icu/icu4c/source/test/cintltst/cnmdptst.c b/icu/icu4c/source/test/cintltst/cnmdptst.c index 98504e0220f..b7ce012361b 100644 --- a/icu/icu4c/source/test/cintltst/cnmdptst.c +++ b/icu/icu4c/source/test/cintltst/cnmdptst.c @@ -813,7 +813,7 @@ static void TestGetKeywordValuesForLocale(void) { { "und", "USD", "USN", NULL }, /* { "und_ZZ", "USD", NULL, NULL }, -- temporarily remove as this locale now has 15 entries */ { "en_US", "USD", "USN", NULL }, - { "en_029", "USD", "USN", NULL }, + { "en_029", "XCD", NULL, NULL }, { "en_TH", "THB", NULL, NULL }, { "de", "EUR", NULL, NULL }, { "de_DE", "EUR", NULL, NULL }, @@ -827,11 +827,11 @@ static void TestGetKeywordValuesForLocale(void) { { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL }, }; const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { - 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 + 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 }; /* ucurr_forLocale results for same locales; "" if no result expected */ const char *FORLOCALE[PREFERRED_SIZE] = { - "", "", "USD", "", + "", "", "USD", "XCD", "THB", "", "EUR", "", "ILS", "CAD", "ZZZ", "DEM", "THB", "USD", "CAD" diff --git a/icu/icu4c/source/test/cintltst/creststn.c b/icu/icu4c/source/test/cintltst/creststn.c index 71fd936e377..63a758c5b78 100644 --- a/icu/icu4c/source/test/cintltst/creststn.c +++ b/icu/icu4c/source/test/cintltst/creststn.c @@ -2715,16 +2715,6 @@ static void TestGetFunctionalEquivalent(void) { "f", "nl_NL@collation=stroke", "root", "f", "nl_NL_EEXT@collation=stroke", "root", /* Additions to test aliased locales */ - "f", "yue_HK", "zh@collation=stroke", - "f", "yue_Hant", "zh@collation=stroke", - "f", "yue_Hant_HK", "zh@collation=stroke", - "f", "yue@collation=stroke", "zh@collation=stroke", - "f", "yue@collation=pinyin", "zh", - "f", "yue_CN", "zh", - "f", "yue_Hans", "zh", - "f", "yue_Hans_CN", "zh", - "f", "yue_Hans@collation=pinyin", "zh", - "f", "yue_Hans@collation=stroke", "zh@collation=stroke", "f", "mo", "mo", "t", "no", "no", "t", "nb", "no", @@ -2735,8 +2725,6 @@ static void TestGetFunctionalEquivalent(void) { "f", "zh_Hant_CN", "zh@collation=stroke", "f", "zh_Hant_US", "zh@collation=stroke", "f", "zh_Hans_US", "zh", - "f", "yue_TW", "zh@collation=stroke", - "f", "yue_US", "zh@collation=stroke", "f", "ja_CN", "ja", "f", "ja_US", "ja", NULL diff --git a/icu/icu4c/source/test/cintltst/currtest.c b/icu/icu4c/source/test/cintltst/currtest.c index d8355133a18..51dff0eb0b3 100644 --- a/icu/icu4c/source/test/cintltst/currtest.c +++ b/icu/icu4c/source/test/cintltst/currtest.c @@ -298,6 +298,26 @@ static void TestNumericCode(void) { } } +static void TestSaudiRiyalSymbol(void) { + UErrorCode status = U_ZERO_ERROR; + UChar currency[4]; + UBool isChoiceFormat = false; + int32_t len = 0; + static const UChar expectedSymbol[] = {0x20C1, 0}; + const UChar* symbol; + + u_charsToUChars("SAR", currency, UPRV_LENGTHOF(currency)); + symbol = ucurr_getName(currency, "ar_SA", UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &status); + if (U_FAILURE(status)) { + log_data_err("Error: ucurr_getName returned %s (Are you missing data?)\n", u_errorName(status)); + return; + } + if (isChoiceFormat || len != 1 || symbol == NULL || u_strncmp(symbol, expectedSymbol, len) != 0) { + log_err("Error: SAR symbol for ar_SA should be U+20C1. Got length=%d first=U+%04X choice=%s\n", + len, (len > 0 && symbol != NULL) ? symbol[0] : 0, isChoiceFormat ? "true" : "false"); + } +} + void addCurrencyTest(TestNode** root); #define TESTCASE(x) addTest(root, &x, "tsformat/currtest/" #x) @@ -310,6 +330,7 @@ void addCurrencyTest(TestNode** root) TESTCASE(TestFractionDigitOverride); TESTCASE(TestPrefixSuffix); TESTCASE(TestNumericCode); + TESTCASE(TestSaudiRiyalSymbol); } #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu/icu4c/source/test/cintltst/udatpg_test.c b/icu/icu4c/source/test/cintltst/udatpg_test.c index b9278085b20..d6e6d209a97 100644 --- a/icu/icu4c/source/test/cintltst/udatpg_test.c +++ b/icu/icu4c/source/test/cintltst/udatpg_test.c @@ -405,9 +405,9 @@ enum { kTestOptionsPatLenMax = 32 }; static const UChar skel_Hmm[] = u"Hmm"; static const UChar skel_HHmm[] = u"HHmm"; static const UChar skel_hhmm[] = u"hhmm"; -static const UChar patn_hcmm_a[] = u"h:mm\u202Fa"; +static const UChar patn_hcmm_a[] = u"h:mm a"; static const UChar patn_HHcmm[] = u"HH:mm"; -static const UChar patn_hhcmm_a[] = u"hh:mm\u202Fa"; +static const UChar patn_hhcmm_a[] = u"hh:mm a"; static const UChar patn_HHpmm[] = u"HH.mm"; static const UChar patn_hpmm_a[] = u"h.mm\u202Fa"; static const UChar patn_Hpmm[] = u"H.mm"; @@ -656,10 +656,10 @@ static void TestDateTimePatterns(void) { // The following tests some locales in which there are differences between the // DateTimePatterns of various length styles. DTPLocaleAndResults localeAndResults[] = { - { "en", { u"EEEE, MMMM d, y 'at' h:mm\u202Fa", // long != medium - u"MMMM d, y 'at' h:mm\u202Fa", - u"MMM d, y, h:mm\u202Fa", - u"M/d/y, h:mm\u202Fa" } }, + { "en", { u"EEEE, MMMM d, y 'at' h:mm a", // long != medium + u"MMMM d, y 'at' h:mm a", + u"MMM d, y, h:mm a", + u"M/d/y, h:mm a" } }, { "fr", { u"EEEE d MMMM y 'à' HH:mm", // medium != short u"d MMMM y 'à' HH:mm", u"d MMM y, HH:mm", @@ -683,10 +683,10 @@ static void TestDateTimePatterns(void) { u"{1} _2_ {0}", u"{1} _3_ {0}" }; - DTPLocaleAndResults enModResults = { "en", { u"EEEE, MMMM d, y _0_ h:mm\u202Fa", - u"MMMM d, y _1_ h:mm\u202Fa", - u"MMM d, y _2_ h:mm\u202Fa", - u"M/d/y _3_ h:mm\u202Fa" } + DTPLocaleAndResults enModResults = { "en", { u"EEEE, MMMM d, y _0_ h:mm a", + u"MMMM d, y _1_ h:mm a", + u"MMM d, y _2_ h:mm a", + u"M/d/y _3_ h:mm a" } }; // Test various locales with standard data @@ -817,7 +817,7 @@ static void TestRegionOverride(void) { } RegionOverrideTest; const RegionOverrideTest testCases[] = { - { "en_US", u"h:mm\u202fa", UDAT_HOUR_CYCLE_12 }, + { "en_US", u"h:mm a", UDAT_HOUR_CYCLE_12 }, { "en_GB", u"HH:mm", UDAT_HOUR_CYCLE_23 }, { "en_US@rg=GBZZZZ", u"HH:mm", UDAT_HOUR_CYCLE_23 }, { "en_US@hours=h23", u"HH:mm", UDAT_HOUR_CYCLE_23 }, @@ -859,9 +859,9 @@ static void TestISO8601(void) { { "en_US@calendar=iso8601", u"Edjmm", u"d, EEE, h:mm a" }, { "en_US@calendar=iso8601", u"EdHmm", u"d, EEE, HH:mm" }, - { "en_US", u"EEEEyMMMMdjmm", u"EEEE, MMMM d, y 'at' h:mm a" }, + { "en_US", u"EEEEyMMMMdjmm", u"EEEE, MMMM d, y 'at' h:mm a" }, { "en_US", u"EEEEyMMMMdHmm", u"EEEE, MMMM d, y 'at' HH:mm" }, - { "en_US", u"Edjmm", u"d EEE, h:mm a" }, + { "en_US", u"Edjmm", u"d EEE, h:mm a" }, { "en_US", u"EdHmm", u"d EEE, HH:mm" }, }; diff --git a/icu/icu4c/source/test/cintltst/uregiontest.c b/icu/icu4c/source/test/cintltst/uregiontest.c index 0dd896817c0..decac11892a 100644 --- a/icu/icu4c/source/test/cintltst/uregiontest.c +++ b/icu/icu4c/source/test/cintltst/uregiontest.c @@ -152,17 +152,14 @@ static KnownRegion knownRegions[] = { { "CZ" , 203, "151", URGN_TERRITORY, "150" }, { "DD" , 276, "155", URGN_TERRITORY, "150" }, { "DE" , 276, "155", URGN_TERRITORY, "150" }, - { "DG" , -1 , "QO" , URGN_TERRITORY, "009" }, { "DJ" , 262, "014", URGN_TERRITORY, "002" }, { "DK" , 208, "154", URGN_TERRITORY, "150" }, { "DM" , 212, "029", URGN_TERRITORY, "019" }, { "DO" , 214, "029", URGN_TERRITORY, "019" }, { "DZ" , 12, "015", URGN_TERRITORY, "002" }, - { "EA" , -1, "015", URGN_TERRITORY, "002" }, { "EC" , 218, "005", URGN_TERRITORY, "019" }, { "EE" , 233, "154", URGN_TERRITORY, "150" }, { "EG" , 818, "015", URGN_TERRITORY, "002" }, - { "EH" , 732, "015", URGN_TERRITORY, "002" }, { "ER" , 232, "014", URGN_TERRITORY, "002" }, { "ES" , 724, "039", URGN_TERRITORY, "150" }, { "ET" , 231, "014", URGN_TERRITORY, "002" }, @@ -199,7 +196,6 @@ static KnownRegion knownRegions[] = { { "HR" , 191, "039", URGN_TERRITORY, "150" }, { "HT" , 332, "029", URGN_TERRITORY, "019" }, { "HU" , 348, "151", URGN_TERRITORY, "150" }, - { "IC" , -1, "015", URGN_TERRITORY, "002" }, { "ID" , 360, "035", URGN_TERRITORY, "142" }, { "IE" , 372, "154", URGN_TERRITORY, "150" }, { "IL" , 376, "145", URGN_TERRITORY, "142" }, diff --git a/icu/icu4c/source/test/intltest/Makefile.in b/icu/icu4c/source/test/intltest/Makefile.in index 2e448319243..eab33ebb0b6 100644 --- a/icu/icu4c/source/test/intltest/Makefile.in +++ b/icu/icu4c/source/test/intltest/Makefile.in @@ -78,7 +78,7 @@ units_data_test.o units_router_test.o units_test.o displayoptions_test.o \ numbertest_simple.o \ cplusplus_header_api_build_test.o uchar_type_build_test.o \ ucolheaderonlytest.o usetheaderonlytest.o utfiteratortest.o utfstringtest.o \ -intltesttest.o +intltesttest.o uprefstest.o DEPS = $(OBJECTS:.o=.d) diff --git a/icu/icu4c/source/test/intltest/apicoll.cpp b/icu/icu4c/source/test/intltest/apicoll.cpp index 4ccdc373e6c..a31873fe436 100644 --- a/icu/icu4c/source/test/intltest/apicoll.cpp +++ b/icu/icu4c/source/test/intltest/apicoll.cpp @@ -1664,18 +1664,7 @@ void CollationAPITest::TestGetLocale() { { "zh_TW", "zh_Hant_TW", "zh@collation=stroke" }, { "zh_TW@collation=pinyin", "zh_Hant_TW@collation=pinyin", "zh" }, { "zh_CN@collation=stroke", "zh_Hans_CN@collation=stroke", "zh@collation=stroke" }, - // yue/yue_Hant aliased to zh_Hant, yue_Hans aliased to zh_Hans. - { "yue", "zh_Hant", "zh@collation=stroke" }, - { "yue_HK", "zh_Hant", "zh@collation=stroke" }, - { "yue_Hant", "zh_Hant", "zh@collation=stroke" }, - { "yue_Hant_HK", "zh_Hant", "zh@collation=stroke" }, - { "yue@collation=pinyin", "zh_Hant@collation=pinyin", "zh" }, - { "yue_HK@collation=pinyin", "zh_Hant@collation=pinyin", "zh" }, - { "yue_CN", "zh_Hans", "zh" }, - { "yue_Hans", "zh_Hans", "zh" }, - { "yue_Hans_CN", "zh_Hans", "zh" }, - { "yue_Hans@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" }, - { "yue_CN@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" } + // CLDR-MS does not ship yue collation aliases. }; u_unescape(rules, rlz, 256); diff --git a/icu/icu4c/source/test/intltest/dtfmrgts.cpp b/icu/icu4c/source/test/intltest/dtfmrgts.cpp index 2fd10e01d87..fed3546b8d4 100644 --- a/icu/icu4c/source/test/intltest/dtfmrgts.cpp +++ b/icu/icu4c/source/test/intltest/dtfmrgts.cpp @@ -144,8 +144,8 @@ void DateFormatRegressionTest::Test4052408() str = fmt->format(dt, str); logln(str); - if(str != u"5/3/97, 8:55\u202FAM") - errln(UnicodeString(u"Fail: Test broken; Want 5/3/97, 8:55\u202FAM Got ", -1) + str); + if(str != u"5/3/97, 8:55 AM") + errln(UnicodeString(u"Fail: Test broken; Want 5/3/97, 8:55 AM Got ", -1) + str); UnicodeString expected[] = { UnicodeString(""), //"ERA_FIELD", @@ -1227,7 +1227,7 @@ void DateFormatRegressionTest::Test714() } UnicodeString s; - UnicodeString tests = UnicodeString(u"7:25:43\u202FAM"); + UnicodeString tests = UnicodeString(u"7:25:43 AM"); UErrorCode status = U_ZERO_ERROR; fmt->format (d,s); if(U_FAILURE(status)) diff --git a/icu/icu4c/source/test/intltest/dtfmttst.cpp b/icu/icu4c/source/test/intltest/dtfmttst.cpp index 9ef923fc25b..7af9ebb0215 100644 --- a/icu/icu4c/source/test/intltest/dtfmttst.cpp +++ b/icu/icu4c/source/test/intltest/dtfmttst.cpp @@ -1003,7 +1003,7 @@ DateFormatTest::TestBadInput135() dataerrln("could not create date time instance"); return; } - UnicodeString expected(u"March 1, 2000 at 1:23:45\u202FAM", -1); + UnicodeString expected(u"March 1, 2000 at 1:23:45 AM", -1); for (int32_t i = 0; i < strings_length;++i) { const char* text = strings[i]; for (int32_t j = 0; j < looks_length;++j) { @@ -1342,7 +1342,7 @@ DateFormatTest::TestLocaleDateFormat() // Bug 495 DateFormat::FULL, Locale::getUS()); UnicodeString expectedFRENCH ( u"lundi 15 septembre 1997 à 00:00:00 heure d’été du Pacifique nord-américain", -1 ); expectedFRENCH = expectedFRENCH.unescape(); - UnicodeString expectedUS ( u"Monday, September 15, 1997 at 12:00:00\u202FAM Pacific Daylight Time", -1 ); + UnicodeString expectedUS ( u"Monday, September 15, 1997 at 12:00:00 AM Pacific Daylight Time", -1 ); logln(UnicodeString("Date set to : ") + dateToString(testDate)); UnicodeString out; if (dfUS == nullptr || dfFrench == nullptr){ @@ -5028,7 +5028,7 @@ void DateFormatTest::TestPatternFromSkeleton() { const char16_t* const pattern; } TESTDATA[] = { // Ticket #11985 - {Locale::getEnglish(), "jjmm", u"h:mm\u202Fa"}, + {Locale::getEnglish(), "jjmm", u"h:mm a"}, {Locale::getEnglish(), "JJmm", u"hh:mm"}, {Locale::getGerman(), "jjmm", u"HH:mm"}, {Locale::getGerman(), "JJmm", u"HH:mm"}, @@ -5851,10 +5851,10 @@ void DateFormatTest::TestHourCycle() { UnicodeString expectedResult; } TEST_CASES[] = { // test some locales for which we have data - { "en-us", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, - { "en-ca", u"Tuesday, March 16, 1943 at 3:45:32 p.m." }, + { "en-us", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, + { "en-ca", u"Tuesday, March 16, 1943 at 3:45:32 p.m." }, { "en-gb", u"Tuesday, 16 March 1943 at 15:45:32" }, - { "en-au", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, + { "en-au", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, // test a couple locales for which we don't have specific locale files (we should still get the correct hour cycle) { "en-co", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, { "en-mx", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, @@ -5862,12 +5862,12 @@ void DateFormatTest::TestHourCycle() { { "en-us-u-rg-gbzzzz", u"Tuesday, March 16, 1943 at 15:45:32" }, { "en-us-u-rg-cazzzz", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, { "en-ca-u-rg-uszzzz", u"Tuesday, March 16, 1943 at 3:45:32 p.m." }, - { "en-gb-u-rg-uszzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, - { "en-gb-u-rg-cazzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, - { "en-gb-u-rg-auzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, + { "en-gb-u-rg-uszzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, + { "en-gb-u-rg-cazzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, + { "en-gb-u-rg-auzzzz", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, // test that the hc ("hours") subtag does the right thing { "en-us-u-hc-h23", u"Tuesday, March 16, 1943 at 15:45:32" }, - { "en-gb-u-hc-h12", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, + { "en-gb-u-hc-h12", u"Tuesday, 16 March 1943 at 3:45:32 pm" }, // test that the rg and hc subtags do the right thing when used together { "en-us-u-rg-gbzzzz-hc-h12", u"Tuesday, March 16, 1943 at 3:45:32 PM" }, { "en-gb-u-rg-uszzzz-hc-h23", u"Tuesday, 16 March 1943 at 15:45:32" }, diff --git a/icu/icu4c/source/test/intltest/dtifmtts.cpp b/icu/icu4c/source/test/intltest/dtifmtts.cpp index f539104be66..62d05a90e3e 100644 --- a/icu/icu4c/source/test/intltest/dtifmtts.cpp +++ b/icu/icu4c/source/test/intltest/dtifmtts.cpp @@ -496,7 +496,7 @@ void DateIntervalFormatTest::testFormat() { "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EddMMy", "Wed, 10/10/2007\\u2009\\u2013\\u2009Fri, 10/10/2008", - "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM", + "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10 AM\\u2009\\u2013\\u200910/10/2008, 10:10 AM", "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmmzz", "10/10/2007, 10:10\\u202FAM PDT\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM PDT", @@ -633,7 +633,7 @@ void DateIntervalFormatTest::testFormat() { "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EddMMy", "Sat, 11/10/2007\\u2009\\u2013\\u2009Tue, 11/20/2007", - "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM", + "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10 AM\\u2009\\u2013\\u200911/20/2007, 10:10 AM", "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmmzz", "11/10/2007, 10:10\\u202FAM PST\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM PST", @@ -821,7 +821,7 @@ void DateIntervalFormatTest::testFormat() { "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEddMMyyyy", "Wed, 01/10/2007", - "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmm", "10:10\\u202FAM", + "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmm", "10:10 AM", "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "HHmm", "10:10", "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmmzz", "10:10\\u202FAM PST", @@ -2382,7 +2382,7 @@ void DateIntervalFormatTest::testTicket21939() { const DateFormat* df = dif->getDateFormat(); const SimpleDateFormat* sdf = dynamic_cast(df); UnicodeString pattern; - assertEquals("Wrong pattern", u"M/d/r, h:mm\u202Fa", sdf->toPattern(pattern)); + assertEquals("Wrong pattern", u"M/d/r, h:mm a", sdf->toPattern(pattern)); } // additional tests for the related ICU-22202 diff --git a/icu/icu4c/source/test/intltest/dtptngts.cpp b/icu/icu4c/source/test/intltest/dtptngts.cpp index e7360dda69f..e76ea5cfc5b 100644 --- a/icu/icu4c/source/test/intltest/dtptngts.cpp +++ b/icu/icu4c/source/test/intltest/dtptngts.cpp @@ -107,14 +107,14 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/) UnicodeString("Jan 13"), // 05: MMMd UnicodeString("January 13"), // 06: MMMMd UnicodeString("Q1 1999"), // 07: yQQQ - UnicodeString(u"11:58\u202FPM", -1), // 08: hhmm + UnicodeString(u"11:58 PM", -1), // 08: hhmm UnicodeString("23:58"), // 09: HHmm - UnicodeString(u"11:58\u202FPM", -1), // 10: jjmm + UnicodeString(u"11:58 PM", -1), // 10: jjmm UnicodeString("58:59"), // 11: mmss UnicodeString("January 1999"), // 12: yyyyMMMM UnicodeString("Wed, Jan 13"), // 13: MMMEd -> EEE, MMM d UnicodeString("13 Wed"), // 14: Ed -> d EEE - UnicodeString(u"11:58:59.123\u202FPM", -1), // 15: jmmssSSS -> "h:mm:ss.SSS a" + UnicodeString(u"11:58:59.123 PM", -1), // 15: jmmssSSS -> "h:mm:ss.SSS a" UnicodeString("11:58"), // 16: JJmm }; @@ -128,14 +128,14 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/) UnicodeString("Jan 13"), // 5: MMMd UnicodeString("January 13"), // 6: MMMMd UnicodeString("Q1 11 Heisei"), // 7: yQQQ - UnicodeString(u"11:58\u202FPM", -1), // 8: hhmm + UnicodeString(u"11:58 PM", -1), // 8: hhmm UnicodeString("23:58"), // 9: HHmm - UnicodeString(u"11:58\u202FPM", -1), // 10: jjmm + UnicodeString(u"11:58 PM", -1), // 10: jjmm UnicodeString("58:59"), // 11: mmss UnicodeString("January 11 Heisei"), // 12: yyyyMMMM UnicodeString("Wed, Jan 13"), // 13: MMMEd -> EEE, MMM d" UnicodeString("13 Wed"), // 14: Ed -> d EEE - UnicodeString(u"11:58:59.123\u202FPM", -1), // 15: jmmssSSS -> "h:mm:ss.SSS a" + UnicodeString(u"11:58:59.123 PM", -1), // 15: jmmssSSS -> "h:mm:ss.SSS a" UnicodeString("11:58"), // 16: JJmm }; @@ -377,14 +377,14 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/) UnicodeString("O 14, 1999"), UnicodeString("T, O 14"), UnicodeString("Oct 14"), - UnicodeString(u"Oct 14, 6:58\u202FAM", -1), - UnicodeString(u"Thu, Oct 14, 6:58:59\u202FAM", -1), - UnicodeString(u"10/14, 6:58\u202FAM", -1), - UnicodeString(u"Thursday, Oct 14, 6:58:59\u202FAM", -1), - UnicodeString(u"Oct 14, 1999, 6:58:59\u202FAM", -1), - UnicodeString(u"Thu, Oct 14, 1999, 6:58:59\u202FAM", -1), - UnicodeString(u"6:58\u202FAM", -1), - UnicodeString(u"6:58\u202FAM", -1), + UnicodeString(u"Oct 14, 6:58 AM", -1), + UnicodeString(u"Thu, Oct 14, 6:58:59 AM", -1), + UnicodeString(u"10/14, 6:58 AM", -1), + UnicodeString(u"Thursday, Oct 14, 6:58:59 AM", -1), + UnicodeString(u"Oct 14, 1999, 6:58:59 AM", -1), + UnicodeString(u"Thu, Oct 14, 1999, 6:58:59 AM", -1), + UnicodeString(u"6:58 AM", -1), + UnicodeString(u"6:58 AM", -1), UnicodeString(u"6:58\u202FAM GMT+00:00", -1), UnicodeString(""), }; @@ -908,10 +908,10 @@ void IntlTestDateTimePatternGeneratorAPI::testOptions(/*char *par*/) // locale skel expectedPattern options { "en", "Hmm", u"HH:mm", UDATPG_MATCH_NO_OPTIONS }, { "en", "HHmm", u"HH:mm", UDATPG_MATCH_NO_OPTIONS }, - { "en", "hhmm", u"h:mm\u202Fa", UDATPG_MATCH_NO_OPTIONS }, + { "en", "hhmm", u"h:mm a", UDATPG_MATCH_NO_OPTIONS }, { "en", "Hmm", u"HH:mm", UDATPG_MATCH_HOUR_FIELD_LENGTH }, { "en", "HHmm", u"HH:mm", UDATPG_MATCH_HOUR_FIELD_LENGTH }, - { "en", "hhmm", u"hh:mm\u202Fa", UDATPG_MATCH_HOUR_FIELD_LENGTH }, + { "en", "hhmm", u"hh:mm a", UDATPG_MATCH_HOUR_FIELD_LENGTH }, { "da", "Hmm", u"HH.mm", UDATPG_MATCH_NO_OPTIONS }, { "da", "HHmm", u"HH.mm", UDATPG_MATCH_NO_OPTIONS }, { "da", "hhmm", u"h.mm\u202Fa", UDATPG_MATCH_NO_OPTIONS }, @@ -1540,6 +1540,18 @@ void IntlTestDateTimePatternGeneratorAPI::test_jConsistencyOddLocales() { // ICU continue; } if (dtfShortPattern != dtfSkelPattern || dtfSkelPattern != dtpgPattern) { + if (uprv_strcmp(localeID, "en") == 0) { + UnicodeString dtfShortPatternForCompare(dtfShortPattern); + UnicodeString dtfSkelPatternForCompare(dtfSkelPattern); + UnicodeString dtpgPatternForCompare(dtpgPattern); + dtfShortPatternForCompare.findAndReplace(u"\u202F", u" "); + dtfSkelPatternForCompare.findAndReplace(u"\u202F", u" "); + dtpgPatternForCompare.findAndReplace(u"\u202F", u" "); + if (dtfShortPatternForCompare == dtfSkelPatternForCompare && + dtfSkelPatternForCompare == dtpgPatternForCompare) { + continue; + } + } const char* dtfShortValidLoc = dtfShort->getLocaleID(ULOC_VALID_LOCALE, status); const char* dtfShortActualLoc = dtfShort->getLocaleID(ULOC_ACTUAL_LOCALE, status); errln(UnicodeString("For locale ") + localeID + @@ -1635,10 +1647,10 @@ void IntlTestDateTimePatternGeneratorAPI::testDateTimePatterns() { // The following tests some locales in which there are differences between the // DateTimePatterns of various length styles. DTPLocaleAndResults localeAndResults[] = { - { "en", { UnicodeString(u"EEEE, MMMM d, y 'at' h:mm\u202Fa"), // long != medium - UnicodeString(u"MMMM d, y 'at' h:mm\u202Fa"), - UnicodeString(u"MMM d, y, h:mm\u202Fa"), - UnicodeString(u"M/d/y, h:mm\u202Fa") } }, + { "en", { UnicodeString(u"EEEE, MMMM d, y 'at' h:mm a"), // long != medium + UnicodeString(u"MMMM d, y 'at' h:mm a"), + UnicodeString(u"MMM d, y, h:mm a"), + UnicodeString(u"M/d/y, h:mm a") } }, { "fr", { UnicodeString(u"EEEE d MMMM y 'à' HH:mm"), // medium != short UnicodeString(u"d MMMM y 'à' HH:mm"), UnicodeString(u"d MMM y, HH:mm"), @@ -1663,10 +1675,10 @@ void IntlTestDateTimePatternGeneratorAPI::testDateTimePatterns() { UnicodeString(u"{1} _2_ {0}"), UnicodeString(u"{1} _3_ {0}") }; - DTPLocaleAndResults enModResults = { "en", { UnicodeString(u"EEEE, MMMM d, y _0_ h:mm\u202Fa"), - UnicodeString(u"MMMM d, y _1_ h:mm\u202Fa"), - UnicodeString(u"MMM d, y _2_ h:mm\u202Fa"), - UnicodeString(u"M/d/y _3_ h:mm\u202Fa") } + DTPLocaleAndResults enModResults = { "en", { UnicodeString(u"EEEE, MMMM d, y _0_ h:mm a"), + UnicodeString(u"MMMM d, y _1_ h:mm a"), + UnicodeString(u"MMM d, y _2_ h:mm a"), + UnicodeString(u"M/d/y _3_ h:mm a") } }; // Test various locales with standard data @@ -1784,7 +1796,7 @@ void IntlTestDateTimePatternGeneratorAPI::testRegionOverride() { const char16_t* expectedPattern; UDateFormatHourCycle expectedHourCycle; } testCases[] = { - { "en_US", u"h:mm\u202fa", UDAT_HOUR_CYCLE_12 }, + { "en_US", u"h:mm a", UDAT_HOUR_CYCLE_12 }, { "en_GB", u"HH:mm", UDAT_HOUR_CYCLE_23 }, { "en_US@rg=GBZZZZ", u"HH:mm", UDAT_HOUR_CYCLE_23 }, { "en_US@hours=h23", u"HH:mm", UDAT_HOUR_CYCLE_23 }, diff --git a/icu/icu4c/source/test/intltest/intltest.vcxproj b/icu/icu4c/source/test/intltest/intltest.vcxproj index ce69ec0de41..0ee503fcbe4 100644 --- a/icu/icu4c/source/test/intltest/intltest.vcxproj +++ b/icu/icu4c/source/test/intltest/intltest.vcxproj @@ -247,6 +247,7 @@ + @@ -378,6 +379,7 @@ + diff --git a/icu/icu4c/source/test/intltest/itutil.cpp b/icu/icu4c/source/test/intltest/itutil.cpp index 20c16389c0a..768507c632a 100644 --- a/icu/icu4c/source/test/intltest/itutil.cpp +++ b/icu/icu4c/source/test/intltest/itutil.cpp @@ -33,6 +33,9 @@ #include "uvectest.h" #include "aliastst.h" #include "usettest.h" +#if U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY + #include "uprefstest.h" +#endif extern IntlTest *createBytesTrieTest(); #if !UCONFIG_NO_COLLATION @@ -76,6 +79,9 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* & TESTCASE_AUTO_CLASS(LocaleAliasTest); TESTCASE_AUTO_CLASS(UnicodeSetTest); TESTCASE_AUTO_CLASS(ErrorCodeTest); +#if U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY + TESTCASE_AUTO_CLASS(UPrefsTest); +#endif TESTCASE_AUTO_CREATE_CLASS(LocalPointerTest); TESTCASE_AUTO_CREATE_CLASS(BytesTrieTest); TESTCASE_AUTO_CREATE_CLASS(UCharsTrieTest); diff --git a/icu/icu4c/source/test/intltest/locnmtst.cpp b/icu/icu4c/source/test/intltest/locnmtst.cpp index 864b57ef518..0703866445d 100644 --- a/icu/icu4c/source/test/intltest/locnmtst.cpp +++ b/icu/icu4c/source/test/intltest/locnmtst.cpp @@ -104,7 +104,7 @@ void LocaleDisplayNamesTest::TestCreateDialect() { LocaleDisplayNames *ldn = LocaleDisplayNames::createInstance(Locale::getUS(), ULDN_DIALECT_NAMES); ldn->localeDisplayName("en_GB", temp); delete ldn; - test_assert_equal("British English", temp); + test_assert_equal("English (United Kingdom)", temp); } void LocaleDisplayNamesTest::TestWithKeywordsAndEverything() { @@ -190,7 +190,7 @@ void LocaleDisplayNamesTest::TestUldnOpenDialect() { test_assert(U_SUCCESS(status)); UnicodeString str(result, len, kMaxResultSize); - test_assert_equal("British English", str); + test_assert_equal("English (United Kingdom)", str); } void LocaleDisplayNamesTest::TestUldnWithGarbage() { @@ -299,22 +299,22 @@ static char16_t daFor_en[] = {0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0}; //"en static char16_t daFor_en_cabud[] = {0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x62,0x75,0x64,0x64,0x68,0x69,0x73,0x74,0x69,0x73,0x6B,0x20, 0x6B,0x61,0x6C,0x65,0x6E,0x64,0x65,0x72,0x29,0}; //"engelsk (buddhistisk kalender)" static char16_t daFor_en_GB[] = {0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x53,0x74,0x6F,0x72,0x62,0x72,0x69,0x74,0x61,0x6E,0x6E,0x69,0x65,0x6E,0x29,0}; //"engelsk (Storbritannien)" -static char16_t daFor_en_GB_D[] = {0x62,0x72,0x69,0x74,0x69,0x73,0x6B,0x20,0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0}; //"britisk engelsk" +static char16_t daFor_en_GB_D[] = {0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x53,0x74,0x6F,0x72,0x62,0x72,0x69,0x74,0x61,0x6E,0x6E,0x69,0x65,0x6E,0x29,0}; //"engelsk (Storbritannien)" static char16_t esFor_en[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0}; //"ingles" with acute on the e static char16_t esFor_en_GB[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"ingles (Reino Unido)" ... -static char16_t esFor_en_GB_S[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x55,0x29,0}; //"ingles (RU)" ... -static char16_t esFor_en_GB_D[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x62,0x72,0x69,0x74,0xE1,0x6E,0x69,0x63,0x6F,0}; //"ingles britanico" with acute on the e, a +static char16_t esFor_en_GB_S[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"ingles (Reino Unido)" ... +static char16_t esFor_en_GB_D[] = {0x69,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"ingles (Reino Unido)" ... static char16_t ruFor_uz_Latn[] = {0x0443,0x0437,0x0431,0x0435,0x043A,0x0441,0x043A,0x0438,0x0439,0x20,0x28,0x043B,0x0430,0x0442,0x0438,0x043D,0x0438,0x0446,0x0430,0x29,0}; // all lowercase #if !UCONFIG_NO_BREAK_ITERATION static char16_t daFor_en_T[] = {0x45,0x6E,0x67,0x65,0x6C,0x73,0x6B,0}; //"Engelsk" static char16_t daFor_en_cabudT[]= {0x45,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x62,0x75,0x64,0x64,0x68,0x69,0x73,0x74,0x69,0x73,0x6B,0x20, 0x6B,0x61,0x6C,0x65,0x6E,0x64,0x65,0x72,0x29,0}; //"Engelsk (buddhistisk kalender)" static char16_t daFor_en_GB_T[] = {0x45,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x53,0x74,0x6F,0x72,0x62,0x72,0x69,0x74,0x61,0x6E,0x6E,0x69,0x65,0x6E,0x29,0}; //"Engelsk (Storbritannien)" -static char16_t daFor_en_GB_DT[] = {0x42,0x72,0x69,0x74,0x69,0x73,0x6B,0x20,0x65,0x6E,0x67,0x65,0x6C,0x73,0x6B,0}; //"Britisk engelsk" +static char16_t daFor_en_GB_DT[] = {0x45,0x6E,0x67,0x65,0x6C,0x73,0x6B,0x20,0x28,0x53,0x74,0x6F,0x72,0x62,0x72,0x69,0x74,0x61,0x6E,0x6E,0x69,0x65,0x6E,0x29,0}; //"Engelsk (Storbritannien)" static char16_t esFor_en_T[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0}; //"Ingles" with acute on the e static char16_t esFor_en_GB_T[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"Ingles (Reino Unido)" ... -static char16_t esFor_en_GB_ST[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x55,0x29,0}; //"Ingles (RU)" ... -static char16_t esFor_en_GB_DT[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x62,0x72,0x69,0x74,0xE1,0x6E,0x69,0x63,0x6F,0}; //"Ingles britanico" with acute on the e, a +static char16_t esFor_en_GB_ST[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"Ingles (Reino Unido)" ... +static char16_t esFor_en_GB_DT[] = {0x49,0x6E,0x67,0x6C,0xE9,0x73,0x20,0x28,0x52,0x65,0x69,0x6E,0x6F,0x20,0x55,0x6E,0x69,0x64,0x6F,0x29,0}; //"Ingles (Reino Unido)" ... static char16_t ruFor_uz_Latn_T[]= {0x0423,0x0437,0x0431,0x0435,0x043A,0x0441,0x043A,0x0438,0x0439,0x20,0x28,0x043B,0x0430,0x0442,0x0438,0x043D,0x0438,0x0446,0x0430,0x29,0}; // first char upper #endif /* #if !UCONFIG_NO_BREAK_ITERATION */ diff --git a/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp b/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp index f01b64baf51..3492e06f92a 100644 --- a/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp +++ b/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp @@ -48,7 +48,7 @@ there was {$what} on planet {$planet :integer}.") .setArgument("planet", (int64_t) 7) .setDateArgument("when", (UDate) 871068000000) .setArgument("what", "a disturbance in the Force") - .setExpected(CharsToUnicodeString("At 12:20:00\\u202FPM on Aug 8, 1997, there was a disturbance in the Force on planet 7.")) + .setExpected(CharsToUnicodeString("At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7.")) .build(), errorCode); } diff --git a/icu/icu4c/source/test/intltest/regiontst.cpp b/icu/icu4c/source/test/intltest/regiontst.cpp index cdbeac793a7..f2b06fd3bb8 100644 --- a/icu/icu4c/source/test/intltest/regiontst.cpp +++ b/icu/icu4c/source/test/intltest/regiontst.cpp @@ -124,17 +124,14 @@ static KnownRegion knownRegions[] = { { "CZ" , 203, "151", URGN_TERRITORY, "150" }, { "DD" , 276, "155", URGN_TERRITORY, "150" }, { "DE" , 276, "155", URGN_TERRITORY, "150" }, - { "DG" , -1 , "QO" , URGN_TERRITORY, "009" }, { "DJ" , 262, "014", URGN_TERRITORY, "002" }, { "DK" , 208, "154", URGN_TERRITORY, "150" }, { "DM" , 212, "029", URGN_TERRITORY, "019" }, { "DO" , 214, "029", URGN_TERRITORY, "019" }, { "DZ" , 12, "015", URGN_TERRITORY, "002" }, - { "EA" , -1, "015", URGN_TERRITORY, "002" }, { "EC" , 218, "005", URGN_TERRITORY, "019" }, { "EE" , 233, "154", URGN_TERRITORY, "150" }, { "EG" , 818, "015", URGN_TERRITORY, "002" }, - { "EH" , 732, "015", URGN_TERRITORY, "002" }, { "ER" , 232, "014", URGN_TERRITORY, "002" }, { "ES" , 724, "039", URGN_TERRITORY, "150" }, { "ET" , 231, "014", URGN_TERRITORY, "002" }, @@ -171,7 +168,6 @@ static KnownRegion knownRegions[] = { { "HR" , 191, "039", URGN_TERRITORY, "150" }, { "HT" , 332, "029", URGN_TERRITORY, "019" }, { "HU" , 348, "151", URGN_TERRITORY, "150" }, - { "IC" , -1, "015", URGN_TERRITORY, "002" }, { "ID" , 360, "035", URGN_TERRITORY, "142" }, { "IE" , 372, "154", URGN_TERRITORY, "150" }, { "IL" , 376, "145", URGN_TERRITORY, "142" }, diff --git a/icu/icu4c/source/test/intltest/tmsgfmt.cpp b/icu/icu4c/source/test/intltest/tmsgfmt.cpp index 54b71ed3e78..0603136ba11 100644 --- a/icu/icu4c/source/test/intltest/tmsgfmt.cpp +++ b/icu/icu4c/source/test/intltest/tmsgfmt.cpp @@ -288,7 +288,7 @@ void TestMessageFormat::PatternTest() u"Quotes ', {, 'a' 1 {0}", u"Quotes ', {, 'a' 1 {0}", u"{1,number,'#',##} #34,56", - u"There are 3,456 files on Disk at 1/12/70, 5:46\u202FAM.", + u"There are 3,456 files on Disk at 1/12/70, 5:46 AM.", u"On Disk, there are 3,456 files, with $1.00.", u"{1,number,percent}, 345,600%,", u"{1,date,full}, Wednesday, December 31, 1969,", @@ -419,7 +419,7 @@ void TestMessageFormat::testStaticFormat() } const UnicodeString expected( - u"At 12:20:00\u202FPM on Aug 8, 1997, there was a disturbance in the Force on planet 7."); + u"At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7."); if (result != expected) { errln(UnicodeString("TestMessageFormat::testStaticFormat failed on test") + UnicodeString("\n Result: ") + result + @@ -1502,7 +1502,7 @@ void TestMessageFormat::TestUnlimitedArgsAndSubformats() { UnicodeString expected = u"On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) " - u"at 9:46:40\u202FAM (aka 9:46\u202FAM, aka 9:46:40\u202FAM PST) " + u"at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) " u"there were 1,303 werjes " u"(a 8% increase over 1,202) " u"despite the Glimmung's efforts " diff --git a/icu/icu4c/source/test/intltest/uprefstest.cpp b/icu/icu4c/source/test/intltest/uprefstest.cpp new file mode 100644 index 00000000000..69c5265eed1 --- /dev/null +++ b/icu/icu4c/source/test/intltest/uprefstest.cpp @@ -0,0 +1,438 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +#include "uprefstest.h" +#if U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY + +#define ARRAY_SIZE 512 + +std::wstring UPrefsTest::language = L""; +std::wstring UPrefsTest::currency = L""; +std::wstring UPrefsTest::hourCycle = L""; +int32_t UPrefsTest::firstday = 0; +int32_t UPrefsTest::measureSystem = 0; +CALID UPrefsTest::calendar = 0; + +void UPrefsTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) +{ + if (exec) logln("TestSuite UPrefsTest: "); + TESTCASE_AUTO_BEGIN; + TESTCASE_AUTO(TestGetDefaultLocaleAsBCP47Tag); + TESTCASE_AUTO(TestBCP47TagWithSorting); + TESTCASE_AUTO(TestBCP47TagChineseSimplified); + TESTCASE_AUTO(TestBCP47TagChineseSortingStroke); + TESTCASE_AUTO(TestBCP47TagJapanCalendar); + TESTCASE_AUTO(TestUseNeededBuffer); + TESTCASE_AUTO(TestGetNeededBuffer); + TESTCASE_AUTO(TestGetUnsupportedSorting); + TESTCASE_AUTO(Get24HourCycleMixed); + TESTCASE_AUTO(Get12HourCycleMixed); + TESTCASE_AUTO(Get12HourCycleMixed2); + TESTCASE_AUTO(Get12HourCycle); + TESTCASE_AUTO(Get12HourCycle2); + TESTCASE_AUTO_END; +} + +int32_t UPrefsTest::MockGetLocaleInfoEx(LPCWSTR lpLocaleName, LCTYPE LCType, LPWSTR lpLCData, + int cchData, UErrorCode *status) +{ + switch (LCType) + { + case LOCALE_SNAME: + if (cchData == 0) + { + *status = U_ZERO_ERROR; + return language.length() + 1; + } + + if (language.length() + 1 > cchData) + { + *status = U_BUFFER_OVERFLOW_ERROR; + return 0; + } + wcsncpy(lpLCData, language.c_str(), cchData); + *status = U_ZERO_ERROR; + return language.length(); + + case LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER: + if (cchData == 0) + { + *status = U_ZERO_ERROR; + return 2; + } + if (cchData < 2) + { + *status = U_BUFFER_OVERFLOW_ERROR; + return 0; + } + *(reinterpret_cast(lpLCData)) = calendar; + *status = U_ZERO_ERROR; + return 2; + + case LOCALE_SINTLSYMBOL: + if (cchData == 0) + { + *status = U_ZERO_ERROR; + return currency.length() + 1; + } + if (currency.length() + 1 > cchData) + { + *status = U_BUFFER_OVERFLOW_ERROR; + return 0; + } + wcsncpy(lpLCData, currency.c_str(), cchData); + *status = U_ZERO_ERROR; + return currency.length(); + + case LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER: + if (cchData == 0) + { + *status = U_ZERO_ERROR; + return 2; + } + if (cchData < 2) + { + *status = U_BUFFER_OVERFLOW_ERROR; + return 0; + } + + *(reinterpret_cast(lpLCData)) = firstday; + *status = U_ZERO_ERROR; + return 2; + + case LOCALE_STIMEFORMAT: + if (cchData == 0) + { + *status = U_ZERO_ERROR; + return hourCycle.length() + 1; + } + + if (hourCycle.length() + 1 > cchData) + { + *status = U_BUFFER_OVERFLOW_ERROR; + return 0; + } + wcsncpy(lpLCData, hourCycle.c_str(), cchData); + *status = U_ZERO_ERROR; + return 0; + + case LOCALE_IMEASURE | LOCALE_RETURN_NUMBER: + if (cchData == 0) + { + *status = U_ZERO_ERROR; + return 2; + } + + if (cchData < 2) + { + *status = U_BUFFER_OVERFLOW_ERROR; + return 0; + } + *(reinterpret_cast(lpLCData)) = measureSystem; + *status = U_ZERO_ERROR; + return 2; + + default: + *status = U_INTERNAL_PROGRAM_ERROR; + return 0; + } +} + +// The code above is independent of the library itself, but for the code below this point, +// we need to include the library to be able to use the definitions of the API uprefs_getBCP47Tag +#include "uprefs.cpp" + +void UPrefsTest::TestGetDefaultLocaleAsBCP47Tag() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"en-US"; + currency = L"USD"; + hourCycle = L"HH:mm:ss"; + firstday = 0; + measureSystem = 1; + calendar = CAL_GREGORIAN; + UErrorCode status = U_ZERO_ERROR; + const char* expectedValue = "en-US-u-ca-gregory-cu-usd-fw-mon-hc-h23-ms-ussystem"; + + if ( uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 52) + { + errln("Expected length to be 52, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::TestBCP47TagWithSorting() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"de-DE_phoneb"; + currency = L"EUR"; + hourCycle = L"HH:mm:ss"; + firstday = 0; + measureSystem = 1; + calendar = CAL_GREGORIAN; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "de-DE-u-ca-gregory-co-phonebk-cu-eur-fw-mon-hc-h23-ms-ussystem"; + + if ( uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 63) + { + errln("Expected length to be 63, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::TestBCP47TagChineseSimplified() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"zh-Hans-HK"; + currency = L"EUR"; + hourCycle = L"hh:mm:ss"; + firstday = 2; + measureSystem = 1; + calendar = CAL_GREGORIAN; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "zh-Hans-HK-u-ca-gregory-cu-eur-fw-wed-hc-h12-ms-ussystem"; + + if ( uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 57) + { + errln("Expected length to be 57, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::TestBCP47TagChineseSortingStroke() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"zh-SG_stroke"; + currency = L"EUR"; + hourCycle = L"hh:mm:ss"; + firstday = 2; + measureSystem = 0; + calendar = CAL_GREGORIAN; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "zh-SG-u-ca-gregory-co-stroke-cu-eur-fw-wed-hc-h12-ms-metric"; + + if ( uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 60) + { + errln("Expected length to be 60, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::TestBCP47TagJapanCalendar() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"ja-JP"; + currency = L"MXN"; + hourCycle = L"hh:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_JAPAN; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "ja-JP-u-ca-japanese-cu-mxn-fw-tue-hc-h12-ms-metric"; + + if ( uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::TestUseNeededBuffer() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"ja-JP"; + currency = L"MXN"; + hourCycle = L"hh:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_THAI; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "ja-JP-u-ca-buddhist-cu-mxn-fw-tue-hc-h12-ms-metric"; + + int32_t neededBufferSize = uprefs_getBCP47Tag(nullptr, 0, &status); + + if ( uprefs_getBCP47Tag(languageBuffer, neededBufferSize, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::TestGetNeededBuffer() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"zh-SG_stroke"; + currency = L"MXN"; + hourCycle = L"hh:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_THAI; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "zh-SG-u-ca-buddhist-co-stroke-cu-mxn-fw-tue-hc-h12-ms-metric"; + + int32_t neededBufferSize = uprefs_getBCP47Tag(nullptr, 0, &status); + + if ( neededBufferSize != 61) + { + errln("Expected buffer size to be 61, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprefs_getBCP47Tag(languageBuffer, neededBufferSize, &status) != 61) + { + errln("Expected length to be 61, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::TestGetUnsupportedSorting() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"hu-HU_technl"; + currency = L"MXN"; + hourCycle = L"hh:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_THAI; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "hu-HU-u-ca-buddhist-cu-mxn-fw-tue-hc-h12-ms-metric"; + + if ( uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n",uprv_strlen(languageBuffer)); + } + if ( uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::Get24HourCycleMixed() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"ja-JP"; + currency = L"MXN"; + hourCycle = L"HHhh:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_THAI; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "ja-JP-u-ca-buddhist-cu-mxn-fw-tue-hc-h23-ms-metric"; + + if (uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n", uprv_strlen(languageBuffer)); + } + if (uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::Get12HourCycleMixed() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"ja-JP"; + currency = L"MXN"; + hourCycle = L"hHhH:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_THAI; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "ja-JP-u-ca-buddhist-cu-mxn-fw-tue-hc-h12-ms-metric"; + + if (uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n", uprv_strlen(languageBuffer)); + } + if (uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + + +void UPrefsTest::Get12HourCycleMixed2() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"ja-JP"; + currency = L"MXN"; + hourCycle = L"hH''h'H'H:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_THAI; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "ja-JP-u-ca-buddhist-cu-mxn-fw-tue-hc-h12-ms-metric"; + + if (uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n", uprv_strlen(languageBuffer)); + } + if (uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::Get12HourCycle() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"ja-JP"; + currency = L"MXN"; + hourCycle = L"h'H'h:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_THAI; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "ja-JP-u-ca-buddhist-cu-mxn-fw-tue-hc-h12-ms-metric"; + + if (uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n", uprv_strlen(languageBuffer)); + } + if (uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} + +void UPrefsTest::Get12HourCycle2() +{ + char languageBuffer[ARRAY_SIZE] = {0}; + language = L"ja-JP"; + currency = L"MXN"; + hourCycle = L"'H'h'H'h:mm:ss"; + firstday = 1; + measureSystem = 0; + calendar = CAL_THAI; + UErrorCode status = U_ZERO_ERROR; + char* expectedValue = "ja-JP-u-ca-buddhist-cu-mxn-fw-tue-hc-h12-ms-metric"; + + if (uprefs_getBCP47Tag(languageBuffer, ARRAY_SIZE, &status) != 51) + { + errln("Expected length to be 51, but got: %d\n", uprv_strlen(languageBuffer)); + } + if (uprv_strcmp(expectedValue, languageBuffer) != 0) + { + errln("Expected BCP47Tag to be %s, but got: %s\n", expectedValue, languageBuffer); + } +} +#endif //U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY \ No newline at end of file diff --git a/icu/icu4c/source/test/intltest/uprefstest.h b/icu/icu4c/source/test/intltest/uprefstest.h new file mode 100644 index 00000000000..2f3e6515b06 --- /dev/null +++ b/icu/icu4c/source/test/intltest/uprefstest.h @@ -0,0 +1,50 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +#ifndef UPREFSTEST_H +#define UPREFSTEST_H + +#include "unicode/platform.h" +#if U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY +// We define UPREFS_TEST to use the mock version of GetLocaleInfoEx(), which +// allows us to simulate its behaviour and determine if the results given by the +// API align with what we expect to receive +#define UPREFS_TEST 1 + + +#include "windows.h" +#include "intltest.h" +#include "uprefs.h" + +class UPrefsTest: public IntlTest { +private: + static std::wstring language; + static std::wstring currency; + static std::wstring hourCycle; + static int32_t firstday; + static int32_t measureSystem; + static CALID calendar; + +public: + UPrefsTest(){}; + virtual ~UPrefsTest(){}; + + virtual void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = NULL) override; + int32_t MockGetLocaleInfoEx(LPCWSTR lpLocaleName, LCTYPE LCType, LPWSTR lpLCData, int cchData, UErrorCode* status); + void TestGetDefaultLocaleAsBCP47Tag(); + void TestBCP47TagWithSorting(); + void TestBCP47TagChineseSimplified(); + void TestBCP47TagChineseSortingStroke(); + void TestBCP47TagJapanCalendar(); + void TestUseNeededBuffer(); + void TestGetNeededBuffer(); + void TestGetUnsupportedSorting(); + void Get24HourCycleMixed(); + void Get12HourCycleMixed(); + void Get12HourCycleMixed2(); + void Get12HourCycle(); + void Get12HourCycle2(); +}; + + +#endif //U_PLATFORM_USES_ONLY_WIN32_API && UCONFIG_USE_WINDOWS_PREFERENCES_LIBRARY +#endif //UPREFSTEST_H \ No newline at end of file diff --git a/icu/icu4c/source/test/testdata/format.txt b/icu/icu4c/source/test/testdata/format.txt index e3d6e72fd8b..b8d3c3ba5b9 100644 --- a/icu/icu4c/source/test/testdata/format.txt +++ b/icu/icu4c/source/test/testdata/format.txt @@ -37,7 +37,7 @@ format:table(nofallback) { "", "DATE=SHORT,TIME=SHORT", "ERA=1,YEAR=2007,MONTH=AUGUST,DATE=8,HOUR_OF_DAY=18,MINUTE=54,SECOND=0", - "8/8/07, 6:54 PM" + "8/8/07, 6:54 PM" }, { "zh_TW@calendar=roc", @@ -102,14 +102,14 @@ format:table(nofallback) { "GMT", "TIME=LONG", "ERA=1,YEAR=2012,MONTH=OCTOBER,DATE=8,HOUR_OF_DAY=23,MINUTE=59,SECOND=0", - "11:59:00 PM GMT" + "11:59:00 PM GMT" }, { "en_US@calendar=gregorian", "GMT", "TIME=LONG", "RELATIVE_ADD:DATE=-1,HOUR_OF_DAY=17,MINUTE=0,SECOND=0", // one day before now at specified time - "5:00:00 PM GMT" + "5:00:00 PM GMT" }, // normal formats, combined using 'at' { @@ -117,7 +117,7 @@ format:table(nofallback) { "GMT", "DATE=RELATIVE_FULL,TIME=LONG", "ERA=1,YEAR=2012,MONTH=OCTOBER,DATE=8,HOUR_OF_DAY=23,MINUTE=59,SECOND=0", - "Monday, October 8, 2012, 11:59:00 PM GMT" + "Monday, October 8, 2012, 11:59:00 PM GMT" }, // normal formats, combined using ", " { @@ -125,7 +125,7 @@ format:table(nofallback) { "GMT", "DATE=RELATIVE_MEDIUM,TIME=SHORT", "ERA=1,YEAR=2012,MONTH=OCTOBER,DATE=8,HOUR_OF_DAY=23,MINUTE=59,SECOND=0", - "Oct 8, 2012, 11:59 PM" + "Oct 8, 2012, 11:59 PM" }, // formats with relative day, combined using 'at' { @@ -133,7 +133,7 @@ format:table(nofallback) { "GMT", "DATE=RELATIVE_FULL,TIME=LONG", "RELATIVE_ADD:DATE=-1,HOUR_OF_DAY=17,MINUTE=0,SECOND=0", // one day before now at specified time - "yesterday, 5:00:00 PM GMT" + "yesterday, 5:00:00 PM GMT" }, // formats with relative day, combined using ", " { @@ -141,7 +141,7 @@ format:table(nofallback) { "GMT", "DATE=RELATIVE_MEDIUM,TIME=SHORT", "RELATIVE_ADD:DATE=-1,HOUR_OF_DAY=17,MINUTE=0,SECOND=0", // one day before now at specified time - "yesterday, 5:00 PM" + "yesterday, 5:00 PM" }, // normal formats that have quoted literals, combined { @@ -554,7 +554,7 @@ format:table(nofallback) { "", "DATE=FULL,TIME=FULL", "MILLIS=3076424179200000", - "Friday, 3 Heshvan 103217 at 12:00:00 AM GMT-08:00" + "Friday, 3 Heshvan 103217 at 12:00:00 AM GMT-08:00" }, } } diff --git a/icu/icu4c/source/test/testdata/message2/icu4j/icu-test-functions.json b/icu/icu4c/source/test/testdata/message2/icu4j/icu-test-functions.json index 21f917da6e5..b72421119ee 100644 --- a/icu/icu4c/source/test/testdata/message2/icu4j/icu-test-functions.json +++ b/icu/icu4c/source/test/testdata/message2/icu4j/icu-test-functions.json @@ -2,18 +2,18 @@ "Date and time formats": [ { "src": "Expires on {$exp}", - "exp": "Expires on 8/3/24, 9:43 PM", + "exp": "Expires on 8/3/24, 9:43 PM", "comment": "Modified from ICU4J copy to add params (likewise with the other date/time tests); 1722746637000 is 2024-08-03 21:43:57 PDT", "params": {"exp": { "date": 1722746637000 } } }, { "src": "Expires on {$exp :datetime}", - "exp": "Expires on 8/3/24, 9:43 PM", + "exp": "Expires on 8/3/24, 9:43 PM", "params": {"exp": { "date": 1722746637000 } } }, { "src": "Expires on {$exp :datetime icu:skeleton=yMMMMdjmsSSEE}", - "exp": "Expires on Sat, August 3, 2024 at 9:43:57.00 PM", + "exp": "Expires on Sat, August 3, 2024 at 9:43:57.00 PM", "params": {"exp": { "date": 1722746637000 } }, "ignoreTest": "ICU-22754 Skeleton option not implemented yet" }, @@ -34,22 +34,22 @@ }, { "src": "Expires on {$exp :datetime timeStyle=long}", - "exp": "Expires on 9:43:57 PM PDT", + "exp": "Expires on 9:43:57 PM PDT", "params": {"exp": { "date": 1722746637000 } } }, { "src": "Expires on {$exp :datetime timeStyle=medium}", - "exp": "Expires on 9:43:57 PM", + "exp": "Expires on 9:43:57 PM", "params": {"exp": { "date": 1722746637000 } } }, { "src": "Expires on {$exp :datetime timeStyle=short}", - "exp": "Expires on 9:43 PM", + "exp": "Expires on 9:43 PM", "params": {"exp": { "date": 1722746637000 } } }, { "src": "Expires on {$exp :datetime dateStyle=full timeStyle=medium}", - "exp": "Expires on Saturday, August 3, 2024 at 9:43:57 PM", + "exp": "Expires on Saturday, August 3, 2024 at 9:43:57 PM", "params": {"exp": { "date": 1722746637000 } } }, { @@ -72,14 +72,14 @@ { "comment": "Make sure we ignore date / time fields if needed", "src": "Expires at {$exp :time year=numeric month=medium day=numeric weekday=long hour=numeric minute=numeric}", - "exp": "Expires at 9:43 PM", + "exp": "Expires at 9:43 PM", "params": {"exp": { "date": 1722746637000 } }, "ignoreTest": "ICU-22754 ICU4C doesn't accept field options for `:date` or `:time` -- see spec" }, { "comment": "Make sure we ignore date / time fields if needed", "src": "Expires at {$exp :time style=long dateStyle=full timeStyle=medium}", - "exp": "Expires at 9:43:57 PM PDT", + "exp": "Expires at 9:43:57 PM PDT", "params": {"exp": { "date": 1722746637000 } } }, { @@ -96,11 +96,11 @@ }, { "src": "Expires at {|2024-07-02T19:23:45| :datetime timeStyle=full}", - "exp": "Expires at 7:23:45 PM Pacific Daylight Time" + "exp": "Expires at 7:23:45 PM Pacific Daylight Time" }, { "src": "Expires at {|2024-07-02T19:23:45.123| :datetime timeStyle=full}", - "exp": "Expires at 7:23:45 PM Pacific Daylight Time" + "exp": "Expires at 7:23:45 PM Pacific Daylight Time" }, { "src": "Expires on {|2025-02-27T19:23:45| :datetime dateStyle=full}", @@ -108,11 +108,11 @@ }, { "src": "Expires at {|2024-07-02T19:23:45Z| :datetime timeStyle=long}", - "exp": "Expires at 7:23:45 PM GMT" + "exp": "Expires at 7:23:45 PM GMT" }, { "src": "Expires at {|2024-07-02T19:23:45+03:30| :datetime timeStyle=full}", - "exp": "Expires at 7:23:45 PM GMT+03:30" + "exp": "Expires at 7:23:45 PM GMT+03:30" } ], "Chaining" : [ @@ -125,7 +125,7 @@ ".local $zooExp = {$exp :datetime dateStyle=short timeStyle=$tsOver}\n", "{{Hello John, you want '{$exp}', '{$longExp}', or '{$zooExp}' or even '{$exp :datetime dateStyle=full}'?}}" ], - "exp": "Hello John, you want '9:43 PM', 'August 3, 2024 at 9:43 PM', or '8/3/24, 9:43:57 PM Pacific Daylight Time' or even 'Saturday, August 3, 2024 at 9:43 PM'?", + "exp": "Hello John, you want '9:43 PM', 'August 3, 2024 at 9:43 PM', or '8/3/24, 9:43:57 PM Pacific Daylight Time' or even 'Saturday, August 3, 2024 at 9:43 PM'?", "params": {"exp": { "date": 1722746637000 }, "user": "John", "tsOver" : "long" }, "ignoreTest": "ICU-22754 ICU4C doesn't implement this kind of function composition yet. See https://github.com/unicode-org/message-format-wg/issues/515" }, diff --git a/icu/icu4c/source/tools/toolutil/package.h b/icu/icu4c/source/tools/toolutil/package.h index ea60c13a74a..3a1d3cd23d9 100644 --- a/icu/icu4c/source/tools/toolutil/package.h +++ b/icu/icu4c/source/tools/toolutil/package.h @@ -27,7 +27,7 @@ // .dat package file representation ---------------------------------------- *** -#define STRING_STORE_SIZE 100000 +#define STRING_STORE_SIZE 200000 #define MAX_PKG_NAME_LENGTH 64 typedef void CheckDependency(void *context, const char *itemName, const char *targetName); diff --git a/icu/icu4c/source/tools/toolutil/pkg_gencmn.cpp b/icu/icu4c/source/tools/toolutil/pkg_gencmn.cpp index c1a46e9aed1..054208170af 100644 --- a/icu/icu4c/source/tools/toolutil/pkg_gencmn.cpp +++ b/icu/icu4c/source/tools/toolutil/pkg_gencmn.cpp @@ -22,7 +22,13 @@ #define STRING_STORE_SIZE 200000 -#define COMMON_DATA_NAME U_ICUDATA_NAME +// MSFT-Change: In the Windows OS ICU build, we only have one data package, and we use a versionless name in filename. +#if defined(ICU_DATA_DIR_WINDOWS) +# define COMMON_DATA_NAME "icudtl" +#else +# define COMMON_DATA_NAME U_ICUDATA_NAME +#endif + #define DATA_TYPE "dat" /* ICU package data file format (.dat files) ------------------------------- *** diff --git a/icu/testdata/message2/icu-test-functions.json b/icu/testdata/message2/icu-test-functions.json index a97446addf0..87e7b401b13 100644 --- a/icu/testdata/message2/icu-test-functions.json +++ b/icu/testdata/message2/icu-test-functions.json @@ -7,18 +7,18 @@ "tests": [ { "src": "Expires on {$exp}", - "exp": "Expires on 8/3/24, 9:43 PM", + "exp": "Expires on 8/3/24, 9:43 PM", "comment": "Modified from ICU4J copy to add params (likewise with the other date/time tests); 1722746637000 is 2024-08-03 21:43:57 PDT", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] }, { "src": "Expires on {$exp :datetime}", - "exp": "Expires on 8/3/24, 9:43 PM", + "exp": "Expires on 8/3/24, 9:43 PM", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] }, { "src": "Expires on {$exp :datetime icu:skeleton=yMMMMdjmsSSEE}", - "exp": "Expires on Sat, August 3, 2024 at 9:43:57.00 PM", + "exp": "Expires on Sat, August 3, 2024 at 9:43:57.00 PM", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }], "ignoreCpp": "ICU-22754 Skeleton option not implemented yet" }, @@ -39,22 +39,22 @@ }, { "src": "Expires on {$exp :datetime timeStyle=long}", - "exp": "Expires on 9:43:57 PM PDT", + "exp": "Expires on 9:43:57 PM PDT", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] }, { "src": "Expires on {$exp :datetime timeStyle=medium}", - "exp": "Expires on 9:43:57 PM", + "exp": "Expires on 9:43:57 PM", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] }, { "src": "Expires on {$exp :datetime timeStyle=short}", - "exp": "Expires on 9:43 PM", + "exp": "Expires on 9:43 PM", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] }, { "src": "Expires on {$exp :datetime dateStyle=full timeStyle=medium}", - "exp": "Expires on Saturday, August 3, 2024 at 9:43:57 PM", + "exp": "Expires on Saturday, August 3, 2024 at 9:43:57 PM", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] }, { @@ -77,14 +77,14 @@ { "comment": "Make sure we ignore date / time fields if needed", "src": "Expires at {$exp :time year=numeric month=medium day=numeric weekday=long hour=numeric minute=numeric}", - "exp": "Expires at 9:43 PM", + "exp": "Expires at 9:43 PM", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }], "ignoreCpp": "ICU-22754 ICU4C doesn't accept field options for `:date` or `:time` -- see spec" }, { "comment": "Make sure we ignore date / time fields if needed", "src": "Expires at {$exp :time style=long dateStyle=full timeStyle=medium}", - "exp": "Expires at 9:43:57 PM PDT", + "exp": "Expires at 9:43:57 PM PDT", "params": [{ "name": "exp", "value": { "date": 1722746637000 } }] }, { @@ -99,11 +99,11 @@ }, { "src": "Expires at {|2024-07-02T19:23:45| :datetime timeStyle=full}", - "exp": "Expires at 7:23:45 PM Pacific Daylight Time" + "exp": "Expires at 7:23:45 PM Pacific Daylight Time" }, { "src": "Expires at {|2024-07-02T19:23:45.123| :datetime timeStyle=full}", - "exp": "Expires at 7:23:45 PM Pacific Daylight Time" + "exp": "Expires at 7:23:45 PM Pacific Daylight Time" }, { "src": "Expires on {|2025-02-27T19:23:45| :datetime dateStyle=full}", @@ -111,12 +111,12 @@ }, { "src": "Expires at {|2024-07-02T19:23:45Z| :datetime timeStyle=long}", - "exp": "Expires at 7:23:45 PM GMT", + "exp": "Expires at 7:23:45 PM GMT", "ignoreCpp": "ICU-22754 Time zones not working yet (bug)" }, { "src": "Expires at {|2024-07-02T19:23:45+03:30| :datetime timeStyle=full}", - "exp": "Expires at 7:23:45 PM GMT+03:30", + "exp": "Expires at 7:23:45 PM GMT+03:30", "ignoreCpp": "ICU-22754 Time zones not working yet (bug)" }, { @@ -128,7 +128,7 @@ ".local $zooExp = {$exp :datetime dateStyle=short timeStyle=$tsOver}\n", "{{Hello John, you want '{$exp}', '{$longExp}', or '{$zooExp}' or even '{$exp :datetime dateStyle=full}'?}}" ], - "exp": "Hello John, you want '9:43 PM', 'August 3, 2024 at 9:43 PM', or '8/3/24, 9:43:57 PM Pacific Daylight Time' or even 'Saturday, August 3, 2024 at 9:43 PM'?", + "exp": "Hello John, you want '9:43 PM', 'August 3, 2024 at 9:43 PM', or '8/3/24, 9:43:57 PM Pacific Daylight Time' or even 'Saturday, August 3, 2024 at 9:43 PM'?", "params": [{"name": "exp", "value": { "date": 1722746637000 }}, {"name": "user", "value": "John"}, {"name": "tsOver", "value": "full" }], diff --git a/icu/testdata/message2/more-functions.json b/icu/testdata/message2/more-functions.json index 6d074f8b2d8..90dc1274ba7 100644 --- a/icu/testdata/message2/more-functions.json +++ b/icu/testdata/message2/more-functions.json @@ -47,17 +47,17 @@ }, { "src": "Testing date formatting: {$date :time style=long}.", - "exp": "Testing date formatting: 7:42:37\u202FPM PST.", + "exp": "Testing date formatting: 7:42:37 PM PST.", "params": [{ "name": "date", "value": { "date": 1669261357000 } }] }, { "src": "Testing date formatting: {$date :time style=medium}.", - "exp": "Testing date formatting: 7:42:37\u202FPM.", + "exp": "Testing date formatting: 7:42:37 PM.", "params": [{ "name": "date", "value": { "date": 1669261357000 } }] }, { "src": "Testing date formatting: {$date :time style=short}.", - "exp": "Testing date formatting: 7:42\u202FPM.", + "exp": "Testing date formatting: 7:42 PM.", "params": [{ "name": "date", "value": { "date": 1669261357000 } }] }, { diff --git a/icu/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/Cldr2IcuCliOptions.java b/icu/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/Cldr2IcuCliOptions.java index d9b46014438..9ff85b38d86 100644 --- a/icu/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/Cldr2IcuCliOptions.java +++ b/icu/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/Cldr2IcuCliOptions.java @@ -380,7 +380,9 @@ private void validateEnvironment() { if (!new File(icuDir).isDirectory() || ! new File(icuDir, "icu4c").isDirectory() - || ! new File(icuDir, "icu4j").isDirectory() + // MSFT-Change: microsoft/icu fork is icu4c-only; no icu4j source tree. + // The Maven dependency on icu4j (used by TransformsMapper) is still + // resolved from ~/.m2 at runtime, so source-tree absence is harmless. || ! new File(icuDir, "tools/cldr/cldr-to-icu").isDirectory() || ! new File(icuDir, "tools/cldr/cldr-to-icu/pom.xml").isFile()) { System.err.println("The `" + icuDir + "` directory does not look like a valid icu root.");