[PATCH 10/10] Add support for LOCALE_RETURN_GENITIVE_NAMES for LOCALE_SMONTHNAME* locale data, update Russian nls resource accordingly
Nikolay Sivov
bunglehead at gmail.com
Tue Oct 20 20:34:59 CDT 2009
---
dlls/kernel32/locale.c | 75 +++++++++++++++++++++++++++++++++++++++--
dlls/kernel32/nls/rus.nls | 24 +++++++-------
dlls/kernel32/tests/locale.c | 32 ++++++++++++++---
3 files changed, 109 insertions(+), 22 deletions(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index 9071ff9..a8a6fda 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;
@@ -1213,7 +1247,7 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len )
HGLOBAL hmem;
INT ret;
UINT lcflags;
- const WCHAR *p;
+ WCHAR *p, *ptr;
unsigned int i;
if (len < 0 || (len && !buffer))
@@ -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 );
@@ -1287,9 +1328,33 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len )
p = LockResource( hmem );
for (i = 0; i < (lctype & 0x0f); i++) p += *p + 1;
+ ptr = p;
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)
+ {
+ int nom_length = 0;
+
+ /* genitive form's stored after a null separator from a nominative */
+ while (++nom_length < *p && *++ptr) ;
+
+ /* no genitive form in locale data */
+ if (nom_length == *p)
+ {
+ ret = *p + 1;
+ ptr = p;
+ }
+ else if (lcflags & LOCALE_RETURN_GENITIVE_NAMES)
+ ret = *p - nom_length + 1;
+ else
+ {
+ /* genitive form is available but not requested */
+ ret = nom_length;
+ ptr = p;
+ }
+ }
+ else
+ ret = (lctype == LOCALE_FONTSIGNATURE) ? *p : *p + 1;
if (!buffer) return ret;
@@ -1321,7 +1386,9 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len )
}
else
{
- memcpy( buffer, p + 1, *p * sizeof(WCHAR) );
+ /* we don't always need whole resource data */
+ i = (ret == *p) ? *p : ret - 1;
+ memcpy( buffer, ptr + 1, i * 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);
}
}
--
1.5.6.5
--=-Y6bS6CEIvEWAnGpb8csB--
More information about the wine-patches
mailing list