Nikolay Sivov : kernel32/locale: Add support for LOCALE_RETURN_GENITIVE_NAMES for LOCALE_SMONTHNAME* locale data , update Russian nls resource accordingly.

Alexandre Julliard julliard at winehq.org
Wed Oct 21 13:14:01 CDT 2009


Module: wine
Branch: master
Commit: 2b7a3657f7cb9ace7482cca8aeececeb83d65cc8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2b7a3657f7cb9ace7482cca8aeececeb83d65cc8

Author: Nikolay Sivov <bunglehead at 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);
   }
 }
 




More information about the wine-cvs mailing list