From 33ee03fe68e93e82094be48dd8a6ff0f8ab459ac Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Mon, 17 Aug 2015 15:48:37 -0700 Subject: [PATCH 2/2] kernel32: add Invariant string table wrc: add support for LANG_INVARIANT --- dlls/kernel32/locale_rc.rc | 2 + dlls/kernel32/nls/ivl.nls | 160 ++++++++++++++++++++++++++++++++++++ dlls/kernel32/tests/locale.c | 187 ++++++++++++++++++++++++++++++++++++++++++- tools/wrc/utils.c | 1 + 4 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 dlls/kernel32/nls/ivl.nls diff --git a/dlls/kernel32/locale_rc.rc b/dlls/kernel32/locale_rc.rc index 890c717..363e7ab 100644 --- a/dlls/kernel32/locale_rc.rc +++ b/dlls/kernel32/locale_rc.rc @@ -249,3 +249,5 @@ #include "nls/cor.nls" /* 0x0492 LANG_CORNISH, SUBLANG_DEFAULT */ #include "nls/gdv.nls" /* 0x0494 LANG_MANX_GAELIC, SUBLANG_MANX_GAELIC */ + +#include "nls/ivl.nls" /* 0x047f LANG_INVARIANT, SUBLANG_NEUTRAL */ diff --git a/dlls/kernel32/nls/ivl.nls b/dlls/kernel32/nls/ivl.nls new file mode 100644 index 0000000..16d6851 --- /dev/null +++ b/dlls/kernel32/nls/ivl.nls @@ -0,0 +1,160 @@ +/* + * Locale definitions for Invariant + * + * Copyright 2002 Alexandre Julliard for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma code_page(1252) + +STRINGTABLE LANGUAGE LANG_INVARIANT, SUBLANG_NEUTRAL +{ + LOCALE_FONTSIGNATURE L"\x00af\x8000\x38cb\x0000\x0000\x0000\x0000\x0000\x0001\x0000\x0000\x8000\x01ff\x003f\x8000\xffff" + LOCALE_ICALENDARTYPE "1" + LOCALE_ICENTURY "1" + LOCALE_ICOUNTRY "1" + LOCALE_ICURRDIGITS "2" + LOCALE_ICURRENCY "0" + LOCALE_IDATE "0" + LOCALE_IDAYLZERO "1" + LOCALE_IDEFAULTANSICODEPAGE "1252" + LOCALE_IDEFAULTCODEPAGE "437" + LOCALE_IDEFAULTCOUNTRY "1" + LOCALE_IDEFAULTEBCDICCODEPAGE "037" + LOCALE_IDEFAULTLANGUAGE "0409" + LOCALE_IDEFAULTMACCODEPAGE "10000" + LOCALE_IDEFAULTUNIXCODEPAGE "28591" + LOCALE_IDIGITS "2" + LOCALE_IDIGITSUBSTITUTION "1" + LOCALE_IFIRSTDAYOFWEEK "6" + LOCALE_IFIRSTWEEKOFYEAR "0" + LOCALE_IINTLCURRDIGITS "2" + LOCALE_ILANGUAGE "007f" + LOCALE_ILDATE "1" + LOCALE_ILZERO "1" + LOCALE_IMEASURE "0" + LOCALE_IMONLZERO "1" + LOCALE_INEGCURR "0" + LOCALE_INEGNUMBER "1" + LOCALE_INEGSEPBYSPACE "0" + LOCALE_INEGSIGNPOSN "0" + LOCALE_INEGSYMPRECEDES "1" + LOCALE_INEUTRAL "0" + LOCALE_IOPTIONALCALENDAR "0" + LOCALE_IPAPERSIZE "9" + LOCALE_IPOSSEPBYSPACE "0" + LOCALE_IPOSSIGNPOSN "3" + LOCALE_IPOSSYMPRECEDES "1" + LOCALE_IREADINGLAYOUT "0" + LOCALE_ITIME "1" + LOCALE_ITIMEMARKPOSN "0" + LOCALE_ITLZERO "1" + LOCALE_S1159 "AM" + LOCALE_S2359 "PM" + LOCALE_SABBREVCTRYNAME "IVC" + LOCALE_SABBREVDAYNAME1 "Mon" + LOCALE_SABBREVDAYNAME2 "Tue" + LOCALE_SABBREVDAYNAME3 "Wed" + LOCALE_SABBREVDAYNAME4 "Thu" + LOCALE_SABBREVDAYNAME5 "Fri" + LOCALE_SABBREVDAYNAME6 "Sat" + LOCALE_SABBREVDAYNAME7 "Sun" + LOCALE_SABBREVLANGNAME "IVL" + LOCALE_SABBREVMONTHNAME1 "Jan" + LOCALE_SABBREVMONTHNAME2 "Feb" + LOCALE_SABBREVMONTHNAME3 "Mar" + LOCALE_SABBREVMONTHNAME4 "Apr" + LOCALE_SABBREVMONTHNAME5 "May" + LOCALE_SABBREVMONTHNAME6 "Jun" + LOCALE_SABBREVMONTHNAME7 "Jul" + LOCALE_SABBREVMONTHNAME8 "Aug" + LOCALE_SABBREVMONTHNAME9 "Sep" + LOCALE_SABBREVMONTHNAME10 "Oct" + LOCALE_SABBREVMONTHNAME11 "Nov" + LOCALE_SABBREVMONTHNAME12 "Dec" + LOCALE_SABBREVMONTHNAME13 "" + LOCALE_SCOUNTRY "Invariant Country" + LOCALE_SCURRENCY "¤" + LOCALE_SDATE "/" + LOCALE_SDAYNAME1 "Monday" + LOCALE_SDAYNAME2 "Tuesday" + LOCALE_SDAYNAME3 "Wednesday" + LOCALE_SDAYNAME4 "Thursday" + LOCALE_SDAYNAME5 "Friday" + LOCALE_SDAYNAME6 "Saturday" + LOCALE_SDAYNAME7 "Sunday" + LOCALE_SDECIMAL "." + LOCALE_SENGCOUNTRY "Invariant Country" + LOCALE_SENGCURRNAME "International Monetary Fund" + LOCALE_SENGLANGUAGE "Invariant Language" + LOCALE_SGROUPING "3;0" + LOCALE_SINTLSYMBOL "XDR" + LOCALE_SISO3166CTRYNAME "IV" + LOCALE_SISO639LANGNAME "iv" + LOCALE_SLANGUAGE "Invariant Language (Invariant Country)" + LOCALE_SLIST "," + LOCALE_SLONGDATE "dddd, dd MMMM yyyy" + LOCALE_SMONDECIMALSEP "." + LOCALE_SMONGROUPING "3;0" + LOCALE_SMONTHNAME1 "January" + LOCALE_SMONTHNAME2 "February" + LOCALE_SMONTHNAME3 "March" + LOCALE_SMONTHNAME4 "April" + LOCALE_SMONTHNAME5 "May" + LOCALE_SMONTHNAME6 "June" + LOCALE_SMONTHNAME7 "July" + LOCALE_SMONTHNAME8 "August" + LOCALE_SMONTHNAME9 "September" + LOCALE_SMONTHNAME10 "October" + LOCALE_SMONTHNAME11 "November" + LOCALE_SMONTHNAME12 "December" + LOCALE_SMONTHNAME13 "" + LOCALE_SMONTHOUSANDSEP "," + LOCALE_SNAME "" + LOCALE_SNATIVECTRYNAME "Invariant Country" + LOCALE_SNATIVECURRNAME "International Monetary Fund" + LOCALE_SNATIVEDIGITS "0123456789" + LOCALE_SNATIVEDISPLAYNAME "Invariant Language (Invariant Country)" + LOCALE_SNATIVELANGNAME "Invariant Language" + LOCALE_SNEGATIVESIGN "-" + LOCALE_SOPENTYPELANGUAGETAG "dflt" + LOCALE_SPOSITIVESIGN "+" + LOCALE_SSCRIPTS "Latn;" + LOCALE_SSHORTDATE "MM/dd/yyyy" + LOCALE_SSORTNAME "Math Alphanumerics" + LOCALE_STHOUSAND "," + LOCALE_STIME ":" + LOCALE_STIMEFORMAT "HH:mm:ss" + LOCALE_SYEARMONTH "yyyy MMMM" + + LGRPID_WESTERN_EUROPE+LGRPID_RES_BASE "Western Europe and United States" + LGRPID_CENTRAL_EUROPE+LGRPID_RES_BASE "Central Europe" + LGRPID_BALTIC+LGRPID_RES_BASE "Baltic" + LGRPID_GREEK+LGRPID_RES_BASE "Greek" + LGRPID_CYRILLIC+LGRPID_RES_BASE "Cyrillic" + LGRPID_TURKISH+LGRPID_RES_BASE "Turkic" + LGRPID_JAPANESE+LGRPID_RES_BASE "Japanese" + LGRPID_KOREAN+LGRPID_RES_BASE "Korean" + LGRPID_TRADITIONAL_CHINESE+LGRPID_RES_BASE "Traditional Chinese" + LGRPID_SIMPLIFIED_CHINESE+LGRPID_RES_BASE "Simplified Chinese" + LGRPID_THAI+LGRPID_RES_BASE "Thai" + LGRPID_HEBREW+LGRPID_RES_BASE "Hebrew" + LGRPID_ARABIC+LGRPID_RES_BASE "Arabic" + LGRPID_VIETNAMESE+LGRPID_RES_BASE "Vietnamese" + LGRPID_INDIC+LGRPID_RES_BASE "Indic" + LGRPID_GEORGIAN+LGRPID_RES_BASE "Georgian" + LGRPID_ARMENIAN+LGRPID_RES_BASE "Armenian" +} diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 51e2b07..31bf8db 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -2420,7 +2420,7 @@ static void test_LocaleNameToLCID(void) lcid = pLocaleNameToLCID(LOCALE_NAME_INVARIANT, 0); ok(lcid == 0x7F, "Expected lcid = 0x7F, got %08x, error %d\n", lcid, GetLastError()); ret = pLCIDToLocaleName(lcid, buffer, LOCALE_NAME_MAX_LENGTH, 0); - todo_wine ok(ret > 0, "Expected ret > 0, got %d, error %d\n", ret, GetLastError()); + ok(ret > 0, "Expected ret > 0, got %d, error %d\n", ret, GetLastError()); trace("%08x, %s\n", lcid, wine_dbgstr_w(buffer)); /* bad name */ @@ -4317,6 +4317,190 @@ static void test_EnumSystemGeoID(void) } } +struct invariant_entry { + const char *name; + int id; + const char *expect; +}; + +#define X(x) #x, x +static const struct invariant_entry invariant_list[] = { + { X(LOCALE_ILANGUAGE), "007f" }, + { X(LOCALE_SENGLANGUAGE), "Invariant Language" }, + { X(LOCALE_SABBREVLANGNAME), "IVL" }, + { X(LOCALE_SNATIVELANGNAME), "Invariant Language" }, + { X(LOCALE_ICOUNTRY), "1" }, + { X(LOCALE_SENGCOUNTRY), "Invariant Country" }, + { X(LOCALE_SABBREVCTRYNAME), "IVC" }, + { X(LOCALE_SNATIVECTRYNAME), "Invariant Country" }, + { X(LOCALE_IDEFAULTLANGUAGE), "0409" }, + { X(LOCALE_IDEFAULTCOUNTRY), "1" }, + { X(LOCALE_IDEFAULTCODEPAGE), "437" }, + { X(LOCALE_IDEFAULTANSICODEPAGE), "1252" }, + { X(LOCALE_IDEFAULTMACCODEPAGE), "10000" }, + { X(LOCALE_SLIST), "," }, + { X(LOCALE_IMEASURE), "0" }, + { X(LOCALE_SDECIMAL), "." }, + { X(LOCALE_STHOUSAND), "," }, + { X(LOCALE_SGROUPING), "3;0" }, + { X(LOCALE_IDIGITS), "2" }, + { X(LOCALE_ILZERO), "1" }, + { X(LOCALE_INEGNUMBER), "1" }, + { X(LOCALE_SNATIVEDIGITS), "0123456789" }, + { X(LOCALE_SCURRENCY), "¤" }, + { X(LOCALE_SINTLSYMBOL), "XDR" }, + { X(LOCALE_SMONDECIMALSEP), "." }, + { X(LOCALE_SMONTHOUSANDSEP), "," }, + { X(LOCALE_SMONGROUPING), "3;0" }, + { X(LOCALE_ICURRDIGITS), "2" }, + { X(LOCALE_IINTLCURRDIGITS), "2" }, + { X(LOCALE_ICURRENCY), "0" }, + { X(LOCALE_INEGCURR), "0" }, + { X(LOCALE_SDATE), "/" }, + { X(LOCALE_STIME), ":" }, + { X(LOCALE_SSHORTDATE), "MM/dd/yyyy" }, + { X(LOCALE_SLONGDATE), "dddd, dd MMMM yyyy" }, + { X(LOCALE_STIMEFORMAT), "HH:mm:ss" }, + { X(LOCALE_IDATE), "0" }, + { X(LOCALE_ILDATE), "1" }, + { X(LOCALE_ITIME), "1" }, + { X(LOCALE_ITIMEMARKPOSN), "0" }, + { X(LOCALE_ICENTURY), "1" }, + { X(LOCALE_ITLZERO), "1" }, + { X(LOCALE_IDAYLZERO), "1" }, + { X(LOCALE_IMONLZERO), "1" }, + { X(LOCALE_S1159), "AM" }, + { X(LOCALE_S2359), "PM" }, + { X(LOCALE_ICALENDARTYPE), "1" }, + { X(LOCALE_IOPTIONALCALENDAR), "0" }, + { X(LOCALE_IFIRSTDAYOFWEEK), "6" }, + { X(LOCALE_IFIRSTWEEKOFYEAR), "0" }, + { X(LOCALE_SDAYNAME1), "Monday" }, + { X(LOCALE_SDAYNAME2), "Tuesday" }, + { X(LOCALE_SDAYNAME3), "Wednesday" }, + { X(LOCALE_SDAYNAME4), "Thursday" }, + { X(LOCALE_SDAYNAME5), "Friday" }, + { X(LOCALE_SDAYNAME6), "Saturday" }, + { X(LOCALE_SDAYNAME7), "Sunday" }, + { X(LOCALE_SABBREVDAYNAME1), "Mon" }, + { X(LOCALE_SABBREVDAYNAME2), "Tue" }, + { X(LOCALE_SABBREVDAYNAME3), "Wed" }, + { X(LOCALE_SABBREVDAYNAME4), "Thu" }, + { X(LOCALE_SABBREVDAYNAME5), "Fri" }, + { X(LOCALE_SABBREVDAYNAME6), "Sat" }, + { X(LOCALE_SABBREVDAYNAME7), "Sun" }, + { X(LOCALE_SMONTHNAME1), "January" }, + { X(LOCALE_SMONTHNAME2), "February" }, + { X(LOCALE_SMONTHNAME3), "March" }, + { X(LOCALE_SMONTHNAME4), "April" }, + { X(LOCALE_SMONTHNAME5), "May" }, + { X(LOCALE_SMONTHNAME6), "June" }, + { X(LOCALE_SMONTHNAME7), "July" }, + { X(LOCALE_SMONTHNAME8), "August" }, + { X(LOCALE_SMONTHNAME9), "September" }, + { X(LOCALE_SMONTHNAME10), "October" }, + { X(LOCALE_SMONTHNAME11), "November" }, + { X(LOCALE_SMONTHNAME12), "December" }, + { X(LOCALE_SMONTHNAME13), "" }, + { X(LOCALE_SABBREVMONTHNAME1), "Jan" }, + { X(LOCALE_SABBREVMONTHNAME2), "Feb" }, + { X(LOCALE_SABBREVMONTHNAME3), "Mar" }, + { X(LOCALE_SABBREVMONTHNAME4), "Apr" }, + { X(LOCALE_SABBREVMONTHNAME5), "May" }, + { X(LOCALE_SABBREVMONTHNAME6), "Jun" }, + { X(LOCALE_SABBREVMONTHNAME7), "Jul" }, + { X(LOCALE_SABBREVMONTHNAME8), "Aug" }, + { X(LOCALE_SABBREVMONTHNAME9), "Sep" }, + { X(LOCALE_SABBREVMONTHNAME10), "Oct" }, + { X(LOCALE_SABBREVMONTHNAME11), "Nov" }, + { X(LOCALE_SABBREVMONTHNAME12), "Dec" }, + { X(LOCALE_SABBREVMONTHNAME13), "" }, + { X(LOCALE_SPOSITIVESIGN), "+" }, + { X(LOCALE_SNEGATIVESIGN), "-" }, + { X(LOCALE_IPOSSIGNPOSN), "3" }, + { X(LOCALE_INEGSIGNPOSN), "0" }, + { X(LOCALE_IPOSSYMPRECEDES), "1" }, + { X(LOCALE_IPOSSEPBYSPACE), "0" }, + { X(LOCALE_INEGSYMPRECEDES), "1" }, + { X(LOCALE_INEGSEPBYSPACE), "0" }, + { X(LOCALE_SISO639LANGNAME), "iv" }, + { X(LOCALE_SISO3166CTRYNAME), "IV" }, + { X(LOCALE_IDEFAULTEBCDICCODEPAGE), "037" }, + { X(LOCALE_IPAPERSIZE), "9" }, + { X(LOCALE_SENGCURRNAME), "International Monetary Fund" }, + { X(LOCALE_SNATIVECURRNAME), "International Monetary Fund" }, + { X(LOCALE_SYEARMONTH), "yyyy MMMM" }, + { X(LOCALE_IDIGITSUBSTITUTION), "1" }, + { X(LOCALE_SNAME), "" }, + { X(LOCALE_SSCRIPTS), "Latn;" }, + { 0 } +}; +#undef X + +static void test_invariant(void) +{ + int ret; + int len; + char buffer[BUFFER_SIZE]; + const struct invariant_entry *ptr = invariant_list; + + if (!GetLocaleInfoA(LOCALE_INVARIANT, NUO|LOCALE_SLANGUAGE, buffer, sizeof(buffer))) + { + win_skip("GetLocaleInfoA(LOCALE_INVARIANT) not supported\n"); /* win2k */ + return; + } + + while (ptr->name) + { + ret = GetLocaleInfoA(LOCALE_INVARIANT, NUO|ptr->id, buffer, sizeof(buffer)); + if (!ret && (ptr->id == LOCALE_SNAME || ptr->id == LOCALE_SSCRIPTS)) + win_skip("not supported\n"); /* winxp/win2k3 */ + else + { + len = strlen(ptr->expect)+1; /* include \0 */ + ok(ret == len, "For id %d, expected ret == %d, got %d, error %d\n", + ptr->id, len, ret, GetLastError()); + ok(!strcmp(buffer, ptr->expect), "For id %d, Expected %s, got '%s'\n", + ptr->id, ptr->expect, buffer); + } + + ptr++; + } + + if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) || + (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH)) + { + skip("Non-English locale\n"); + } + else + { + /* some locales translate these */ + static const char lang[] = "Invariant Language (Invariant Country)"; + static const char cntry[] = "Invariant Country"; + static const char sortm[] = "Math Alphanumerics"; + static const char sortd[] = "Default"; /* win2k3 */ + + ret = GetLocaleInfoA(LOCALE_INVARIANT, NUO|LOCALE_SLANGUAGE, buffer, sizeof(buffer)); + len = lstrlenA(lang) + 1; + ok(ret == len, "Expected ret == %d, got %d, error %d\n", len, ret, GetLastError()); + ok(!strcmp(buffer, lang), "Expected %s, got '%s'\n", lang, buffer); + + ret = GetLocaleInfoA(LOCALE_INVARIANT, NUO|LOCALE_SCOUNTRY, buffer, sizeof(buffer)); + len = lstrlenA(cntry) + 1; + ok(ret == len, "Expected ret == %d, got %d, error %d\n", len, ret, GetLastError()); + ok(!strcmp(buffer, cntry), "Expected %s, got '%s'\n", cntry, buffer); + + ret = GetLocaleInfoA(LOCALE_INVARIANT, NUO|LOCALE_SSORTNAME, buffer, sizeof(buffer)); + if (ret == lstrlenA(sortm)+1) + ok(!strcmp(buffer, sortm), "Expected %s, got '%s'\n", sortm, buffer); + else if (ret == lstrlenA(sortd)+1) /* win2k3 */ + ok(!strcmp(buffer, sortd), "Expected %s, got '%s'\n", sortd, buffer); + else + ok(0, "Expected ret == %d or %d, got %d, error %d\n", + lstrlenA(sortm)+1, lstrlenA(sortd)+1, ret, GetLastError()); + } +} + START_TEST(locale) { InitFunctionPointers(); @@ -4356,6 +4540,7 @@ START_TEST(locale) test_CompareStringOrdinal(); test_GetGeoInfo(); test_EnumSystemGeoID(); + test_invariant(); /* this requires collation table patch to make it MS compatible */ if (0) test_sorting(); } diff --git a/tools/wrc/utils.c b/tools/wrc/utils.c index 4dc3364..5360b95 100644 --- a/tools/wrc/utils.c +++ b/tools/wrc/utils.c @@ -453,6 +453,7 @@ static const struct lang2cp lang2cps[] = { LANG_INDONESIAN, SUBLANG_NEUTRAL, 1252 }, { LANG_INUKTITUT, SUBLANG_NEUTRAL, 0 }, { LANG_INUKTITUT, SUBLANG_INUKTITUT_CANADA_LATIN, 0 }, + { LANG_INVARIANT, SUBLANG_NEUTRAL, 0 }, { LANG_IRISH, SUBLANG_NEUTRAL, 1252 }, { LANG_ITALIAN, SUBLANG_NEUTRAL, 1252 }, { LANG_JAPANESE, SUBLANG_NEUTRAL, 932 }, -- 1.9.5