Module: wine Branch: master Commit: 2b7a3657f7cb9ace7482cca8aeececeb83d65cc8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2b7a3657f7cb9ace7482cca8ae...
Author: Nikolay Sivov bunglehead@gmail.com Date: Wed Oct 21 05:34:59 2009 +0400
kernel32/locale: Add support for LOCALE_RETURN_GENITIVE_NAMES for LOCALE_SMONTHNAME* locale data, update Russian nls resource accordingly.
---
dlls/kernel32/locale.c | 60 +++++++++++++++++++++++++++++++++++++++-- dlls/kernel32/nls/rus.nls | 24 ++++++++-------- dlls/kernel32/tests/locale.c | 32 ++++++++++++++++++---- 3 files changed, 95 insertions(+), 21 deletions(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index 9071ff9..dcbef36 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -53,7 +53,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(nls);
-#define LOCALE_LOCALEINFOFLAGSMASK (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP|LOCALE_RETURN_NUMBER) +#define LOCALE_LOCALEINFOFLAGSMASK (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP|\ + LOCALE_RETURN_NUMBER|LOCALE_RETURN_GENITIVE_NAMES)
/* current code pages */ static const union cptable *ansi_cptable; @@ -579,6 +580,33 @@ static LCID convert_default_lcid( LCID lcid, LCTYPE lctype ) return ConvertDefaultLocale( lcid ); }
+/*********************************************************************** + * is_genitive_name_supported + * + * Determine could LCTYPE basically support genitive name form or not. + */ +static BOOL is_genitive_name_supported( LCTYPE lctype ) +{ + switch(lctype & 0xffff) + { + case LOCALE_SMONTHNAME1: + case LOCALE_SMONTHNAME2: + case LOCALE_SMONTHNAME3: + case LOCALE_SMONTHNAME4: + case LOCALE_SMONTHNAME5: + case LOCALE_SMONTHNAME6: + case LOCALE_SMONTHNAME7: + case LOCALE_SMONTHNAME8: + case LOCALE_SMONTHNAME9: + case LOCALE_SMONTHNAME10: + case LOCALE_SMONTHNAME11: + case LOCALE_SMONTHNAME12: + case LOCALE_SMONTHNAME13: + return TRUE; + default: + return FALSE; + } +}
/*********************************************************************** * create_registry_key @@ -1163,6 +1191,12 @@ INT WINAPI GetLocaleInfoA( LCID lcid, LCTYPE lctype, LPSTR buffer, INT len ) SetLastError( ERROR_INVALID_PARAMETER ); return 0; } + if (lctype & LOCALE_RETURN_GENITIVE_NAMES ) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } + if (!len) buffer = NULL;
if (!(lenW = GetLocaleInfoW( lcid, lctype, NULL, 0 ))) return 0; @@ -1221,6 +1255,13 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len ) SetLastError( ERROR_INVALID_PARAMETER ); return 0; } + if (lctype & LOCALE_RETURN_GENITIVE_NAMES && + !is_genitive_name_supported( lctype )) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } + if (!len) buffer = NULL;
lcid = convert_default_lcid( lcid, lctype ); @@ -1289,7 +1330,20 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len ) for (i = 0; i < (lctype & 0x0f); i++) p += *p + 1;
if (lcflags & LOCALE_RETURN_NUMBER) ret = sizeof(UINT)/sizeof(WCHAR); - else ret = (lctype == LOCALE_FONTSIGNATURE) ? *p : *p + 1; + else if (is_genitive_name_supported( lctype ) && *p) + { + /* genitive form's stored after a null separator from a nominative */ + for (i = 1; i <= *p; i++) if (!p[i]) break; + + if (i <= *p && (lcflags & LOCALE_RETURN_GENITIVE_NAMES)) + { + ret = *p - i - 1; + p += i; + } + else ret = i; + } + else + ret = (lctype == LOCALE_FONTSIGNATURE) ? *p : *p + 1;
if (!buffer) return ret;
@@ -1321,7 +1375,7 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len ) } else { - memcpy( buffer, p + 1, *p * sizeof(WCHAR) ); + memcpy( buffer, p + 1, ret * sizeof(WCHAR) ); if (lctype != LOCALE_FONTSIGNATURE) buffer[ret-1] = 0;
TRACE( "(lcid=0x%x,lctype=0x%x,%p,%d) returning %d %s\n", diff --git a/dlls/kernel32/nls/rus.nls b/dlls/kernel32/nls/rus.nls index fdda023..5cead81 100644 --- a/dlls/kernel32/nls/rus.nls +++ b/dlls/kernel32/nls/rus.nls @@ -107,18 +107,18 @@ STRINGTABLE LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT LOCALE_SLONGDATE "d MMMM yyyy 'г.'" LOCALE_SMONDECIMALSEP "," LOCALE_SMONGROUPING "3;0" - LOCALE_SMONTHNAME1 "Январь" - LOCALE_SMONTHNAME2 "Февраль" - LOCALE_SMONTHNAME3 "Март" - LOCALE_SMONTHNAME4 "Апрель" - LOCALE_SMONTHNAME5 "Май" - LOCALE_SMONTHNAME6 "Июнь" - LOCALE_SMONTHNAME7 "Июль" - LOCALE_SMONTHNAME8 "Август" - LOCALE_SMONTHNAME9 "Сентябрь" - LOCALE_SMONTHNAME10 "Октябрь" - LOCALE_SMONTHNAME11 "Ноябрь" - LOCALE_SMONTHNAME12 "Декабрь" + LOCALE_SMONTHNAME1 "Январь\0января" + LOCALE_SMONTHNAME2 "Февраль\0февраля" + LOCALE_SMONTHNAME3 "Март\0марта" + LOCALE_SMONTHNAME4 "Апрель\0апреля" + LOCALE_SMONTHNAME5 "Май\0мая" + LOCALE_SMONTHNAME6 "Июнь\0июня" + LOCALE_SMONTHNAME7 "Июль\0июля" + LOCALE_SMONTHNAME8 "Август\0августа" + LOCALE_SMONTHNAME9 "Сентябрь\0сентября" + LOCALE_SMONTHNAME10 "Октябрь\0октября" + LOCALE_SMONTHNAME11 "Ноябрь\0ноября" + LOCALE_SMONTHNAME12 "Декабрь\0декабря" LOCALE_SMONTHNAME13 "" LOCALE_SMONTHOUSANDSEP " " LOCALE_SNAME "ru-RU" diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index f4db1ba..77fae8b 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -211,22 +211,25 @@ static void test_GetLocaleInfoW(void)
/* LOCALE_RETURN_GENITIVE_NAMES isn't supported for GetLocaleInfoA */ bufferA[0] = 'a'; + SetLastError(0xdeadbeef); ret = GetLocaleInfoA(lcid_ru, LOCALE_SMONTHNAME1|LOCALE_RETURN_GENITIVE_NAMES, bufferA, COUNTOF(bufferA)); -todo_wine { ok(ret == 0, "LOCALE_RETURN_GENITIVE_NAMES should fail with GetLocaleInfoA\n"); ok(bufferA[0] == 'a', "Expected buffer to be untouched\n"); -} + ok(GetLastError() == ERROR_INVALID_FLAGS, + "Expected ERROR_INVALID_FLAGS, got %x\n", GetLastError());
bufferW[0] = 'a'; + SetLastError(0xdeadbeef); ret = GetLocaleInfoW(lcid_ru, LOCALE_RETURN_GENITIVE_NAMES, bufferW, COUNTOF(bufferW)); -todo_wine { ok(ret == 0, "LOCALE_RETURN_GENITIVE_NAMES itself doesn't return anything, got %d\n", ret); ok(bufferW[0] == 'a', "Expected buffer to be untouched\n"); -} + ok(GetLastError() == ERROR_INVALID_FLAGS, + "Expected ERROR_INVALID_FLAGS, got %x\n", GetLastError());
+ /* yes, test empty 13 month entry too */ for (i = 0; i < 12; i++) { bufferW[0] = 0; ret = GetLocaleInfoW(lcid_ru, (LOCALE_SMONTHNAME1+i)|LOCALE_RETURN_GENITIVE_NAMES, @@ -241,8 +244,25 @@ todo_wine { ok(ret == lstrlenW(buffer2W)+1, "Expected actual length, got %d, length %d\n", ret, lstrlenW(buffer2W));
- todo_wine ok(lstrcmpW(bufferW, buffer2W) != 0, - "Expected genitive name to differ, got the same for month %d\n", i+1); + ok(lstrcmpW(bufferW, buffer2W) != 0, + "Expected genitive name to differ, got the same for month %d\n", i+1); + + /* for locale without genitive names nominative returned in both cases */ + bufferW[0] = 0; + ret = GetLocaleInfoW(lcid_en, (LOCALE_SMONTHNAME1+i)|LOCALE_RETURN_GENITIVE_NAMES, + bufferW, COUNTOF(bufferW)); + ok(ret, "Expected non zero result\n"); + ok(ret == lstrlenW(bufferW)+1, "Expected actual length, got %d, length %d\n", + ret, lstrlenW(bufferW)); + buffer2W[0] = 0; + ret = GetLocaleInfoW(lcid_en, LOCALE_SMONTHNAME1+i, + buffer2W, COUNTOF(buffer2W)); + ok(ret, "Expected non zero result\n"); + ok(ret == lstrlenW(buffer2W)+1, "Expected actual length, got %d, length %d\n", + ret, lstrlenW(buffer2W)); + + ok(lstrcmpW(bufferW, buffer2W) == 0, + "Expected same names, got different for month %d\n", i+1); } }