2002-05-29 02:30:32 +02:00
/*
2003-09-18 00:40:07 +02:00
* Unit tests for locale functions
2002-05-29 02:30:32 +02:00
*
2003-09-18 00:40:07 +02:00
* Copyright 2002 YASAR Mehmet
2003-06-27 21:02:23 +02:00
* Copyright 2003 Dmitry Timoshkov
2003-09-18 00:40:07 +02:00
* Copyright 2003 Jon Griffiths
2002-05-29 02:30:32 +02:00
*
* 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
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2003-09-18 00:40:07 +02:00
*
* NOTES
* We must pass LOCALE_NOUSEROVERRIDE ( NUO ) to formatting functions so that
* even when the user has overridden their default i8n settings ( e . g . in
* the control panel i8n page ) , we will still get the expected results .
2002-05-29 02:30:32 +02:00
*/
2003-11-22 01:00:53 +01:00
2020-03-02 07:30:35 +01:00
# define _CRT_NON_CONFORMING_WCSTOK
2003-11-22 01:00:53 +01:00
# include <assert.h>
# include <stdlib.h>
2003-09-06 01:08:26 +02:00
# include <stdarg.h>
2009-12-04 01:06:58 +01:00
# include <stdio.h>
2003-09-06 01:08:26 +02:00
2019-11-19 10:08:27 +01:00
# include "ntstatus.h"
# define WIN32_NO_STATUS
2002-05-29 02:30:32 +02:00
# include "wine/test.h"
2003-09-06 01:08:26 +02:00
# include "windef.h"
2002-05-29 02:30:32 +02:00
# include "winbase.h"
# include "winerror.h"
# include "winnls.h"
2019-11-19 10:08:27 +01:00
# include "winternl.h"
2021-03-08 17:34:40 +01:00
# include "winreg.h"
2002-05-29 02:30:32 +02:00
2012-06-04 22:53:55 +02:00
static const WCHAR upper_case [ ] = { ' \t ' , ' J ' , ' U ' , ' S ' , ' T ' , ' ! ' , ' ' , ' A ' , ' , ' , ' ' , ' T ' , ' E ' , ' S ' , ' T ' , ' ; ' , ' ' , ' S ' , ' T ' , ' R ' , ' I ' , ' N ' , ' G ' , ' ' , ' 1 ' , ' / ' , ' * ' , ' + ' , ' - ' , ' . ' , ' \r ' , ' \n ' , 0 } ;
static const WCHAR lower_case [ ] = { ' \t ' , ' j ' , ' u ' , ' s ' , ' t ' , ' ! ' , ' ' , ' a ' , ' , ' , ' ' , ' t ' , ' e ' , ' s ' , ' t ' , ' ; ' , ' ' , ' s ' , ' t ' , ' r ' , ' i ' , ' n ' , ' g ' , ' ' , ' 1 ' , ' / ' , ' * ' , ' + ' , ' - ' , ' . ' , ' \r ' , ' \n ' , 0 } ;
2016-09-22 17:06:12 +02:00
static const WCHAR title_case [ ] = { ' \t ' , ' J ' , ' u ' , ' s ' , ' t ' , ' ! ' , ' ' , ' A ' , ' , ' , ' ' , ' T ' , ' e ' , ' s ' , ' t ' , ' ; ' , ' ' , ' S ' , ' t ' , ' r ' , ' i ' , ' n ' , ' g ' , ' ' , ' 1 ' , ' / ' , ' * ' , ' + ' , ' - ' , ' . ' , ' \r ' , ' \n ' , 0 } ;
2012-06-04 22:53:55 +02:00
static const WCHAR symbols_stripped [ ] = { ' j ' , ' u ' , ' s ' , ' t ' , ' a ' , ' t ' , ' e ' , ' s ' , ' t ' , ' s ' , ' t ' , ' r ' , ' i ' , ' n ' , ' g ' , ' 1 ' , 0 } ;
2014-12-24 17:52:04 +01:00
static const WCHAR localeW [ ] = { ' e ' , ' n ' , ' - ' , ' U ' , ' S ' , 0 } ;
2012-06-04 22:53:55 +02:00
static const WCHAR fooW [ ] = { ' f ' , ' o ' , ' o ' , 0 } ;
2014-12-24 17:52:04 +01:00
static const WCHAR emptyW [ ] = { 0 } ;
2017-01-17 11:51:44 +01:00
static const WCHAR invalidW [ ] = { ' i ' , ' n ' , ' v ' , ' a ' , ' l ' , ' i ' , ' d ' , 0 } ;
2012-06-04 22:53:55 +02:00
2003-09-24 20:52:39 +02:00
/* Some functions are only in later versions of kernel32.dll */
2004-11-01 22:06:28 +01:00
static WORD enumCount ;
2003-09-24 20:52:39 +02:00
2014-12-24 17:52:04 +01:00
static INT ( WINAPI * pGetTimeFormatEx ) ( LPCWSTR , DWORD , const SYSTEMTIME * , LPCWSTR , LPWSTR , INT ) ;
static INT ( WINAPI * pGetDateFormatEx ) ( LPCWSTR , DWORD , const SYSTEMTIME * , LPCWSTR , LPWSTR , INT , LPCWSTR ) ;
2013-10-21 10:02:07 +02:00
static BOOL ( WINAPI * pEnumSystemLanguageGroupsA ) ( LANGUAGEGROUP_ENUMPROCA , DWORD , LONG_PTR ) ;
static BOOL ( WINAPI * pEnumLanguageGroupLocalesA ) ( LANGGROUPLOCALE_ENUMPROCA , LGRPID , DWORD , LONG_PTR ) ;
static BOOL ( WINAPI * pEnumUILanguagesA ) ( UILANGUAGE_ENUMPROCA , DWORD , LONG_PTR ) ;
2010-09-27 14:03:12 +02:00
static BOOL ( WINAPI * pEnumSystemLocalesEx ) ( LOCALE_ENUMPROCEX , DWORD , LPARAM , LPVOID ) ;
2012-06-04 22:53:55 +02:00
static INT ( WINAPI * pLCMapStringEx ) ( LPCWSTR , DWORD , LPCWSTR , INT , LPWSTR , INT , LPNLSVERSIONINFO , LPVOID , LPARAM ) ;
2012-03-18 19:28:41 +01:00
static LCID ( WINAPI * pLocaleNameToLCID ) ( LPCWSTR , DWORD ) ;
2019-11-19 10:08:27 +01:00
static NTSTATUS ( WINAPI * pRtlLocaleNameToLcid ) ( LPCWSTR , LCID * , DWORD ) ;
2012-03-18 19:28:41 +01:00
static INT ( WINAPI * pLCIDToLocaleName ) ( LCID , LPWSTR , INT , DWORD ) ;
2010-09-27 14:03:12 +02:00
static BOOL ( WINAPI * pIsValidLanguageGroup ) ( LGRPID , DWORD ) ;
2012-04-24 16:11:52 +02:00
static INT ( WINAPI * pIdnToNameprepUnicode ) ( DWORD , LPCWSTR , INT , LPWSTR , INT ) ;
2012-04-30 17:27:56 +02:00
static INT ( WINAPI * pIdnToAscii ) ( DWORD , LPCWSTR , INT , LPWSTR , INT ) ;
2012-04-30 17:28:20 +02:00
static INT ( WINAPI * pIdnToUnicode ) ( DWORD , LPCWSTR , INT , LPWSTR , INT ) ;
2012-07-26 09:20:46 +02:00
static INT ( WINAPI * pGetLocaleInfoEx ) ( LPCWSTR , LCTYPE , LPWSTR , INT ) ;
2012-07-27 05:00:24 +02:00
static BOOL ( WINAPI * pIsValidLocaleName ) ( LPCWSTR ) ;
2012-10-31 09:56:39 +01:00
static INT ( WINAPI * pCompareStringOrdinal ) ( const WCHAR * , INT , const WCHAR * , INT , BOOL ) ;
2014-04-16 21:54:58 +02:00
static INT ( WINAPI * pCompareStringEx ) ( LPCWSTR , DWORD , LPCWSTR , INT , LPCWSTR , INT ,
LPNLSVERSIONINFO , LPVOID , LPARAM ) ;
2014-07-11 04:36:18 +02:00
static INT ( WINAPI * pGetGeoInfoA ) ( GEOID , GEOTYPE , LPSTR , INT , LANGID ) ;
static INT ( WINAPI * pGetGeoInfoW ) ( GEOID , GEOTYPE , LPWSTR , INT , LANGID ) ;
2021-03-08 17:34:40 +01:00
static INT ( WINAPI * pGetUserDefaultGeoName ) ( LPWSTR , int ) ;
static BOOL ( WINAPI * pSetUserGeoName ) ( PWSTR ) ;
2014-07-15 03:51:32 +02:00
static BOOL ( WINAPI * pEnumSystemGeoID ) ( GEOCLASS , GEOID , GEO_ENUMPROC ) ;
2016-01-17 10:00:55 +01:00
static BOOL ( WINAPI * pGetSystemPreferredUILanguages ) ( DWORD , ULONG * , WCHAR * , ULONG * ) ;
2016-04-29 10:14:35 +02:00
static BOOL ( WINAPI * pGetThreadPreferredUILanguages ) ( DWORD , ULONG * , WCHAR * , ULONG * ) ;
2016-10-18 20:00:12 +02:00
static BOOL ( WINAPI * pGetUserPreferredUILanguages ) ( DWORD , ULONG * , WCHAR * , ULONG * ) ;
2016-06-14 10:08:46 +02:00
static WCHAR ( WINAPI * pRtlUpcaseUnicodeChar ) ( WCHAR ) ;
2016-08-15 19:54:20 +02:00
static INT ( WINAPI * pGetNumberFormatEx ) ( LPCWSTR , DWORD , LPCWSTR , const NUMBERFMTW * , LPWSTR , int ) ;
2018-03-13 15:09:45 +01:00
static INT ( WINAPI * pFindNLSStringEx ) ( LPCWSTR , DWORD , LPCWSTR , INT , LPCWSTR , INT , LPINT , LPNLSVERSIONINFO , LPVOID , LPARAM ) ;
2018-03-31 11:24:53 +02:00
static LANGID ( WINAPI * pSetThreadUILanguage ) ( LANGID ) ;
static LANGID ( WINAPI * pGetThreadUILanguage ) ( VOID ) ;
2018-04-09 20:38:00 +02:00
static INT ( WINAPI * pNormalizeString ) ( NORM_FORM , LPCWSTR , INT , LPWSTR , INT ) ;
2018-10-30 07:31:57 +01:00
static INT ( WINAPI * pFindStringOrdinal ) ( DWORD , LPCWSTR lpStringSource , INT , LPCWSTR , INT , BOOL ) ;
2020-03-20 12:54:36 +01:00
static BOOL ( WINAPI * pGetNLSVersion ) ( NLS_FUNCTION , LCID , NLSVERSIONINFO * ) ;
static BOOL ( WINAPI * pGetNLSVersionEx ) ( NLS_FUNCTION , LPCWSTR , NLSVERSIONINFOEX * ) ;
2020-03-20 14:43:45 +01:00
static DWORD ( WINAPI * pIsValidNLSVersion ) ( NLS_FUNCTION , LPCWSTR , NLSVERSIONINFOEX * ) ;
2019-11-21 10:43:46 +01:00
static NTSTATUS ( WINAPI * pRtlNormalizeString ) ( ULONG , LPCWSTR , INT , LPWSTR , INT * ) ;
static NTSTATUS ( WINAPI * pRtlIsNormalizedString ) ( ULONG , LPCWSTR , INT , BOOLEAN * ) ;
2019-11-26 17:56:04 +01:00
static NTSTATUS ( WINAPI * pNtGetNlsSectionPtr ) ( ULONG , ULONG , void * , void * * , SIZE_T * ) ;
static void ( WINAPI * pRtlInitCodePageTable ) ( USHORT * , CPTABLEINFO * ) ;
2019-12-06 17:17:52 +01:00
static NTSTATUS ( WINAPI * pRtlCustomCPToUnicodeN ) ( CPTABLEINFO * , WCHAR * , DWORD , DWORD * , const char * , DWORD ) ;
2020-05-22 12:42:14 +02:00
static NTSTATUS ( WINAPI * pRtlGetSystemPreferredUILanguages ) ( DWORD , ULONG , ULONG * , WCHAR * , ULONG * ) ;
static NTSTATUS ( WINAPI * pRtlGetThreadPreferredUILanguages ) ( DWORD , ULONG * , WCHAR * , ULONG * ) ;
static NTSTATUS ( WINAPI * pRtlGetUserPreferredUILanguages ) ( DWORD , ULONG , ULONG * , WCHAR * , ULONG * ) ;
2003-12-08 23:20:44 +01:00
2003-09-24 20:52:39 +02:00
static void InitFunctionPointers ( void )
{
2016-06-14 10:08:46 +02:00
HMODULE mod = GetModuleHandleA ( " kernel32 " ) ;
2014-07-11 04:36:18 +02:00
2016-06-14 10:08:46 +02:00
# define X(f) p##f = (void*)GetProcAddress(mod, #f)
2014-12-24 17:52:04 +01:00
X ( GetTimeFormatEx ) ;
X ( GetDateFormatEx ) ;
2014-07-11 04:36:18 +02:00
X ( EnumSystemLanguageGroupsA ) ;
X ( EnumLanguageGroupLocalesA ) ;
X ( LocaleNameToLCID ) ;
X ( LCIDToLocaleName ) ;
X ( LCMapStringEx ) ;
X ( IsValidLanguageGroup ) ;
X ( EnumUILanguagesA ) ;
X ( EnumSystemLocalesEx ) ;
X ( IdnToNameprepUnicode ) ;
X ( IdnToAscii ) ;
X ( IdnToUnicode ) ;
X ( GetLocaleInfoEx ) ;
X ( IsValidLocaleName ) ;
X ( CompareStringOrdinal ) ;
X ( CompareStringEx ) ;
X ( GetGeoInfoA ) ;
X ( GetGeoInfoW ) ;
2021-03-08 17:34:40 +01:00
X ( GetUserDefaultGeoName ) ;
X ( SetUserGeoName ) ;
2014-07-15 03:51:32 +02:00
X ( EnumSystemGeoID ) ;
2016-01-17 10:00:55 +01:00
X ( GetSystemPreferredUILanguages ) ;
2016-04-29 10:14:35 +02:00
X ( GetThreadPreferredUILanguages ) ;
2016-10-18 20:00:12 +02:00
X ( GetUserPreferredUILanguages ) ;
2016-08-15 19:54:20 +02:00
X ( GetNumberFormatEx ) ;
2018-03-13 15:09:45 +01:00
X ( FindNLSStringEx ) ;
2018-03-31 11:24:53 +02:00
X ( SetThreadUILanguage ) ;
X ( GetThreadUILanguage ) ;
2018-04-09 20:38:00 +02:00
X ( NormalizeString ) ;
2018-10-30 07:31:57 +01:00
X ( FindStringOrdinal ) ;
2020-03-20 12:54:36 +01:00
X ( GetNLSVersion ) ;
X ( GetNLSVersionEx ) ;
2020-03-20 14:43:45 +01:00
X ( IsValidNLSVersion ) ;
2016-06-14 10:08:46 +02:00
mod = GetModuleHandleA ( " ntdll " ) ;
X ( RtlUpcaseUnicodeChar ) ;
2019-11-19 10:08:27 +01:00
X ( RtlLocaleNameToLcid ) ;
2019-11-21 10:43:46 +01:00
X ( RtlNormalizeString ) ;
X ( RtlIsNormalizedString ) ;
2019-11-26 17:56:04 +01:00
X ( NtGetNlsSectionPtr ) ;
X ( RtlInitCodePageTable ) ;
2019-12-06 17:17:52 +01:00
X ( RtlCustomCPToUnicodeN ) ;
2020-05-22 12:42:14 +02:00
X ( RtlGetSystemPreferredUILanguages ) ;
X ( RtlGetThreadPreferredUILanguages ) ;
X ( RtlGetUserPreferredUILanguages ) ;
2014-07-11 04:36:18 +02:00
# undef X
2003-09-24 20:52:39 +02:00
}
2002-05-29 02:30:32 +02:00
# define eq(received, expected, label, type) \
2003-09-18 00:40:07 +02:00
ok ( ( received ) = = ( expected ) , " %s: got " type " instead of " type " \n " , \
( label ) , ( received ) , ( expected ) )
2002-05-29 02:30:32 +02:00
2003-09-18 00:40:07 +02:00
# define BUFFER_SIZE 128
2002-05-29 02:30:32 +02:00
2021-08-22 18:21:49 +02:00
# define expect_str(r,s,e) expect_str_(__LINE__, r, s, e)
static void expect_str_ ( int line , int ret , const char * str , const char * expected )
{
if ( ret )
{
ok_ ( __FILE__ , line ) ( GetLastError ( ) = = 0xdeadbeef , " unexpected gle %u \n " , GetLastError ( ) ) ;
ok_ ( __FILE__ , line ) ( ret = = strlen ( expected ) + 1 , " Expected ret %d, got %d \n " , strlen ( expected ) + 1 , ret ) ;
if ( str )
ok_ ( __FILE__ , line ) ( strcmp ( str , expected ) = = 0 , " Expected '%s', got '%s' \n " , expected , str ) ;
}
else
ok_ ( __FILE__ , line ) ( 0 , " expected success, got error %d \n " , GetLastError ( ) ) ;
}
# define expect_err(r,s,e) expect_err_(__LINE__, r, s, e, #e)
static void expect_err_ ( int line , int ret , const char * str , DWORD err , const char * err_name )
{
ok_ ( __FILE__ , line ) ( ! ret & & GetLastError ( ) = = err ,
" Expected %s, got %d and ret=%d \n " , err_name , GetLastError ( ) , ret ) ;
if ( str )
ok_ ( __FILE__ , line ) ( strcmp ( str , " pristine " ) = = 0 , " Expected a pristine buffer, got '%s' \n " , str ) ;
}
2021-08-24 10:14:57 +02:00
# define expect_wstr(r,s,e) expect_wstr_(__LINE__, r, s, e)
static void expect_wstr_ ( int line , int ret , const WCHAR * str , const WCHAR * expected )
{
if ( ret )
{
ok_ ( __FILE__ , line ) ( GetLastError ( ) = = 0xdeadbeef , " unexpected gle %u \n " , GetLastError ( ) ) ;
ok_ ( __FILE__ , line ) ( ret = = wcslen ( expected ) + 1 , " Expected ret %d, got %d \n " , wcslen ( expected ) + 1 , ret ) ;
if ( str )
ok_ ( __FILE__ , line ) ( wcscmp ( str , expected ) = = 0 , " Expected %s, got %s \n " , wine_dbgstr_w ( expected ) , wine_dbgstr_w ( str ) ) ;
}
else
ok_ ( __FILE__ , line ) ( 0 , " expected success, got error %d \n " , GetLastError ( ) ) ;
}
# define expect_werr(r,s,e) expect_werr_(__LINE__, r, s, e, #e)
static void expect_werr_ ( int line , int ret , const WCHAR * str , DWORD err , const char * err_name )
{
ok_ ( __FILE__ , line ) ( ! ret & & GetLastError ( ) = = err ,
" Expected %s, got %d and ret=%d \n " , err_name , GetLastError ( ) , ret ) ;
if ( str )
ok_ ( __FILE__ , line ) ( wcscmp ( str , L " pristine " ) = = 0 , " Expected a pristine buffer, got %s \n " , wine_dbgstr_w ( str ) ) ;
}
2003-09-18 00:40:07 +02:00
# define NUO LOCALE_NOUSEROVERRIDE
2005-06-20 16:18:03 +02:00
static void test_GetLocaleInfoA ( void )
2002-05-29 02:30:32 +02:00
{
2003-09-18 00:40:07 +02:00
int ret ;
2009-06-02 23:41:52 +02:00
int len ;
2003-09-18 00:40:07 +02:00
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
char buffer [ BUFFER_SIZE ] ;
2009-06-02 23:41:52 +02:00
char expected [ BUFFER_SIZE ] ;
2012-07-26 09:20:46 +02:00
DWORD val ;
2003-09-18 00:40:07 +02:00
2006-10-10 01:06:48 +02:00
ok ( lcid = = 0x409 , " wrong LCID calculated - %d \n " , lcid ) ;
2003-09-18 00:40:07 +02:00
2012-07-26 09:20:46 +02:00
ret = GetLocaleInfoA ( lcid , LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER , ( char * ) & val , sizeof ( val ) ) ;
ok ( ret , " got %d \n " , ret ) ;
ok ( val = = lcid , " got 0x%08x \n " , val ) ;
2009-09-01 12:19:35 +02:00
/* en and ar use SUBLANG_NEUTRAL, but GetLocaleInfo assume SUBLANG_DEFAULT
Same is true for zh on pre - Vista , but on Vista and higher GetLocaleInfo
assumes SUBLANG_NEUTRAL for zh */
2018-06-22 19:50:38 +02:00
memset ( expected , 0 , ARRAY_SIZE ( expected ) ) ;
len = GetLocaleInfoA ( MAKELANGID ( LANG_ENGLISH , SUBLANG_DEFAULT ) , LOCALE_SLANGUAGE , expected , ARRAY_SIZE ( expected ) ) ;
2009-06-01 23:12:30 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
memset ( buffer , 0 , ARRAY_SIZE ( buffer ) ) ;
ret = GetLocaleInfoA ( LANG_ENGLISH , LOCALE_SLANGUAGE , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-06-02 23:41:52 +02:00
ok ( ( ret = = len ) & & ! lstrcmpA ( buffer , expected ) ,
" got %d with '%s' (expected %d with '%s') \n " ,
ret , buffer , len , expected ) ;
2018-06-22 19:50:38 +02:00
memset ( expected , 0 , ARRAY_SIZE ( expected ) ) ;
len = GetLocaleInfoA ( MAKELANGID ( LANG_ARABIC , SUBLANG_DEFAULT ) , LOCALE_SLANGUAGE , expected , ARRAY_SIZE ( expected ) ) ;
2009-06-02 23:41:52 +02:00
if ( len ) {
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
memset ( buffer , 0 , ARRAY_SIZE ( buffer ) ) ;
ret = GetLocaleInfoA ( LANG_ARABIC , LOCALE_SLANGUAGE , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-06-02 23:41:52 +02:00
ok ( ( ret = = len ) & & ! lstrcmpA ( buffer , expected ) ,
" got %d with '%s' (expected %d with '%s') \n " ,
ret , buffer , len , expected ) ;
}
else
win_skip ( " LANG_ARABIC not installed \n " ) ;
/* SUBLANG_DEFAULT is required for mlang.dll, but optional for GetLocaleInfo */
2018-06-22 19:50:38 +02:00
memset ( expected , 0 , ARRAY_SIZE ( expected ) ) ;
len = GetLocaleInfoA ( MAKELANGID ( LANG_GERMAN , SUBLANG_DEFAULT ) , LOCALE_SLANGUAGE , expected , ARRAY_SIZE ( expected ) ) ;
2009-06-01 23:12:30 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
memset ( buffer , 0 , ARRAY_SIZE ( buffer ) ) ;
ret = GetLocaleInfoA ( LANG_GERMAN , LOCALE_SLANGUAGE , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-06-02 23:41:52 +02:00
ok ( ( ret = = len ) & & ! lstrcmpA ( buffer , expected ) ,
" got %d with '%s' (expected %d with '%s') \n " ,
ret , buffer , len , expected ) ;
2009-06-01 23:12:30 +02:00
2003-09-18 00:40:07 +02:00
/* HTMLKit and "Font xplorer lite" expect GetLocaleInfoA to
* partially fill the buffer even if it is too short . See bug 637.
*/
2009-06-01 23:12:30 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
memset ( buffer , 0 , ARRAY_SIZE ( buffer ) ) ;
2003-09-18 00:40:07 +02:00
ret = GetLocaleInfoA ( lcid , NUO | LOCALE_SDAYNAME1 , buffer , 0 ) ;
ok ( ret = = 7 & & ! buffer [ 0 ] , " Expected len=7, got %d \n " , ret ) ;
2009-06-01 23:12:30 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
memset ( buffer , 0 , ARRAY_SIZE ( buffer ) ) ;
2003-09-18 00:40:07 +02:00
ret = GetLocaleInfoA ( lcid , NUO | LOCALE_SDAYNAME1 , buffer , 3 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
2003-09-18 00:40:07 +02:00
ok ( ! strcmp ( buffer , " Mon " ) , " Expected 'Mon', got '%s' \n " , buffer ) ;
2009-06-01 23:12:30 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
memset ( buffer , 0 , ARRAY_SIZE ( buffer ) ) ;
2003-09-18 00:40:07 +02:00
ret = GetLocaleInfoA ( lcid , NUO | LOCALE_SDAYNAME1 , buffer , 10 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 7 , " Expected ret == 7, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-09-18 00:40:07 +02:00
ok ( ! strcmp ( buffer , " Monday " ) , " Expected 'Monday', got '%s' \n " , buffer ) ;
2002-05-29 02:30:32 +02:00
}
2012-07-26 09:20:46 +02:00
struct neutralsublang_name2_t {
WCHAR name [ 3 ] ;
2012-07-26 11:14:15 +02:00
WCHAR sname [ 15 ] ;
2012-07-26 09:20:46 +02:00
LCID lcid ;
LCID lcid_broken ;
2012-07-26 11:14:15 +02:00
WCHAR sname_broken [ 15 ] ;
2012-07-26 09:20:46 +02:00
} ;
static const struct neutralsublang_name2_t neutralsublang_names2 [ ] = {
2012-07-26 11:14:15 +02:00
{ { ' a ' , ' r ' , 0 } , { ' a ' , ' r ' , ' - ' , ' S ' , ' A ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_SAUDI_ARABIA ) , SORT_DEFAULT ) } ,
{ { ' a ' , ' z ' , 0 } , { ' a ' , ' z ' , ' - ' , ' L ' , ' a ' , ' t ' , ' n ' , ' - ' , ' A ' , ' Z ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_AZERI , SUBLANG_AZERI_LATIN ) , SORT_DEFAULT ) } ,
{ { ' d ' , ' e ' , 0 } , { ' d ' , ' e ' , ' - ' , ' D ' , ' E ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_GERMAN , SUBLANG_GERMAN ) , SORT_DEFAULT ) } ,
{ { ' e ' , ' n ' , 0 } , { ' e ' , ' n ' , ' - ' , ' U ' , ' S ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) } ,
{ { ' e ' , ' s ' , 0 } , { ' e ' , ' s ' , ' - ' , ' E ' , ' S ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_SPANISH , SUBLANG_SPANISH_MODERN ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_SPANISH , SUBLANG_SPANISH ) , SORT_DEFAULT ) /* vista */ ,
2017-01-24 21:43:53 +01:00
{ ' e ' , ' s ' , ' - ' , ' E ' , ' S ' , ' _ ' , ' t ' , ' r ' , ' a ' , ' d ' , ' n ' , ' l ' , 0 } } ,
2012-07-26 11:14:15 +02:00
{ { ' g ' , ' a ' , 0 } , { ' g ' , ' a ' , ' - ' , ' I ' , ' E ' , 0 } ,
2019-11-19 09:58:20 +01:00
MAKELCID ( MAKELANGID ( LANG_IRISH , SUBLANG_IRISH_IRELAND ) , SORT_DEFAULT ) , 0 , { 0 } } ,
2012-07-26 11:14:15 +02:00
{ { ' i ' , ' t ' , 0 } , { ' i ' , ' t ' , ' - ' , ' I ' , ' T ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_ITALIAN , SUBLANG_ITALIAN ) , SORT_DEFAULT ) } ,
{ { ' m ' , ' s ' , 0 } , { ' m ' , ' s ' , ' - ' , ' M ' , ' Y ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_MALAY , SUBLANG_MALAY_MALAYSIA ) , SORT_DEFAULT ) } ,
{ { ' n ' , ' l ' , 0 } , { ' n ' , ' l ' , ' - ' , ' N ' , ' L ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_DUTCH , SUBLANG_DUTCH ) , SORT_DEFAULT ) } ,
{ { ' p ' , ' t ' , 0 } , { ' p ' , ' t ' , ' - ' , ' B ' , ' R ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_PORTUGUESE , SUBLANG_PORTUGUESE_BRAZILIAN ) , SORT_DEFAULT ) } ,
{ { ' s ' , ' r ' , 0 } , { ' h ' , ' r ' , ' - ' , ' H ' , ' R ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_SERBIAN , SUBLANG_SERBIAN_CROATIA ) , SORT_DEFAULT ) } ,
{ { ' s ' , ' v ' , 0 } , { ' s ' , ' v ' , ' - ' , ' S ' , ' E ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_SWEDISH , SUBLANG_SWEDISH ) , SORT_DEFAULT ) } ,
{ { ' u ' , ' z ' , 0 } , { ' u ' , ' z ' , ' - ' , ' L ' , ' a ' , ' t ' , ' n ' , ' - ' , ' U ' , ' Z ' , 0 } ,
MAKELCID ( MAKELANGID ( LANG_UZBEK , SUBLANG_UZBEK_LATIN ) , SORT_DEFAULT ) } ,
{ { ' z ' , ' h ' , 0 } , { ' z ' , ' h ' , ' - ' , ' C ' , ' N ' , 0 } ,
2017-01-24 21:43:53 +01:00
MAKELCID ( MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_SIMPLIFIED ) , SORT_DEFAULT ) } ,
2012-07-26 09:20:46 +02:00
{ { 0 } }
} ;
2009-10-20 21:46:34 +02:00
static void test_GetLocaleInfoW ( void )
{
LCID lcid_en = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
LCID lcid_ru = MAKELCID ( MAKELANGID ( LANG_RUSSIAN , SUBLANG_NEUTRAL ) , SORT_DEFAULT ) ;
2012-07-26 09:20:46 +02:00
LCID lcid_en_neut = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_NEUTRAL ) , SORT_DEFAULT ) ;
2009-10-20 21:46:34 +02:00
WCHAR bufferW [ 80 ] , buffer2W [ 80 ] ;
CHAR bufferA [ 80 ] ;
2012-07-26 09:20:46 +02:00
DWORD val ;
2009-10-20 21:46:34 +02:00
DWORD ret ;
INT i ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid_en , LOCALE_SMONTHNAME1 , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2009-10-20 21:46:34 +02:00
if ( ! ret ) {
win_skip ( " GetLocaleInfoW() isn't implemented \n " ) ;
return ;
}
2012-07-26 09:20:46 +02:00
ret = GetLocaleInfoW ( lcid_en , LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER , ( WCHAR * ) & val , sizeof ( val ) / sizeof ( WCHAR ) ) ;
ok ( ret , " got %d \n " , ret ) ;
ok ( val = = lcid_en , " got 0x%08x \n " , val ) ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid_en_neut , LOCALE_SNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
if ( ret )
{
static const WCHAR slangW [ ] = { ' E ' , ' n ' , ' g ' , ' l ' , ' i ' , ' s ' , ' h ' , ' ' , ' ( ' , ' U ' , ' n ' , ' i ' , ' t ' , ' e ' , ' d ' , ' ' ,
' S ' , ' t ' , ' a ' , ' t ' , ' e ' , ' s ' , ' ) ' , 0 } ;
static const WCHAR statesW [ ] = { ' U ' , ' n ' , ' i ' , ' t ' , ' e ' , ' d ' , ' ' , ' S ' , ' t ' , ' a ' , ' t ' , ' e ' , ' s ' , 0 } ;
static const WCHAR enW [ ] = { ' e ' , ' n ' , ' - ' , ' U ' , ' S ' , 0 } ;
const struct neutralsublang_name2_t * ptr = neutralsublang_names2 ;
ok ( ! lstrcmpW ( bufferW , enW ) , " got wrong name %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid_en_neut , LOCALE_SCOUNTRY , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
ok ( ret , " got %d \n " , ret ) ;
2013-02-11 00:03:30 +01:00
if ( ( PRIMARYLANGID ( LANGIDFROMLCID ( GetSystemDefaultLCID ( ) ) ) ! = LANG_ENGLISH ) | |
( PRIMARYLANGID ( LANGIDFROMLCID ( GetThreadLocale ( ) ) ) ! = LANG_ENGLISH ) )
{
skip ( " Non-English locale \n " ) ;
}
else
ok ( ! lstrcmpW ( statesW , bufferW ) , " got wrong name %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid_en_neut , LOCALE_SLANGUAGE , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
ok ( ret , " got %d \n " , ret ) ;
2013-02-11 00:03:30 +01:00
if ( ( PRIMARYLANGID ( LANGIDFROMLCID ( GetSystemDefaultLCID ( ) ) ) ! = LANG_ENGLISH ) | |
( PRIMARYLANGID ( LANGIDFROMLCID ( GetThreadLocale ( ) ) ) ! = LANG_ENGLISH ) )
{
skip ( " Non-English locale \n " ) ;
}
else
ok ( ! lstrcmpW ( slangW , bufferW ) , " got wrong name %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
while ( * ptr - > name )
{
LANGID langid ;
2012-07-26 11:14:15 +02:00
LCID lcid ;
2012-07-26 09:20:46 +02:00
/* make neutral lcid */
langid = MAKELANGID ( PRIMARYLANGID ( LANGIDFROMLCID ( ptr - > lcid ) ) , SUBLANG_NEUTRAL ) ;
2012-07-26 11:14:15 +02:00
lcid = MAKELCID ( langid , SORT_DEFAULT ) ;
2012-07-26 09:20:46 +02:00
val = 0 ;
2012-07-26 11:14:15 +02:00
GetLocaleInfoW ( lcid , LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER , ( WCHAR * ) & val , sizeof ( val ) / sizeof ( WCHAR ) ) ;
2019-11-19 09:58:20 +01:00
ok ( val = = ptr - > lcid | | ( val & & broken ( val = = ptr - > lcid_broken ) ) , " %s: got wrong lcid 0x%04x, expected 0x%04x \n " ,
wine_dbgstr_w ( ptr - > name ) , val , ptr - > lcid ) ;
2012-07-26 11:14:15 +02:00
/* now check LOCALE_SNAME */
2018-06-22 19:50:38 +02:00
GetLocaleInfoW ( lcid , LOCALE_SNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2019-11-19 09:58:20 +01:00
ok ( ! lstrcmpW ( bufferW , ptr - > sname ) | |
( * ptr - > sname_broken & & broken ( ! lstrcmpW ( bufferW , ptr - > sname_broken ) ) ) ,
" %s: got %s \n " , wine_dbgstr_w ( ptr - > name ) , wine_dbgstr_w ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
ptr + + ;
}
}
else
win_skip ( " English neutral locale not supported \n " ) ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid_ru , LOCALE_SMONTHNAME1 , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2009-10-20 21:46:34 +02:00
if ( ! ret ) {
win_skip ( " LANG_RUSSIAN locale data unavailable \n " ) ;
return ;
}
ret = GetLocaleInfoW ( lcid_ru , LOCALE_SMONTHNAME1 | LOCALE_RETURN_GENITIVE_NAMES ,
2018-06-22 19:50:38 +02:00
bufferW , ARRAY_SIZE ( bufferW ) ) ;
2009-10-20 21:46:34 +02:00
if ( ! ret ) {
win_skip ( " LOCALE_RETURN_GENITIVE_NAMES isn't supported \n " ) ;
return ;
}
/* LOCALE_RETURN_GENITIVE_NAMES isn't supported for GetLocaleInfoA */
bufferA [ 0 ] = ' a ' ;
2009-10-21 03:34:59 +02:00
SetLastError ( 0xdeadbeef ) ;
2009-10-20 21:46:34 +02:00
ret = GetLocaleInfoA ( lcid_ru , LOCALE_SMONTHNAME1 | LOCALE_RETURN_GENITIVE_NAMES ,
2018-06-22 19:50:38 +02:00
bufferA , ARRAY_SIZE ( bufferA ) ) ;
2009-10-20 21:46:34 +02:00
ok ( ret = = 0 , " LOCALE_RETURN_GENITIVE_NAMES should fail with GetLocaleInfoA \n " ) ;
ok ( bufferA [ 0 ] = = ' a ' , " Expected buffer to be untouched \n " ) ;
2009-10-21 03:34:59 +02:00
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS ,
" Expected ERROR_INVALID_FLAGS, got %x \n " , GetLastError ( ) ) ;
2009-10-20 21:46:34 +02:00
bufferW [ 0 ] = ' a ' ;
2009-10-21 03:34:59 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid_ru , LOCALE_RETURN_GENITIVE_NAMES , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2009-10-20 21:46:34 +02:00
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 " ) ;
2009-10-21 03:34:59 +02:00
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS ,
" Expected ERROR_INVALID_FLAGS, got %x \n " , GetLastError ( ) ) ;
2009-10-20 21:46:34 +02:00
2009-10-21 03:34:59 +02:00
/* yes, test empty 13 month entry too */
2009-10-20 21:46:34 +02:00
for ( i = 0 ; i < 12 ; i + + ) {
bufferW [ 0 ] = 0 ;
ret = GetLocaleInfoW ( lcid_ru , ( LOCALE_SMONTHNAME1 + i ) | LOCALE_RETURN_GENITIVE_NAMES ,
2018-06-22 19:50:38 +02:00
bufferW , ARRAY_SIZE ( bufferW ) ) ;
2009-10-20 21:46:34 +02:00
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 ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid_ru , LOCALE_SMONTHNAME1 + i , buffer2W , ARRAY_SIZE ( buffer2W ) ) ;
2009-10-20 21:46:34 +02:00
ok ( ret , " Expected non zero result \n " ) ;
ok ( ret = = lstrlenW ( buffer2W ) + 1 , " Expected actual length, got %d, length %d \n " ,
ret , lstrlenW ( buffer2W ) ) ;
2009-10-21 03:34:59 +02:00
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 ,
2018-06-22 19:50:38 +02:00
bufferW , ARRAY_SIZE ( bufferW ) ) ;
2009-10-21 03:34:59 +02:00
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 ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid_en , LOCALE_SMONTHNAME1 + i , buffer2W , ARRAY_SIZE ( buffer2W ) ) ;
2009-10-21 03:34:59 +02:00
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 ) ;
2009-10-20 21:46:34 +02:00
}
}
2005-06-20 16:18:03 +02:00
static void test_GetTimeFormatA ( void )
2002-05-29 02:30:32 +02:00
{
2003-09-18 00:40:07 +02:00
int ret ;
2002-12-19 22:12:09 +01:00
SYSTEMTIME curtime ;
2003-09-18 00:40:07 +02:00
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
2021-08-22 18:21:49 +02:00
char buffer [ BUFFER_SIZE ] ;
SetLastError ( 0xdeadbeef ) ;
2002-12-19 22:12:09 +01:00
2021-08-22 18:21:49 +02:00
/* Invalid time */
2002-12-19 22:12:09 +01:00
memset ( & curtime , 2 , sizeof ( SYSTEMTIME ) ) ;
2021-08-22 18:21:49 +02:00
strcpy ( buffer , " pristine " ) ;
ret = GetTimeFormatA ( lcid , TIME_FORCE24HOURFORMAT , & curtime , " tt HH':'mm'@'ss " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* Valid time */
2003-09-18 00:40:07 +02:00
curtime . wHour = 8 ;
curtime . wMinute = 56 ;
curtime . wSecond = 13 ;
curtime . wMilliseconds = 22 ;
2021-08-22 18:21:49 +02:00
ret = GetTimeFormatA ( lcid , TIME_FORCE24HOURFORMAT , & curtime , " tt HH':'mm'@'ss " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " AM 08:56@13 " ) ;
2003-09-18 00:40:07 +02:00
2007-01-05 07:25:39 +01:00
/* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
2021-08-22 18:21:49 +02:00
strcpy ( buffer , " pristine " ) ;
ret = GetTimeFormatA ( lcid , NUO | TIME_FORCE24HOURFORMAT , & curtime , " HH " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_FLAGS ) ;
2007-01-05 07:25:39 +01:00
SetLastError ( 0xdeadbeef ) ;
2021-08-22 18:21:49 +02:00
/* Insufficient buffer */
ret = GetTimeFormatA ( lcid , TIME_FORCE24HOURFORMAT , & curtime , " HH " , buffer , 2 ) ;
/* The content of the buffer depends on implementation details:
* it may be " ristine " or " 0ristine " or unchanged and cannot be relied on .
*/
expect_err ( ret , NULL , ERROR_INSUFFICIENT_BUFFER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* Calculate length only */
ret = GetTimeFormatA ( lcid , TIME_FORCE24HOURFORMAT , & curtime , " tt HH':'mm'@'ss " , NULL , 0 ) ;
expect_str ( ret , NULL , " AM 08:56@13 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* TIME_NOMINUTESORSECONDS, default format */
2018-06-22 19:50:38 +02:00
ret = GetTimeFormatA ( lcid , NUO | TIME_NOMINUTESORSECONDS , & curtime , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
2021-08-22 18:21:49 +02:00
expect_str ( ret , buffer , " 8 AM " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* TIME_NOMINUTESORSECONDS/complex format */
ret = GetTimeFormatA ( lcid , TIME_NOMINUTESORSECONDS , & curtime , " m1s2m3s4 " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* TIME_NOSECONDS/Default format */
2018-06-22 19:50:38 +02:00
ret = GetTimeFormatA ( lcid , NUO | TIME_NOSECONDS , & curtime , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
2021-08-22 18:21:49 +02:00
expect_str ( ret , buffer , " 8:56 AM " ) ;
/* TIME_NOSECONDS */
strcpy ( buffer , " pristine " ) ; /* clear previous identical result */
ret = GetTimeFormatA ( lcid , TIME_NOSECONDS , & curtime , " h:m:s tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 8:56 AM " ) ;
/* Multiple delimiters */
ret = GetTimeFormatA ( lcid , TIME_NOSECONDS , & curtime , " h.@:m.@:s.@:tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 8.@:56AM " ) ;
2002-12-19 22:12:09 +01:00
2021-08-22 18:21:49 +02:00
/* Duplicate tokens */
ret = GetTimeFormatA ( lcid , TIME_NOSECONDS , & curtime , " s1s2s3 " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " " ) ;
/* AM time marker */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " t/tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " A/AM " ) ;
/* PM time marker */
2002-12-19 22:12:09 +01:00
curtime . wHour = 13 ;
2021-08-22 18:21:49 +02:00
ret = GetTimeFormatA ( lcid , 0 , & curtime , " t/tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " P/PM " ) ;
/* TIME_NOTIMEMARKER: removes text around time marker token */
ret = GetTimeFormatA ( lcid , TIME_NOTIMEMARKER , & curtime , " h1t2tt3m " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 156 " ) ;
/* TIME_FORCE24HOURFORMAT */
ret = GetTimeFormatA ( lcid , TIME_FORCE24HOURFORMAT , & curtime , " h:m:s tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 13:56:13 PM " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* TIME_FORCE24HOURFORMAT doesn't add time marker */
ret = GetTimeFormatA ( lcid , TIME_FORCE24HOURFORMAT , & curtime , " h:m:s " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 13:56:13 " ) ;
/* 24 hrs, leading 0 */
2002-12-19 22:12:09 +01:00
curtime . wHour = 14 ; /* change this to 14 or 2pm */
curtime . wMinute = 5 ;
curtime . wSecond = 3 ;
2021-08-22 18:21:49 +02:00
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h hh H HH m mm s ss t tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 2 02 14 14 5 05 3 03 P PM " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* "hh" and "HH" */
2002-12-19 22:12:09 +01:00
curtime . wHour = 0 ;
2021-08-22 18:21:49 +02:00
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h/H/hh/HH " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 12/0/12/00 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* non-zero flags should fail with format, doesn't */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h:m:s tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 12:5:3 AM " ) ;
2003-09-18 00:40:07 +02:00
/* try to convert formatting strings with more than two letters
* " h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS "
* NOTE : We expect any letter for which there is an upper case value
* we should see a replacement . For letters that DO NOT have
* upper case values we should see NO REPLACEMENT .
*/
curtime . wHour = 8 ;
curtime . wMinute = 56 ;
curtime . wSecond = 13 ;
curtime . wMilliseconds = 22 ;
2021-08-22 18:21:49 +02:00
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS " ) ;
/* Don't write to buffer if len is 0 */
strcpy ( buffer , " pristine " ) ;
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h:mm " , buffer , 0 ) ;
expect_str ( ret , NULL , " 8:56 " ) ;
ok ( strcmp ( buffer , " pristine " ) = = 0 , " Expected a pristine buffer, got '%s' \n " , buffer ) ;
/* "'" preserves tokens */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt' " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 8 h 8 H 08 HH 56 m 13 s A t AM tt " ) ;
/* invalid quoted string */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " ''' " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " ' " ) ;
/* check that MSDN's suggested single quotation usage works as expected */
strcpy ( buffer , " pristine " ) ; /* clear previous identical result */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " '''' " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " ' " ) ;
/* Normal use */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " ''HHHHHH " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 08 " ) ;
2002-12-19 22:12:09 +01:00
/* and test for normal use of the single quotation mark */
2021-08-22 18:21:49 +02:00
ret = GetTimeFormatA ( lcid , 0 , & curtime , " '''HHHHHH' " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 'HHHHHH " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* Odd use */
strcpy ( buffer , " pristine " ) ; /* clear previous identical result */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " '''HHHHHH " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 'HHHHHH " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* TIME_NOTIMEMARKER drops literals too */
ret = GetTimeFormatA ( lcid , TIME_NOTIMEMARKER , & curtime , " '123'tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " " ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* Invalid time */
2002-12-19 22:12:09 +01:00
curtime . wHour = 25 ;
2021-08-22 18:21:49 +02:00
strcpy ( buffer , " pristine " ) ;
ret = GetTimeFormatA ( lcid , 0 , & curtime , " '123'tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-22 18:21:49 +02:00
/* Invalid date */
2003-09-18 00:40:07 +02:00
curtime . wHour = 12 ;
2021-08-22 18:21:49 +02:00
curtime . wMonth = 60 ;
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h:m:s " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 12:56:13 " ) ;
2021-08-26 18:26:26 +02:00
/* The ANSI string may be longer than the Unicode one.
* In particular , in the Japanese code page , " \x93 \xfa " = L " \x65e5 " .
*/
lcid = MAKELCID ( MAKELANGID ( LANG_JAPANESE , SUBLANG_JAPANESE_JAPAN ) , SORT_DEFAULT ) ;
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h \x93 \xfa " , buffer , 5 ) ;
expect_str ( ret , buffer , " 12 \x93 \xfa " ) ; /* only 3+1 WCHARs */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h \x93 \xfa " , buffer , 4 ) ;
2021-08-26 18:26:36 +02:00
expect_err ( ret , NULL , ERROR_INSUFFICIENT_BUFFER ) ;
2021-08-26 18:26:26 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h \x93 \xfa " , NULL , 0 ) ;
expect_str ( ret , NULL , " 12 \x93 \xfa " ) ;
strcpy ( buffer , " pristine " ) ; /* clear previous identical result */
ret = GetTimeFormatA ( lcid , 0 , & curtime , " h \x93 \xfa " , buffer , 0 ) ;
expect_str ( ret , NULL , " 12 \x93 \xfa " ) ;
ok ( strcmp ( buffer , " pristine " ) = = 0 , " Expected a pristine buffer, got '%s' \n " , buffer ) ;
2002-05-29 02:30:32 +02:00
}
2014-12-24 17:52:04 +01:00
static void test_GetTimeFormatEx ( void )
{
int ret ;
SYSTEMTIME curtime ;
2021-08-24 10:14:57 +02:00
WCHAR buffer [ BUFFER_SIZE ] ;
2014-12-24 17:52:04 +01:00
if ( ! pGetTimeFormatEx )
{
win_skip ( " GetTimeFormatEx not supported \n " ) ;
return ;
}
2021-08-24 10:14:57 +02:00
SetLastError ( 0xdeadbeef ) ;
/* Invalid time */
2014-12-24 17:52:04 +01:00
memset ( & curtime , 2 , sizeof ( SYSTEMTIME ) ) ;
2021-08-24 10:14:57 +02:00
wcscpy ( buffer , L " pristine " ) ;
ret = pGetTimeFormatEx ( localeW , TIME_FORCE24HOURFORMAT , & curtime , L " tt HH':'mm'@'ss " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2014-12-24 17:52:04 +01:00
SetLastError ( 0xdeadbeef ) ;
2021-08-24 10:14:57 +02:00
/* Valid time */
2014-12-24 17:52:04 +01:00
curtime . wHour = 8 ;
curtime . wMinute = 56 ;
curtime . wSecond = 13 ;
curtime . wMilliseconds = 22 ;
2021-08-24 10:14:57 +02:00
ret = pGetTimeFormatEx ( localeW , TIME_FORCE24HOURFORMAT , & curtime , L " tt HH':'mm'@'ss " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " AM 08:56@13 " ) ;
2014-12-24 17:52:04 +01:00
/* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
2021-08-24 10:14:57 +02:00
wcscpy ( buffer , L " pristine " ) ;
ret = pGetTimeFormatEx ( localeW , NUO | TIME_FORCE24HOURFORMAT , & curtime , L " HH " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_FLAGS ) ;
2014-12-24 17:52:04 +01:00
SetLastError ( 0xdeadbeef ) ;
2021-08-24 10:14:57 +02:00
/* Insufficient buffer */
ret = pGetTimeFormatEx ( localeW , TIME_FORCE24HOURFORMAT , & curtime , L " tt " , buffer , 2 ) ;
/* there is no guarantee on the buffer content, see GetTimeFormatA() */
expect_werr ( ret , NULL , ERROR_INSUFFICIENT_BUFFER ) ;
2014-12-24 17:52:04 +01:00
SetLastError ( 0xdeadbeef ) ;
2021-08-24 10:14:57 +02:00
/* Calculate length only */
ret = pGetTimeFormatEx ( localeW , TIME_FORCE24HOURFORMAT , & curtime , L " tt HH':'mm'@'ss " , NULL , 0 ) ;
expect_wstr ( ret , NULL , L " AM 08:56@13 " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* TIME_NOMINUTESORSECONDS, default format */
2018-06-22 19:50:38 +02:00
ret = pGetTimeFormatEx ( localeW , NUO | TIME_NOMINUTESORSECONDS , & curtime , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
2021-08-24 10:14:57 +02:00
expect_wstr ( ret , buffer , L " 8 AM " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* TIME_NOMINUTESORSECONDS/complex format */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetTimeFormatEx ( localeW , TIME_NOMINUTESORSECONDS , & curtime , L " m1s2m3s4 " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* TIME_NOSECONDS/Default format */
2018-06-22 19:50:38 +02:00
ret = pGetTimeFormatEx ( localeW , NUO | TIME_NOSECONDS , & curtime , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
2021-08-24 10:14:57 +02:00
expect_wstr ( ret , buffer , L " 8:56 AM " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* TIME_NOSECONDS */
wcscpy ( buffer , L " pristine " ) ; /* clear previous identical result */
ret = pGetTimeFormatEx ( localeW , TIME_NOSECONDS , & curtime , L " h:m:s tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 8:56 AM " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* Multiple delimiters */
ret = pGetTimeFormatEx ( localeW , TIME_NOSECONDS , & curtime , L " h.@:m.@:s.@:tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 8.@:56AM " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* Duplicate tokens */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetTimeFormatEx ( localeW , TIME_NOSECONDS , & curtime , L " s1s2s3 " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* AM time marker */
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " t/tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " A/AM " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* PM time marker */
2014-12-24 17:52:04 +01:00
curtime . wHour = 13 ;
2021-08-24 10:14:57 +02:00
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " t/tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " P/PM " ) ;
/* TIME_NOTIMEMARKER: removes text around time marker token */
ret = pGetTimeFormatEx ( localeW , TIME_NOTIMEMARKER , & curtime , L " h1t2tt3m " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 156 " ) ;
/* TIME_FORCE24HOURFORMAT */
ret = pGetTimeFormatEx ( localeW , TIME_FORCE24HOURFORMAT , & curtime , L " h:m:s tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 13:56:13 PM " ) ;
/* TIME_FORCE24HOURFORMAT doesn't add time marker */
ret = pGetTimeFormatEx ( localeW , TIME_FORCE24HOURFORMAT , & curtime , L " h:m:s " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 13:56:13 " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* 24 hrs, leading 0 */
2014-12-24 17:52:04 +01:00
curtime . wHour = 14 ; /* change this to 14 or 2pm */
curtime . wMinute = 5 ;
curtime . wSecond = 3 ;
2021-08-24 10:14:57 +02:00
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " h hh H HH m mm s ss t tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 2 02 14 14 5 05 3 03 P PM " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* "hh" and "HH" */
2014-12-24 17:52:04 +01:00
curtime . wHour = 0 ;
2021-08-24 10:14:57 +02:00
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " h/H/hh/HH " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 12/0/12/00 " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* non-zero flags should fail with format, doesn't */
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " h:m:s tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 12:5:3 AM " ) ;
2014-12-24 17:52:04 +01:00
/* try to convert formatting strings with more than two letters
* " h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS "
* NOTE : We expect any letter for which there is an upper case value
* we should see a replacement . For letters that DO NOT have
* upper case values we should see NO REPLACEMENT .
*/
curtime . wHour = 8 ;
curtime . wMinute = 56 ;
curtime . wSecond = 13 ;
curtime . wMilliseconds = 22 ;
2021-08-24 10:14:57 +02:00
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS " ) ;
/* Don't write to buffer if len is 0 */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " h:mm " , buffer , 0 ) ;
expect_wstr ( ret , NULL , L " 8:56 " ) ;
ok ( wcscmp ( buffer , L " pristine " ) = = 0 , " Expected a pristine buffer, got %s \n " , wine_dbgstr_w ( buffer ) ) ;
/* "'" preserves tokens */
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt' " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 8 h 8 H 08 HH 56 m 13 s A t AM tt " ) ;
/* invalid quoted string */
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " ''' " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " ' " ) ;
/* check that MSDN's suggested single quotation usage works as expected */
wcscpy ( buffer , L " pristine " ) ; /* clear previous identical result */
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " '''' " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " ' " ) ;
/* Normal use */
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " ''HHHHHH " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 08 " ) ;
2014-12-24 17:52:04 +01:00
/* and test for normal use of the single quotation mark */
2021-08-24 10:14:57 +02:00
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " '''HHHHHH' " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 'HHHHHH " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* Odd use */
wcscpy ( buffer , L " pristine " ) ; /* clear previous identical result */
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " '''HHHHHH " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 'HHHHHH " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* TIME_NOTIMEMARKER drops literals too */
ret = pGetTimeFormatEx ( localeW , TIME_NOTIMEMARKER , & curtime , L " '123'tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " " ) ;
2014-12-24 17:52:04 +01:00
2021-08-24 10:14:57 +02:00
/* Invalid time */
2014-12-24 17:52:04 +01:00
curtime . wHour = 25 ;
2021-08-24 10:14:57 +02:00
wcscpy ( buffer , L " pristine " ) ;
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " '123'tt " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2014-12-24 17:52:04 +01:00
SetLastError ( 0xdeadbeef ) ;
2021-08-24 10:14:57 +02:00
/* Invalid date */
2014-12-24 17:52:04 +01:00
curtime . wHour = 12 ;
2021-08-24 10:14:57 +02:00
curtime . wMonth = 60 ;
ret = pGetTimeFormatEx ( localeW , 0 , & curtime , L " h:m:s " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 12:56:13 " ) ;
2014-12-24 17:52:04 +01:00
}
2005-06-20 16:18:03 +02:00
static void test_GetDateFormatA ( void )
2002-05-29 02:30:32 +02:00
{
2003-09-18 00:40:07 +02:00
int ret ;
2002-12-19 22:12:09 +01:00
SYSTEMTIME curtime ;
2003-09-18 00:40:07 +02:00
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
2009-12-04 01:06:58 +01:00
LCID lcid_ru = MAKELCID ( MAKELANGID ( LANG_RUSSIAN , SUBLANG_NEUTRAL ) , SORT_DEFAULT ) ;
2021-08-26 18:26:29 +02:00
LCID lcid_ja = MAKELCID ( MAKELANGID ( LANG_JAPANESE , SUBLANG_JAPANESE_JAPAN ) , SORT_DEFAULT ) ;
2021-08-24 10:14:25 +02:00
char buffer [ BUFFER_SIZE ] , Expected [ BUFFER_SIZE ] ;
2009-12-04 01:06:58 +01:00
char short_day [ 10 ] , month [ 10 ] , genitive_month [ 10 ] ;
2002-12-19 22:12:09 +01:00
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2002-12-19 22:12:09 +01:00
2021-08-24 10:14:25 +02:00
/* Invalid time */
memset ( & curtime , 2 , sizeof ( SYSTEMTIME ) ) ;
strcpy ( buffer , " pristine " ) ;
ret = GetDateFormatA ( lcid , 0 , & curtime , " ddd',' MMM dd yy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
/* Simple case */
2003-01-16 01:18:34 +01:00
curtime . wYear = 2002 ;
curtime . wMonth = 5 ;
curtime . wDay = 4 ;
curtime . wDayOfWeek = 3 ;
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid , 0 , & curtime , " ddd',' MMM dd yy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " Sat, May 04 02 " ) ;
2003-09-18 00:40:07 +02:00
2007-01-05 07:25:39 +01:00
/* Same as above but with LOCALE_NOUSEROVERRIDE */
2021-08-24 10:14:25 +02:00
strcpy ( buffer , " pristine " ) ;
ret = GetDateFormatA ( lcid , NUO , & curtime , " ddd',' MMM dd yy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_FLAGS ) ;
2007-01-05 07:25:39 +01:00
SetLastError ( 0xdeadbeef ) ;
2021-08-24 10:14:25 +02:00
/* Format containing "'" */
ret = GetDateFormatA ( lcid , 0 , & curtime , " ddd',' MMM dd yy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " Sat, May 04 02 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:25 +02:00
/* Invalid time */
curtime . wHour = 36 ;
ret = GetDateFormatA ( lcid , 0 , & curtime , " ddd',' MMM dd ''''yy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " Sat, May 04 '02 " ) ;
2002-12-19 22:12:09 +01:00
2021-08-24 10:14:25 +02:00
/* Get size only */
ret = GetDateFormatA ( lcid , 0 , & curtime , " ddd',' MMM dd ''''yy " , NULL , 0 ) ;
expect_str ( ret , NULL , " Sat, May 04 '02 " ) ;
2002-12-19 22:12:09 +01:00
2021-08-24 10:14:25 +02:00
/* Buffer too small */
strcpy ( buffer , " pristine " ) ;
ret = GetDateFormatA ( lcid , 0 , & curtime , " ddd " , buffer , 2 ) ;
/* there is no guarantee on the buffer content, see GetTimeFormatA() */
expect_err ( ret , NULL , ERROR_INSUFFICIENT_BUFFER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:25 +02:00
/* Default to DATE_SHORTDATE */
2018-06-22 19:50:38 +02:00
ret = GetDateFormatA ( lcid , NUO , & curtime , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , " 5/4/2002 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:25 +02:00
/* DATE_LONGDATE */
2018-06-22 19:50:38 +02:00
ret = GetDateFormatA ( lcid , NUO | DATE_LONGDATE , & curtime , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
2008-11-20 21:39:48 +01:00
ok ( ret , " Expected ret != 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2013-11-01 10:21:15 +01:00
ok ( strcmp ( buffer , " Saturday, May 04, 2002 " ) = = 0 | |
strcmp ( buffer , " Saturday, May 4, 2002 " ) = = 0 /* Win 8 */ ,
" got an unexpected date string '%s' \n " , buffer ) ;
2002-12-19 22:12:09 +01:00
/* test for expected DATE_YEARMONTH behavior with null format */
/* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */
2021-08-24 10:14:25 +02:00
strcpy ( buffer , " pristine " ) ;
ret = GetDateFormatA ( lcid , NUO | DATE_YEARMONTH , & curtime , " ddd',' MMM dd ''''yy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_FLAGS ) ;
2007-01-05 07:25:39 +01:00
SetLastError ( 0xdeadbeef ) ;
2002-12-19 22:12:09 +01:00
/* Test that using invalid DATE_* flags results in the correct error */
/* and return values */
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid , DATE_YEARMONTH | DATE_SHORTDATE | DATE_LONGDATE , & curtime , " m/d/y " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , NULL , ERROR_INVALID_FLAGS ) ;
2007-01-05 07:25:39 +01:00
SetLastError ( 0xdeadbeef ) ;
2009-12-04 01:06:58 +01:00
2018-06-22 19:50:38 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " ddMMMM " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
if ( ! ret )
{
win_skip ( " LANG_RUSSIAN locale data unavailable \n " ) ;
return ;
}
/* month part should be in genitive form */
strcpy ( genitive_month , buffer + 2 ) ;
2018-06-22 19:50:38 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " MMMM " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
ok ( ret , " Expected ret != 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
strcpy ( month , buffer ) ;
ok ( strcmp ( genitive_month , month ) ! = 0 , " Expected different month forms \n " ) ;
2018-06-22 19:50:38 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " ddd " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
ok ( ret , " Expected ret != 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
strcpy ( short_day , buffer ) ;
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " dd MMMMddd dd " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
sprintf ( Expected , " 04 %s%s 04 " , genitive_month , short_day ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , Expected ) ;
2009-12-04 01:06:58 +01:00
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " MMMMddd dd " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
sprintf ( Expected , " %s%s 04 " , month , short_day ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , Expected ) ;
2009-12-04 01:06:58 +01:00
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " MMMMddd " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
sprintf ( Expected , " %s%s " , month , short_day ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , Expected ) ;
2009-12-04 01:06:58 +01:00
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " MMMMdd " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
sprintf ( Expected , " %s04 " , genitive_month ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , Expected ) ;
2009-12-04 01:06:58 +01:00
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " MMMMdd ddd " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
sprintf ( Expected , " %s04 %s " , genitive_month , short_day ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , Expected ) ;
2009-12-04 01:06:58 +01:00
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " dd dddMMMM " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
sprintf ( Expected , " 04 %s%s " , short_day , month ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , Expected ) ;
2009-12-04 01:06:58 +01:00
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " dd dddMMMM ddd MMMMdd " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
sprintf ( Expected , " 04 %s%s %s %s04 " , short_day , month , short_day , genitive_month ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , Expected ) ;
2009-12-04 01:06:58 +01:00
/* with literal part */
2021-08-24 10:14:25 +02:00
ret = GetDateFormatA ( lcid_ru , 0 , & curtime , " ddd',' MMMM dd " , buffer , ARRAY_SIZE ( buffer ) ) ;
2009-12-04 01:06:58 +01:00
sprintf ( Expected , " %s, %s 04 " , short_day , genitive_month ) ;
2021-08-24 10:14:25 +02:00
expect_str ( ret , buffer , Expected ) ;
2021-08-26 18:26:29 +02:00
/* The ANSI string may be longer than the Unicode one.
* In particular , in the Japanese code page , " \x93 \xfa " = L " \x65e5 " .
* See the corresponding GetDateFormatW ( ) test .
*/
ret = GetDateFormatA ( lcid_ja , 0 , & curtime , " d \x93 \xfa " , buffer , 4 ) ;
expect_str ( ret , buffer , " 4 \x93 \xfa " ) ; /* only 2+1 WCHARs */
ret = GetDateFormatA ( lcid_ja , 0 , & curtime , " d \x93 \xfa " , buffer , 3 ) ;
2021-08-26 18:26:36 +02:00
expect_err ( ret , NULL , ERROR_INSUFFICIENT_BUFFER ) ;
2021-08-26 18:26:29 +02:00
SetLastError ( 0xdeadbeef ) ;
strcpy ( buffer , " pristine " ) ; /* clear previous identical result */
ret = GetDateFormatA ( lcid_ja , 0 , & curtime , " d \x93 \xfa " , NULL , 0 ) ;
expect_str ( ret , NULL , " 4 \x93 \xfa " ) ;
2002-05-29 02:30:32 +02:00
}
2014-12-24 17:52:04 +01:00
static void test_GetDateFormatEx ( void )
{
int ret ;
SYSTEMTIME curtime ;
2021-08-25 15:35:06 +02:00
WCHAR buffer [ BUFFER_SIZE ] ;
2014-12-24 17:52:04 +01:00
if ( ! pGetDateFormatEx )
{
win_skip ( " GetDateFormatEx not supported \n " ) ;
return ;
}
SetLastError ( 0xdeadbeef ) ;
2021-08-25 15:35:01 +02:00
/* If flags are set, then format must be NULL */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetDateFormatEx ( localeW , DATE_LONGDATE , NULL , L " " , buffer , ARRAY_SIZE ( buffer ) , NULL ) ;
expect_werr ( ret , buffer , ERROR_INVALID_FLAGS ) ;
2014-12-24 17:52:04 +01:00
SetLastError ( 0xdeadbeef ) ;
2021-08-25 15:35:01 +02:00
/* NULL buffer, len > 0 */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetDateFormatEx ( localeW , 0 , NULL , L " " , NULL , ARRAY_SIZE ( buffer ) , NULL ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2014-12-24 17:52:04 +01:00
SetLastError ( 0xdeadbeef ) ;
2021-08-25 15:35:01 +02:00
/* NULL buffer, len == 0 */
ret = pGetDateFormatEx ( localeW , 0 , NULL , L " " , NULL , 0 , NULL ) ;
expect_wstr ( ret , NULL , L " " ) ;
/* Invalid flag combination */
wcscpy ( buffer , L " pristine " ) ;
2014-12-24 17:52:04 +01:00
ret = pGetDateFormatEx ( localeW , DATE_LONGDATE | DATE_SHORTDATE , NULL ,
2021-08-25 15:35:01 +02:00
L " " , NULL , 0 , NULL ) ;
expect_werr ( ret , buffer , ERROR_INVALID_FLAGS ) ;
SetLastError ( 0xdeadbeef ) ;
2014-12-24 17:52:04 +01:00
2021-08-25 15:35:01 +02:00
/* Incorrect DOW and time */
2014-12-24 17:52:04 +01:00
curtime . wYear = 2002 ;
curtime . wMonth = 10 ;
curtime . wDay = 23 ;
curtime . wDayOfWeek = 45612 ; /* Should be 3 - Wednesday */
curtime . wHour = 65432 ; /* Invalid */
curtime . wMinute = 34512 ; /* Invalid */
curtime . wSecond = 65535 ; /* Invalid */
curtime . wMilliseconds = 12345 ;
2021-08-25 15:35:01 +02:00
ret = pGetDateFormatEx ( localeW , 0 , & curtime , L " dddd d MMMM yyyy " , buffer , ARRAY_SIZE ( buffer ) , NULL ) ;
expect_wstr ( ret , buffer , L " Wednesday 23 October 2002 " ) ;
2014-12-24 17:52:04 +01:00
curtime . wYear = 2002 ;
curtime . wMonth = 10 ;
curtime . wDay = 23 ;
curtime . wDayOfWeek = 45612 ; /* Should be 3 - Wednesday */
curtime . wHour = 65432 ; /* Invalid */
curtime . wMinute = 34512 ; /* Invalid */
curtime . wSecond = 65535 ; /* Invalid */
curtime . wMilliseconds = 12345 ;
2021-08-25 15:35:01 +02:00
wcscpy ( buffer , L " pristine " ) ;
ret = pGetDateFormatEx ( localeW , 0 , & curtime , L " dddd d MMMM yyyy " , buffer , ARRAY_SIZE ( buffer ) , emptyW ) ; /* Use reserved arg */
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
2014-12-24 17:52:04 +01:00
/* Limit tests */
curtime . wYear = 1601 ;
curtime . wMonth = 1 ;
curtime . wDay = 1 ;
curtime . wDayOfWeek = 0 ; /* Irrelevant */
curtime . wHour = 0 ;
curtime . wMinute = 0 ;
curtime . wSecond = 0 ;
curtime . wMilliseconds = 0 ;
2021-08-25 15:35:01 +02:00
ret = pGetDateFormatEx ( localeW , 0 , & curtime , L " dddd d MMMM yyyy " , buffer , ARRAY_SIZE ( buffer ) , NULL ) ;
expect_wstr ( ret , buffer , L " Monday 1 January 1601 " ) ;
2014-12-24 17:52:04 +01:00
curtime . wYear = 1600 ;
curtime . wMonth = 12 ;
curtime . wDay = 31 ;
curtime . wDayOfWeek = 0 ; /* Irrelevant */
curtime . wHour = 23 ;
curtime . wMinute = 59 ;
curtime . wSecond = 59 ;
curtime . wMilliseconds = 999 ;
2021-08-25 15:35:01 +02:00
wcscpy ( buffer , L " pristine " ) ;
ret = pGetDateFormatEx ( localeW , 0 , & curtime , L " dddd d MMMM yyyy " , buffer , ARRAY_SIZE ( buffer ) , NULL ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2014-12-24 17:52:04 +01:00
}
2005-06-20 16:18:03 +02:00
static void test_GetDateFormatW ( void )
2002-10-25 21:02:26 +02:00
{
2003-09-18 00:40:07 +02:00
int ret ;
SYSTEMTIME curtime ;
2021-08-25 15:35:04 +02:00
WCHAR buffer [ BUFFER_SIZE ] ;
2003-09-18 00:40:07 +02:00
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
2002-10-25 21:02:26 +02:00
2021-08-25 15:35:04 +02:00
SetLastError ( 0xdeadbeef ) ;
/* If flags is not zero then format must be NULL */
wcscpy ( buffer , L " pristine " ) ;
ret = GetDateFormatW ( LOCALE_SYSTEM_DEFAULT , DATE_LONGDATE , NULL , L " " , buffer , ARRAY_SIZE ( buffer ) ) ;
2003-09-18 00:40:07 +02:00
if ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
2009-05-18 11:24:37 +02:00
{
win_skip ( " GetDateFormatW is not implemented \n " ) ;
return ;
}
2021-08-25 15:35:04 +02:00
expect_werr ( ret , buffer , ERROR_INVALID_FLAGS ) ;
SetLastError ( 0xdeadbeef ) ;
2002-10-25 21:02:26 +02:00
2021-08-25 15:35:04 +02:00
/* NULL buffer, len > 0 */
wcscpy ( buffer , L " pristine " ) ;
ret = GetDateFormatW ( lcid , 0 , NULL , L " " , NULL , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2002-10-25 21:02:26 +02:00
2021-08-25 15:35:04 +02:00
/* NULL buffer, len == 0 */
ret = GetDateFormatW ( lcid , 0 , NULL , L " " , NULL , 0 ) ;
expect_wstr ( ret , NULL , L " " ) ;
2003-09-18 00:40:07 +02:00
2021-08-25 15:35:04 +02:00
/* Incorrect DOW and time */
2003-09-18 00:40:07 +02:00
curtime . wYear = 2002 ;
curtime . wMonth = 10 ;
curtime . wDay = 23 ;
curtime . wDayOfWeek = 45612 ; /* Should be 3 - Wednesday */
curtime . wHour = 65432 ; /* Invalid */
curtime . wMinute = 34512 ; /* Invalid */
curtime . wSecond = 65535 ; /* Invalid */
curtime . wMilliseconds = 12345 ;
2021-08-25 15:35:04 +02:00
ret = GetDateFormatW ( lcid , 0 , & curtime , L " dddd d MMMM yyyy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " Wednesday 23 October 2002 " ) ;
2007-05-04 01:11:08 +02:00
/* Limit tests */
curtime . wYear = 1601 ;
curtime . wMonth = 1 ;
curtime . wDay = 1 ;
curtime . wDayOfWeek = 0 ; /* Irrelevant */
curtime . wHour = 0 ;
curtime . wMinute = 0 ;
curtime . wSecond = 0 ;
curtime . wMilliseconds = 0 ;
2021-08-25 15:35:04 +02:00
ret = GetDateFormatW ( lcid , 0 , & curtime , L " dddd d MMMM yyyy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " Monday 1 January 1601 " ) ;
2007-05-04 01:11:08 +02:00
curtime . wYear = 1600 ;
curtime . wMonth = 12 ;
curtime . wDay = 31 ;
curtime . wDayOfWeek = 0 ; /* Irrelevant */
curtime . wHour = 23 ;
curtime . wMinute = 59 ;
curtime . wSecond = 59 ;
curtime . wMilliseconds = 999 ;
2021-08-25 15:35:04 +02:00
wcscpy ( buffer , L " pristine " ) ;
ret = GetDateFormatW ( lcid , 0 , & curtime , L " dddd d MMMM yyyy " , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2021-08-26 18:26:29 +02:00
SetLastError ( 0xdeadbeef ) ;
/* See the corresponding GetDateFormatA() test */
lcid = MAKELCID ( MAKELANGID ( LANG_JAPANESE , SUBLANG_JAPANESE_JAPAN ) , SORT_DEFAULT ) ;
curtime . wYear = 2002 ;
curtime . wMonth = 5 ;
curtime . wDay = 4 ;
ret = GetDateFormatW ( lcid , 0 , & curtime , L " d \x65e5 " , buffer , 3 ) ;
expect_wstr ( ret , buffer , L " 4 \x65e5 " ) ;
ret = GetDateFormatW ( lcid , 0 , & curtime , L " d \x65e5 " , NULL , 0 ) ;
expect_wstr ( ret , NULL , L " 4 \x65e5 " ) ;
2002-10-25 21:02:26 +02:00
}
2002-05-29 02:30:32 +02:00
2003-09-18 00:40:07 +02:00
# define CY_POS_LEFT 0
# define CY_POS_RIGHT 1
# define CY_POS_LEFT_SPACE 2
# define CY_POS_RIGHT_SPACE 3
2002-05-29 02:30:32 +02:00
2005-06-20 16:18:03 +02:00
static void test_GetCurrencyFormatA ( void )
2003-09-18 00:40:07 +02:00
{
static char szDot [ ] = { ' . ' , ' \0 ' } ;
static char szComma [ ] = { ' , ' , ' \0 ' } ;
static char szDollar [ ] = { ' $ ' , ' \0 ' } ;
2021-08-24 10:13:47 +02:00
static const char * const negative_order [ ] =
{ " ($1.0) " , /* 0 */
" -$1.0 " ,
" $-1.0 " ,
" $1.0- " ,
" (1.0$) " ,
" -1.0$ " , /* 5 */
" 1.0-$ " ,
" 1.0$- " ,
" -1.0 $ " ,
" -$ 1.0 " ,
" 1.0 $- " , /* 10 */
" $ 1.0- " ,
" $ -1.0 " ,
" 1.0- $ " ,
" ($ 1.0) " ,
" (1.0 $) " , /* 15 */
} ;
int ret , o ;
2003-09-18 00:40:07 +02:00
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
2021-08-24 10:13:47 +02:00
char buffer [ BUFFER_SIZE ] ;
2003-09-18 00:40:07 +02:00
CURRENCYFMTA format ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* NULL output, length > 0 --> Error */
ret = GetCurrencyFormatA ( lcid , 0 , " 23 " , NULL , NULL , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , NULL , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Invalid character --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetCurrencyFormatA ( lcid , 0 , " 23,53 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Double '-' --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetCurrencyFormatA ( lcid , 0 , " -- " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Trailing '-' --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetCurrencyFormatA ( lcid , 0 , " 0- " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Double '.' --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetCurrencyFormatA ( lcid , 0 , " 0.. " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Leading space --> Error */
ret = GetCurrencyFormatA ( lcid , 0 , " 0.1 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Length too small --> Write up to length chars */
strcpy ( buffer , " pristine " ) ;
ret = GetCurrencyFormatA ( lcid , NUO , " 1234 " , NULL , buffer , 2 ) ;
/* there is no guarantee on the buffer content, see GetTimeFormatA() */
expect_err ( ret , NULL , ERROR_INSUFFICIENT_BUFFER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Valid number */
ret = GetCurrencyFormatA ( lcid , NUO , " 2353 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $2,353.00 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Valid negative number */
ret = GetCurrencyFormatA ( lcid , NUO , " -2353 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " ($2,353.00) " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Valid real number */
ret = GetCurrencyFormatA ( lcid , NUO , " 2353.1 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $2,353.10 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Too many DP --> Truncated */
ret = GetCurrencyFormatA ( lcid , NUO , " 2353.111 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $2,353.11 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Too many DP --> Rounded */
ret = GetCurrencyFormatA ( lcid , NUO , " 2353.119 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $2,353.12 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Format and flags given --> Error */
memset ( & format , 0 , sizeof ( format ) ) ;
strcpy ( buffer , " pristine " ) ;
ret = GetCurrencyFormatA ( lcid , NUO , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_FLAGS ) ;
SetLastError ( 0xdeadbeef ) ;
/* Invalid format --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetCurrencyFormatA ( lcid , 0 , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2003-09-29 22:20:53 +02:00
format . NumDigits = 0 ; /* No decimal separator */
2003-09-18 00:40:07 +02:00
format . LeadingZero = 0 ;
format . Grouping = 0 ; /* No grouping char */
format . NegativeOrder = 0 ;
format . PositiveOrder = CY_POS_LEFT ;
format . lpDecimalSep = szDot ;
format . lpThousandSep = szComma ;
format . lpCurrencySymbol = szDollar ;
2021-08-24 10:13:47 +02:00
/* No decimal or grouping chars expected */
ret = GetCurrencyFormatA ( lcid , 0 , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $2353 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* 1 DP --> Expect decimal separator */
format . NumDigits = 1 ;
ret = GetCurrencyFormatA ( lcid , 0 , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $2353.0 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Group by 100's */
format . Grouping = 2 ;
ret = GetCurrencyFormatA ( lcid , 0 , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $23,53.0 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
/* Grouping of a positive number */
2009-11-09 10:41:54 +01:00
format . Grouping = 3 ;
2021-08-24 10:13:47 +02:00
ret = GetCurrencyFormatA ( lcid , 0 , " 235 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $235.0 " ) ;
2009-11-09 10:41:54 +01:00
2021-08-24 10:13:47 +02:00
/* Grouping of a negative number */
2009-11-09 10:41:54 +01:00
format . NegativeOrder = 2 ;
2021-08-24 10:13:47 +02:00
ret = GetCurrencyFormatA ( lcid , 0 , " -235 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $-235.0 " ) ;
2009-11-09 10:41:54 +01:00
2021-08-24 10:13:47 +02:00
/* Always provide leading zero */
format . LeadingZero = 1 ;
ret = GetCurrencyFormatA ( lcid , 0 , " .5 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $0.5 " ) ;
2003-09-18 00:40:07 +02:00
format . PositiveOrder = CY_POS_RIGHT ;
2021-08-24 10:13:47 +02:00
ret = GetCurrencyFormatA ( lcid , 0 , " 1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 1.0$ " ) ;
2003-09-18 00:40:07 +02:00
format . PositiveOrder = CY_POS_LEFT_SPACE ;
2021-08-24 10:13:47 +02:00
ret = GetCurrencyFormatA ( lcid , 0 , " 1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " $ 1.0 " ) ;
2003-09-18 00:40:07 +02:00
format . PositiveOrder = CY_POS_RIGHT_SPACE ;
2021-08-24 10:13:47 +02:00
ret = GetCurrencyFormatA ( lcid , 0 , " 1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 1.0 $ " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:13:47 +02:00
for ( o = 0 ; o < = 15 ; o + + )
{
winetest_push_context ( " %d " , o ) ;
format . NegativeOrder = o ;
strcpy ( buffer , " pristine " ) ;
ret = GetCurrencyFormatA ( lcid , 0 , " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , negative_order [ o ] ) ;
winetest_pop_context ( ) ;
}
2002-05-29 02:30:32 +02:00
}
2003-09-18 00:40:07 +02:00
# define NEG_PARENS 0 /* "(1.1)" */
# define NEG_LEFT 1 /* "-1.1" */
# define NEG_LEFT_SPACE 2 /* "- 1.1" */
# define NEG_RIGHT 3 /* "1.1-" */
# define NEG_RIGHT_SPACE 4 /* "1.1 -" */
2002-05-29 02:30:32 +02:00
2005-06-20 16:18:03 +02:00
static void test_GetNumberFormatA ( void )
2002-05-29 02:30:32 +02:00
{
2003-09-18 00:40:07 +02:00
static char szDot [ ] = { ' . ' , ' \0 ' } ;
static char szComma [ ] = { ' , ' , ' \0 ' } ;
int ret ;
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
2021-08-24 10:14:14 +02:00
char buffer [ BUFFER_SIZE ] ;
2003-09-18 00:40:07 +02:00
NUMBERFMTA format ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* NULL output, length > 0 --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetNumberFormatA ( lcid , 0 , " 23 " , NULL , NULL , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Invalid character --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetNumberFormatA ( lcid , 0 , " 23,53 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Double '-' --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetNumberFormatA ( lcid , 0 , " -- " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Trailing '-' --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetNumberFormatA ( lcid , 0 , " 0- " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Double '.' --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetNumberFormatA ( lcid , 0 , " 0.. " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Leading space --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetNumberFormatA ( lcid , 0 , " 0.1 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Length too small --> Write up to length chars */
ret = GetNumberFormatA ( lcid , NUO , " 1234 " , NULL , buffer , 2 ) ;
/* there is no guarantee on the buffer content, see GetTimeFormatA() */
expect_err ( ret , NULL , ERROR_INSUFFICIENT_BUFFER ) ;
2006-12-31 14:11:50 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Valid number */
ret = GetNumberFormatA ( lcid , NUO , " 2353 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 2,353.00 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Valid negative number */
ret = GetNumberFormatA ( lcid , NUO , " -2353 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " -2,353.00 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* test for off by one error in grouping */
ret = GetNumberFormatA ( lcid , NUO , " -353 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " -353.00 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Valid real number */
ret = GetNumberFormatA ( lcid , NUO , " 2353.1 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 2,353.10 " ) ;
2004-02-07 02:28:45 +01:00
2021-08-24 10:14:14 +02:00
/* Too many DP --> Truncated */
ret = GetNumberFormatA ( lcid , NUO , " 2353.111 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 2,353.11 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Too many DP --> Rounded */
ret = GetNumberFormatA ( lcid , NUO , " 2353.119 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 2,353.12 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Format and flags given --> Error */
memset ( & format , 0 , sizeof ( format ) ) ;
strcpy ( buffer , " pristine " ) ;
ret = GetNumberFormatA ( lcid , NUO , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_FLAGS ) ;
SetLastError ( 0xdeadbeef ) ;
/* Invalid format --> Error */
strcpy ( buffer , " pristine " ) ;
ret = GetNumberFormatA ( lcid , 0 , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_err ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
2003-09-18 00:40:07 +02:00
2003-09-29 22:20:53 +02:00
format . NumDigits = 0 ; /* No decimal separator */
2003-09-18 00:40:07 +02:00
format . LeadingZero = 0 ;
format . Grouping = 0 ; /* No grouping char */
format . NegativeOrder = 0 ;
format . lpDecimalSep = szDot ;
format . lpThousandSep = szComma ;
2021-08-24 10:14:14 +02:00
/* No decimal or grouping chars expected */
ret = GetNumberFormatA ( lcid , 0 , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 2353 " ) ;
2003-09-18 00:40:07 +02:00
2003-09-29 22:20:53 +02:00
format . NumDigits = 1 ; /* 1 DP --> Expect decimal separator */
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 2353.0 " ) ;
2003-09-18 00:40:07 +02:00
format . Grouping = 2 ; /* Group by 100's */
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 23,53.0 " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Grouping of a positive number */
2009-11-09 10:41:54 +01:00
format . Grouping = 3 ;
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " 235 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 235.0 " ) ;
2009-11-09 10:41:54 +01:00
2021-08-24 10:14:14 +02:00
/* Grouping of a negative number */
2009-11-09 10:41:54 +01:00
format . NegativeOrder = NEG_LEFT ;
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " -235 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " -235.0 " ) ;
2009-11-09 10:41:54 +01:00
2003-09-18 00:40:07 +02:00
format . LeadingZero = 1 ; /* Always provide leading zero */
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " .5 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 0.5 " ) ;
2003-09-18 00:40:07 +02:00
format . NegativeOrder = NEG_PARENS ;
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " (1.0) " ) ;
2003-09-18 00:40:07 +02:00
format . NegativeOrder = NEG_LEFT ;
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " -1.0 " ) ;
2003-09-18 00:40:07 +02:00
format . NegativeOrder = NEG_LEFT_SPACE ;
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " - 1.0 " ) ;
2003-09-18 00:40:07 +02:00
format . NegativeOrder = NEG_RIGHT ;
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 1.0- " ) ;
2003-09-18 00:40:07 +02:00
format . NegativeOrder = NEG_RIGHT_SPACE ;
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , 0 , " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " 1.0 - " ) ;
2003-09-18 00:40:07 +02:00
2021-08-24 10:14:14 +02:00
/* Test French formatting */
2003-09-18 00:40:07 +02:00
lcid = MAKELCID ( MAKELANGID ( LANG_FRENCH , SUBLANG_DEFAULT ) , SORT_DEFAULT ) ;
if ( IsValidLocale ( lcid , 0 ) )
{
2021-08-24 10:14:14 +02:00
ret = GetNumberFormatA ( lcid , NUO , " -12345 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_str ( ret , buffer , " -12 \xa0 \x33 \x34 \x35 ,00 " ) ; /* Non breaking space */
2003-09-18 00:40:07 +02:00
}
2002-05-29 02:30:32 +02:00
}
2016-08-15 19:54:20 +02:00
static void test_GetNumberFormatEx ( void )
{
int ret ;
NUMBERFMTW format ;
static WCHAR dotW [ ] = { ' . ' , 0 } ;
static WCHAR commaW [ ] = { ' , ' , 0 } ;
static const WCHAR enW [ ] = { ' e ' , ' n ' , ' - ' , ' U ' , ' S ' , 0 } ;
static const WCHAR frW [ ] = { ' f ' , ' r ' , ' - ' , ' F ' , ' R ' , 0 } ;
static const WCHAR bogusW [ ] = { ' b ' , ' o ' , ' g ' , ' u ' , ' s ' , 0 } ;
2021-08-25 15:35:06 +02:00
WCHAR buffer [ BUFFER_SIZE ] ;
2016-08-15 19:54:20 +02:00
if ( ! pGetNumberFormatEx )
{
win_skip ( " GetNumberFormatEx is not available. \n " ) ;
return ;
}
2021-08-25 15:35:06 +02:00
SetLastError ( 0xdeadbeef ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* NULL output, length > 0 --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , 0 , L " 23 " , NULL , NULL , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
/* Invalid character --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , 0 , L " 23,53 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
/* Double '-' --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , 0 , L " -- " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
/* Trailing '-' --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , 0 , L " 0- " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
/* Double '.' --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , 0 , L " 0.. " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
/* Leading space --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , 0 , L " 0.1 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
/* Length too small --> Write up to length chars */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , NUO , L " 1234 " , NULL , buffer , 2 ) ;
/* there is no guarantee on the buffer content, see GetTimeFormatA() */
expect_werr ( ret , NULL , ERROR_INSUFFICIENT_BUFFER ) ;
SetLastError ( 0xdeadbeef ) ;
/* Bogus locale --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( bogusW , NUO , L " 23 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
2016-08-15 19:54:20 +02:00
memset ( & format , 0 , sizeof ( format ) ) ;
2021-08-25 15:35:06 +02:00
/* Format and flags given --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , NUO , L " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_FLAGS ) ;
SetLastError ( 0xdeadbeef ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Invalid format --> Error */
wcscpy ( buffer , L " pristine " ) ;
ret = pGetNumberFormatEx ( enW , 0 , L " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_werr ( ret , buffer , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Valid number */
ret = pGetNumberFormatEx ( enW , NUO , L " 2353 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 2,353.00 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Valid negative number */
ret = pGetNumberFormatEx ( enW , NUO , L " -2353 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " -2,353.00 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* test for off by one error in grouping */
ret = pGetNumberFormatEx ( enW , NUO , L " -353 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " -353.00 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Valid real number */
ret = pGetNumberFormatEx ( enW , NUO , L " 2353.1 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 2,353.10 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Too many DP --> Truncated */
ret = pGetNumberFormatEx ( enW , NUO , L " 2353.111 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 2,353.11 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Too many DP --> Rounded */
ret = pGetNumberFormatEx ( enW , NUO , L " 2353.119 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 2,353.12 " ) ;
2016-08-15 19:54:20 +02:00
format . NumDigits = 0 ; /* No decimal separator */
format . LeadingZero = 0 ;
format . Grouping = 0 ; /* No grouping char */
format . NegativeOrder = 0 ;
format . lpDecimalSep = dotW ;
format . lpThousandSep = commaW ;
2021-08-25 15:35:06 +02:00
/* No decimal or grouping chars expected */
ret = pGetNumberFormatEx ( enW , 0 , L " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 2353 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* 1 DP --> Expect decimal separator */
format . NumDigits = 1 ;
ret = pGetNumberFormatEx ( enW , 0 , L " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 2353.0 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Group by 100's */
format . Grouping = 2 ;
ret = pGetNumberFormatEx ( enW , 0 , L " 2353 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 23,53.0 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Grouping of a positive number */
2016-08-15 19:54:20 +02:00
format . Grouping = 3 ;
2021-08-25 15:35:06 +02:00
ret = pGetNumberFormatEx ( enW , 0 , L " 235 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 235.0 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Grouping of a negative number */
2016-08-15 19:54:20 +02:00
format . NegativeOrder = NEG_LEFT ;
2021-08-25 15:35:06 +02:00
ret = pGetNumberFormatEx ( enW , 0 , L " -235 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " -235.0 " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Always provide leading zero */
format . LeadingZero = 1 ;
ret = pGetNumberFormatEx ( enW , 0 , L " .5 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 0.5 " ) ;
2016-08-15 19:54:20 +02:00
format . NegativeOrder = NEG_PARENS ;
2021-08-25 15:35:06 +02:00
ret = pGetNumberFormatEx ( enW , 0 , L " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " (1.0) " ) ;
2016-08-15 19:54:20 +02:00
format . NegativeOrder = NEG_LEFT ;
2021-08-25 15:35:06 +02:00
ret = pGetNumberFormatEx ( enW , 0 , L " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " -1.0 " ) ;
2016-08-15 19:54:20 +02:00
format . NegativeOrder = NEG_LEFT_SPACE ;
2021-08-25 15:35:06 +02:00
ret = pGetNumberFormatEx ( enW , 0 , L " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " - 1.0 " ) ;
2016-08-15 19:54:20 +02:00
format . NegativeOrder = NEG_RIGHT ;
2021-08-25 15:35:06 +02:00
ret = pGetNumberFormatEx ( enW , 0 , L " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 1.0- " ) ;
2016-08-15 19:54:20 +02:00
format . NegativeOrder = NEG_RIGHT_SPACE ;
2021-08-25 15:35:06 +02:00
ret = pGetNumberFormatEx ( enW , 0 , L " -1 " , & format , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " 1.0 - " ) ;
2016-08-15 19:54:20 +02:00
2021-08-25 15:35:06 +02:00
/* Test French formatting */
2016-08-15 19:54:20 +02:00
if ( pIsValidLocaleName ( frW ) )
{
2021-08-25 15:35:06 +02:00
ret = pGetNumberFormatEx ( frW , NUO , L " -12345 " , NULL , buffer , ARRAY_SIZE ( buffer ) ) ;
expect_wstr ( ret , buffer , L " -12 \xa0 \x33 \x34 \x35 ,00 " ) ; /* Non breaking space */
2016-08-15 19:54:20 +02:00
}
}
2011-10-01 23:40:59 +02:00
struct comparestringa_entry {
LCID lcid ;
DWORD flags ;
const char * first ;
int first_len ;
const char * second ;
int second_len ;
int ret ;
2021-03-20 17:58:43 +01:00
DWORD le ;
2011-10-01 23:40:59 +02:00
} ;
static const struct comparestringa_entry comparestringa_data [ ] = {
{ LOCALE_SYSTEM_DEFAULT , 0 , " EndDialog " , - 1 , " _Property " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " osp_vba.sreg0070 " , - 1 , " _IEWWBrowserComp " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " r " , - 1 , " \\ " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " osp_vba.sreg0031 " , - 1 , " OriginalDatabase " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " AAA " , - 1 , " aaa " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " AAA " , - 1 , " aab " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " AAA " , - 1 , " Aab " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " .AAA " , - 1 , " Aab " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " .AAA " , - 1 , " A.ab " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " aa " , - 1 , " AB " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " aa " , - 1 , " Aab " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " aB " , - 1 , " Aab " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " Ba " , - 1 , " bab " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " {100}{83}{71}{71}{71} " , - 1 , " Global_DataAccess_JRO " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a " , - 1 , " { " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " A " , - 1 , " { " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " 3.5 " , 0 , " 4.0 " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " 3.5 " , - 1 , " 4.0 " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " 3.520.4403.2 " , - 1 , " 4.0.2927.10 " , - 1 , CSTR_LESS_THAN } ,
/* hyphen and apostrophe are treated differently depending on whether SORT_STRINGSORT specified or not */
{ LOCALE_SYSTEM_DEFAULT , 0 , " -o " , - 1 , " /m " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " /m " , - 1 , " -o " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " -o " , - 1 , " /m " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " /m " , - 1 , " -o " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " 'o " , - 1 , " /m " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " /m " , - 1 , " 'o " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " 'o " , - 1 , " /m " , - 1 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " /m " , - 1 , " 'o " , - 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " aLuZkUtZ " , 8 , " aLuZkUtZ " , 9 , CSTR_EQUAL } ,
2016-02-12 08:53:04 +01:00
{ LOCALE_SYSTEM_DEFAULT , 0 , " aLuZkUtZ " , 7 , " aLuZkUtZ \0 A " , 10 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a- " , 3 , " a \0 " , 3 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a' " , 3 , " a \0 " , 3 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " a- " , 3 , " a \0 " , 3 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " a' " , 3 , " a \0 " , 3 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , NORM_IGNORESYMBOLS , " a. " , 3 , " a \0 " , 3 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , NORM_IGNORESYMBOLS , " a " , 3 , " a \0 " , 3 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a " , 1 , " a \0 \0 " , 4 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a " , 2 , " a \0 \0 " , 4 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a \0 \0 " , 4 , " a " , 1 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a \0 \0 " , 4 , " a " , 2 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a " , 1 , " a \0 x " , 4 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a " , 2 , " a \0 x " , 4 , CSTR_LESS_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a \0 x " , 4 , " a " , 1 , CSTR_GREATER_THAN } ,
{ LOCALE_SYSTEM_DEFAULT , 0 , " a \0 x " , 4 , " a " , 2 , CSTR_GREATER_THAN } ,
2021-03-20 17:58:43 +01:00
/* flag tests */
{ LOCALE_SYSTEM_DEFAULT , LOCALE_USE_CP_ACP , " NULL " , - 1 , " NULL " , - 1 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , LINGUISTIC_IGNORECASE , " NULL " , - 1 , " NULL " , - 1 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , LINGUISTIC_IGNOREDIACRITIC , " NULL " , - 1 , " NULL " , - 1 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , NORM_IGNOREKANATYPE , " NULL " , - 1 , " NULL " , - 1 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , NORM_IGNORENONSPACE , " NULL " , - 1 , " NULL " , - 1 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , NORM_IGNOREWIDTH , " NULL " , - 1 , " NULL " , - 1 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , NORM_LINGUISTIC_CASING , " NULL " , - 1 , " NULL " , - 1 , CSTR_EQUAL } ,
{ LOCALE_SYSTEM_DEFAULT , SORT_DIGITSASNUMBERS , " NULL " , - 1 , " NULL " , - 1 , 0 , ERROR_INVALID_FLAGS }
2011-10-01 23:40:59 +02:00
} ;
2002-05-29 02:30:32 +02:00
2005-06-20 16:18:03 +02:00
static void test_CompareStringA ( void )
2002-05-29 02:30:32 +02:00
{
2018-08-11 03:21:07 +02:00
static const char ABC_EE [ ] = { ' A ' , ' B ' , ' C ' , 0 , 0xEE } ;
static const char ABC_FF [ ] = { ' A ' , ' B ' , ' C ' , 0 , 0xFF } ;
2011-10-01 23:40:59 +02:00
int ret , i ;
2013-06-11 15:35:19 +02:00
char a [ 256 ] ;
2003-09-18 00:40:07 +02:00
LCID lcid = MAKELCID ( MAKELANGID ( LANG_FRENCH , SUBLANG_DEFAULT ) , SORT_DEFAULT ) ;
2002-05-29 02:30:32 +02:00
2018-06-22 19:50:38 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( comparestringa_data ) ; i + + )
2011-10-01 23:40:59 +02:00
{
const struct comparestringa_entry * entry = & comparestringa_data [ i ] ;
2021-03-20 17:58:43 +01:00
SetLastError ( 0xdeadbeef ) ;
2011-10-01 23:40:59 +02:00
ret = CompareStringA ( entry - > lcid , entry - > flags , entry - > first , entry - > first_len ,
entry - > second , entry - > second_len ) ;
ok ( ret = = entry - > ret , " %d: got %d, expected %d \n " , i , ret , entry - > ret ) ;
2021-03-20 17:58:43 +01:00
ok ( GetLastError ( ) = = ( ret ? 0xdeadbeef : entry - > le ) , " %d: got last error %d, expected %d \n " ,
i , GetLastError ( ) , ( ret ? 0xdeadbeef : entry - > le ) ) ;
2011-10-01 23:40:59 +02:00
}
2003-09-18 00:40:07 +02:00
ret = CompareStringA ( lcid , NORM_IGNORECASE , " Salut " , - 1 , " Salute " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " (Salut/Salute) Expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2002-05-29 02:30:32 +02:00
2003-09-18 00:40:07 +02:00
ret = CompareStringA ( lcid , NORM_IGNORECASE , " Salut " , - 1 , " SaLuT " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_EQUAL , " (Salut/SaLuT) Expected CSTR_EQUAL, got %d \n " , ret ) ;
2002-05-29 02:30:32 +02:00
2003-09-18 00:40:07 +02:00
ret = CompareStringA ( lcid , NORM_IGNORECASE , " Salut " , - 1 , " hola " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_GREATER_THAN , " (Salut/hola) Expected CSTR_GREATER_THAN, got %d \n " , ret ) ;
2002-05-29 02:30:32 +02:00
2003-09-18 00:40:07 +02:00
ret = CompareStringA ( lcid , NORM_IGNORECASE , " haha " , - 1 , " hoho " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " (haha/hoho) Expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2002-05-29 02:30:32 +02:00
2003-09-18 00:40:07 +02:00
lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
2002-05-29 02:30:32 +02:00
2003-09-18 00:40:07 +02:00
ret = CompareStringA ( lcid , NORM_IGNORECASE , " haha " , - 1 , " hoho " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " (haha/hoho) Expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2002-06-01 01:06:46 +02:00
2003-09-18 00:40:07 +02:00
ret = CompareStringA ( lcid , NORM_IGNORECASE , " haha " , - 1 , " hoho " , 0 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_GREATER_THAN , " (haha/hoho) Expected CSTR_GREATER_THAN, got %d \n " , ret ) ;
2002-05-29 02:30:32 +02:00
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( lcid , NORM_IGNORECASE , " Salut " , 5 , " saLuT " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_EQUAL , " (Salut/saLuT) Expected CSTR_EQUAL, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = lstrcmpA ( " " , " " ) ;
2004-04-05 22:14:33 +02:00
ok ( ret = = 0 , " lstrcmpA( \" \" , \" \" ) should return 0, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
2004-04-05 22:14:33 +02:00
ret = lstrcmpA ( NULL , NULL ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 0 | | broken ( ret = = - 2 ) /* win9x */ , " lstrcmpA(NULL, NULL) should return 0, got %d \n " , ret ) ;
2004-04-05 22:14:33 +02:00
ret = lstrcmpA ( " " , NULL ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 1 | | broken ( ret = = - 2 ) /* win9x */ , " lstrcmpA( \" \" , NULL) should return 1, got %d \n " , ret ) ;
2004-04-05 22:14:33 +02:00
ret = lstrcmpA ( NULL , " " ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = - 1 | | broken ( ret = = - 2 ) /* win9x */ , " lstrcmpA(NULL, \" \" ) should return -1, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
2021-08-22 18:15:42 +02:00
/* this requires collation table patch to make it MS compatible */
if ( strcmp ( winetest_platform , " wine " ) = = 0 )
skip ( " in Wine due to the lack of a compatible collation table \n " ) ;
else
{
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , 0 , " 'o " , - 1 , " -o " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " 'o vs -o expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " 'o " , - 1 , " -o " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " 'o vs -o expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , 0 , " ' " , - 1 , " - " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " ' vs - expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " ' " , - 1 , " - " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " ' vs - expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , 0 , " `o " , - 1 , " /m " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_GREATER_THAN , " `o vs /m CSTR_GREATER_THAN got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , 0 , " /m " , - 1 , " `o " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " /m vs `o expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " `o " , - 1 , " /m " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_GREATER_THAN , " `o vs /m CSTR_GREATER_THAN got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " /m " , - 1 , " `o " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " /m vs `o expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , 0 , " `o " , - 1 , " -m " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " `o vs -m expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , 0 , " -m " , - 1 , " `o " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_GREATER_THAN , " -m vs `o CSTR_GREATER_THAN got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " `o " , - 1 , " -m " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_GREATER_THAN , " `o vs -m CSTR_GREATER_THAN got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_SYSTEM_DEFAULT , SORT_STRINGSORT , " -m " , - 1 , " `o " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN , " -m vs `o expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2005-06-02 12:30:57 +02:00
}
2003-11-22 01:00:53 +01:00
2006-06-21 23:53:45 +02:00
/* WinXP handles embedded NULLs differently than earlier versions */
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_USER_DEFAULT , 0 , " aLuZkUtZ " , 8 , " aLuZkUtZ \0 A " , 10 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN | | ret = = CSTR_EQUAL , " aLuZkUtZ vs aLuZkUtZ \\ 0A expected CSTR_LESS_THAN or CSTR_EQUAL, got %d \n " , ret ) ;
2003-11-22 01:00:53 +01:00
ret = CompareStringA ( LOCALE_USER_DEFAULT , 0 , " aLu \0 ZkUtZ " , 8 , " aLu \0 ZkUtZ \0 A " , 10 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_LESS_THAN | | ret = = CSTR_EQUAL , " aLu \\ 0ZkUtZ vs aLu \\ 0ZkUtZ \\ 0A expected CSTR_LESS_THAN or CSTR_EQUAL, got %d \n " , ret ) ;
2006-06-21 23:53:45 +02:00
ret = CompareStringA ( lcid , 0 , " a \0 b " , - 1 , " a " , - 1 ) ;
2012-06-20 00:54:18 +02:00
ok ( ret = = CSTR_EQUAL , " a vs a expected CSTR_EQUAL, got %d \n " , ret ) ;
2006-06-21 23:53:45 +02:00
ret = CompareStringA ( lcid , 0 , " a \0 b " , 4 , " a " , 2 ) ;
2008-04-16 23:02:21 +02:00
ok ( ret = = CSTR_EQUAL | | /* win2k */
ret = = CSTR_GREATER_THAN ,
" a \\ 0b vs a expected CSTR_EQUAL or CSTR_GREATER_THAN, got %d \n " , ret ) ;
2006-06-21 23:53:45 +02:00
2006-06-23 09:14:05 +02:00
ret = CompareStringA ( lcid , 0 , " \2 " , 2 , " \1 " , 2 ) ;
2012-06-20 00:54:18 +02:00
todo_wine ok ( ret ! = CSTR_EQUAL , " \\ 2 vs \\ 1 expected unequal \n " ) ;
2009-01-14 14:28:58 +01:00
ret = CompareStringA ( lcid , NORM_IGNORECASE | LOCALE_USE_CP_ACP , " # " , - 1 , " . " , - 1 ) ;
todo_wine ok ( ret = = CSTR_LESS_THAN , " \" # \" vs \" . \" expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2010-06-07 17:29:16 +02:00
ret = CompareStringA ( lcid , NORM_IGNORECASE , " _ " , - 1 , " . " , - 1 ) ;
todo_wine ok ( ret = = CSTR_GREATER_THAN , " \" _ \" vs \" . \" expected CSTR_GREATER_THAN, got %d \n " , ret ) ;
2013-10-21 10:02:07 +02:00
ret = lstrcmpiA ( " # " , " . " ) ;
2009-01-14 14:28:58 +01:00
todo_wine ok ( ret = = - 1 , " \" # \" vs \" . \" expected -1, got %d \n " , ret ) ;
2011-05-12 11:39:01 +02:00
lcid = MAKELCID ( MAKELANGID ( LANG_POLISH , SUBLANG_DEFAULT ) , SORT_DEFAULT ) ;
/* \xB9 character lies between a and b */
ret = CompareStringA ( lcid , 0 , " a " , 1 , " \xB9 " , 1 ) ;
2019-05-21 17:19:48 +02:00
ok ( ret = = CSTR_LESS_THAN , " \' \\ xB9 \' character should be greater than \' a \' \n " ) ;
2011-05-12 11:39:01 +02:00
ret = CompareStringA ( lcid , 0 , " \xB9 " , 1 , " b " , 1 ) ;
ok ( ret = = CSTR_LESS_THAN , " \' \\ xB9 \' character should be smaller than \' b \' \n " ) ;
2013-06-11 15:35:19 +02:00
memset ( a , ' a ' , sizeof ( a ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = CompareStringA ( lcid , 0 , a , sizeof ( a ) , a , sizeof ( a ) ) ;
ok ( GetLastError ( ) = = 0xdeadbeef & & ret = = CSTR_EQUAL ,
" ret %d, error %d, expected value %d \n " , ret , GetLastError ( ) , CSTR_EQUAL ) ;
2018-08-11 03:21:07 +02:00
ret = CompareStringA ( CP_ACP , 0 , ABC_EE , 3 , ABC_FF , 3 ) ;
ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
ret = CompareStringA ( CP_ACP , 0 , ABC_EE , 5 , ABC_FF , 3 ) ;
ok ( ret = = CSTR_GREATER_THAN , " expected CSTR_GREATER_THAN, got %d \n " , ret ) ;
ret = CompareStringA ( CP_ACP , 0 , ABC_EE , 3 , ABC_FF , 5 ) ;
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
ret = CompareStringA ( CP_ACP , 0 , ABC_EE , 5 , ABC_FF , 5 ) ;
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
ret = CompareStringA ( CP_ACP , 0 , ABC_FF , 5 , ABC_EE , 5 ) ;
ok ( ret = = CSTR_GREATER_THAN , " expected CSTR_GREATER_THAN, got %d \n " , ret ) ;
2002-05-29 02:30:32 +02:00
}
2016-02-13 22:24:06 +01:00
static void test_CompareStringW ( void )
{
2018-08-11 03:21:07 +02:00
static const WCHAR ABC_EE [ ] = { ' A ' , ' B ' , ' C ' , 0 , 0xEE } ;
static const WCHAR ABC_FF [ ] = { ' A ' , ' B ' , ' C ' , 0 , 0xFF } ;
2019-05-15 21:58:48 +02:00
static const WCHAR A_ACUTE_BC [ ] = { 0xc1 , ' B ' , ' C ' , 0 } ;
static const WCHAR A_ACUTE_BC_DECOMP [ ] = { ' A ' , 0x301 , ' B ' , ' C ' , 0 } ;
static const WCHAR A_NULL_BC [ ] = { ' A ' , 0 , ' B ' , ' C ' , 0 } ;
2016-02-13 22:24:06 +01:00
WCHAR * str1 , * str2 ;
SYSTEM_INFO si ;
DWORD old_prot ;
BOOL success ;
char * buf ;
int ret ;
GetSystemInfo ( & si ) ;
buf = VirtualAlloc ( NULL , si . dwPageSize * 4 , MEM_COMMIT , PAGE_READWRITE ) ;
ok ( buf ! = NULL , " VirtualAlloc failed with %u \n " , GetLastError ( ) ) ;
success = VirtualProtect ( buf + si . dwPageSize , si . dwPageSize , PAGE_NOACCESS , & old_prot ) ;
ok ( success , " VirtualProtect failed with %u \n " , GetLastError ( ) ) ;
success = VirtualProtect ( buf + 3 * si . dwPageSize , si . dwPageSize , PAGE_NOACCESS , & old_prot ) ;
ok ( success , " VirtualProtect failed with %u \n " , GetLastError ( ) ) ;
str1 = ( WCHAR * ) ( buf + si . dwPageSize - sizeof ( WCHAR ) ) ;
str2 = ( WCHAR * ) ( buf + 3 * si . dwPageSize - sizeof ( WCHAR ) ) ;
* str1 = ' A ' ;
* str2 = ' B ' ;
/* CompareStringW should abort on the first non-matching character */
ret = CompareStringW ( CP_ACP , 0 , str1 , 100 , str2 , 100 ) ;
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
success = VirtualFree ( buf , 0 , MEM_RELEASE ) ;
ok ( success , " VirtualFree failed with %u \n " , GetLastError ( ) ) ;
2018-08-11 03:21:07 +02:00
2021-03-20 17:58:43 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = CompareStringW ( CP_ACP , SORT_DIGITSASNUMBERS , L " NULL " , - 1 , L " NULL " , - 1 ) ;
2021-03-20 17:58:44 +01:00
ok ( ret = = CSTR_EQUAL | | broken ( ! ret & & GetLastError ( ) = = ERROR_INVALID_FLAGS ) /* <Win7 */ ,
2021-03-20 17:58:43 +01:00
" expected CSTR_EQUAL, got %d, last error %d \n " , ret , GetLastError ( ) ) ;
2018-08-11 03:21:07 +02:00
ret = CompareStringW ( CP_ACP , 0 , ABC_EE , 3 , ABC_FF , 3 ) ;
ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
ret = CompareStringW ( CP_ACP , 0 , ABC_EE , 5 , ABC_FF , 3 ) ;
ok ( ret = = CSTR_GREATER_THAN , " expected CSTR_GREATER_THAN, got %d \n " , ret ) ;
ret = CompareStringW ( CP_ACP , 0 , ABC_EE , 3 , ABC_FF , 5 ) ;
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
ret = CompareStringW ( CP_ACP , 0 , ABC_EE , 5 , ABC_FF , 5 ) ;
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
ret = CompareStringW ( CP_ACP , 0 , ABC_FF , 5 , ABC_EE , 5 ) ;
ok ( ret = = CSTR_GREATER_THAN , " expected CSTR_GREATER_THAN, got %d \n " , ret ) ;
2019-05-15 21:58:48 +02:00
ret = CompareStringW ( CP_ACP , 0 , ABC_EE , 4 , A_ACUTE_BC , 4 ) ;
2019-05-21 17:19:52 +02:00
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2019-05-15 21:58:48 +02:00
ret = CompareStringW ( CP_ACP , 0 , ABC_EE , 4 , A_ACUTE_BC_DECOMP , 5 ) ;
2019-05-21 17:19:52 +02:00
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2019-05-15 21:58:48 +02:00
ret = CompareStringW ( CP_ACP , 0 , A_ACUTE_BC , 4 , A_ACUTE_BC_DECOMP , 5 ) ;
2019-05-21 17:19:48 +02:00
ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
2019-05-15 21:58:48 +02:00
ret = CompareStringW ( CP_ACP , NORM_IGNORENONSPACE , ABC_EE , 3 , A_ACUTE_BC , 4 ) ;
2019-05-21 17:19:48 +02:00
todo_wine ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
2019-05-15 21:58:48 +02:00
ret = CompareStringW ( CP_ACP , NORM_IGNORENONSPACE , ABC_EE , 4 , A_ACUTE_BC_DECOMP , 5 ) ;
todo_wine ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
ret = CompareStringW ( CP_ACP , NORM_IGNORENONSPACE , A_ACUTE_BC , 4 , A_ACUTE_BC_DECOMP , 5 ) ;
2019-05-21 17:19:48 +02:00
ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
2019-05-15 21:58:48 +02:00
ret = CompareStringW ( CP_ACP , 0 , ABC_EE , 4 , A_NULL_BC , 4 ) ;
2019-05-21 17:19:52 +02:00
ok ( ret = = CSTR_EQUAL , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
2019-05-15 21:58:48 +02:00
ret = CompareStringW ( CP_ACP , NORM_IGNORENONSPACE , ABC_EE , 4 , A_NULL_BC , 4 ) ;
2019-05-21 17:19:52 +02:00
ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
2019-05-15 21:58:48 +02:00
ret = CompareStringW ( CP_ACP , 0 , A_NULL_BC , 4 , A_ACUTE_BC , 4 ) ;
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
ret = CompareStringW ( CP_ACP , NORM_IGNORENONSPACE , A_NULL_BC , 4 , A_ACUTE_BC , 4 ) ;
todo_wine ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
ret = CompareStringW ( CP_ACP , 0 , A_NULL_BC , 4 , A_ACUTE_BC_DECOMP , 5 ) ;
ok ( ret = = CSTR_LESS_THAN , " expected CSTR_LESS_THAN, got %d \n " , ret ) ;
ret = CompareStringW ( CP_ACP , NORM_IGNORENONSPACE , A_NULL_BC , 4 , A_ACUTE_BC_DECOMP , 5 ) ;
todo_wine ok ( ret = = CSTR_EQUAL , " expected CSTR_EQUAL, got %d \n " , ret ) ;
2016-02-13 22:24:06 +01:00
}
2014-04-16 21:54:58 +02:00
struct comparestringex_test {
const char * locale ;
DWORD flags ;
const WCHAR first [ 2 ] ;
const WCHAR second [ 2 ] ;
INT ret ;
INT broken ;
BOOL todo ;
} ;
static const struct comparestringex_test comparestringex_tests [ ] = {
/* default behavior */
{ /* 0 */
" tr-TR " , 0 ,
{ ' i ' , 0 } , { ' I ' , 0 } , CSTR_LESS_THAN , - 1 , FALSE
} ,
{ /* 1 */
" tr-TR " , 0 ,
{ ' i ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
} ,
{ /* 2 */
" tr-TR " , 0 ,
{ ' i ' , 0 } , { 0x131 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
} ,
{ /* 3 */
" tr-TR " , 0 ,
2019-05-21 17:19:48 +02:00
{ ' I ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 4 */
" tr-TR " , 0 ,
{ ' I ' , 0 } , { 0x131 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
} ,
{ /* 5 */
" tr-TR " , 0 ,
{ 0x130 , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , - 1 , TRUE
} ,
/* with NORM_IGNORECASE */
{ /* 6 */
" tr-TR " , NORM_IGNORECASE ,
{ ' i ' , 0 } , { ' I ' , 0 } , CSTR_EQUAL , - 1 , FALSE
} ,
{ /* 7 */
" tr-TR " , NORM_IGNORECASE ,
2019-05-21 17:19:48 +02:00
{ ' i ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 8 */
" tr-TR " , NORM_IGNORECASE ,
{ ' i ' , 0 } , { 0x131 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
} ,
{ /* 9 */
" tr-TR " , NORM_IGNORECASE ,
2019-05-21 17:19:48 +02:00
{ ' I ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 10 */
" tr-TR " , NORM_IGNORECASE ,
{ ' I ' , 0 } , { 0x131 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
} ,
{ /* 11 */
" tr-TR " , NORM_IGNORECASE ,
{ 0x130 , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , - 1 , TRUE
} ,
/* with NORM_LINGUISTIC_CASING */
{ /* 12 */
" tr-TR " , NORM_LINGUISTIC_CASING ,
{ ' i ' , 0 } , { ' I ' , 0 } , CSTR_GREATER_THAN , CSTR_LESS_THAN , TRUE
} ,
{ /* 13 */
" tr-TR " , NORM_LINGUISTIC_CASING ,
2014-04-16 21:55:13 +02:00
{ ' i ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 14 */
" tr-TR " , NORM_LINGUISTIC_CASING ,
{ ' i ' , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , CSTR_LESS_THAN , TRUE
} ,
{ /* 15 */
" tr-TR " , NORM_LINGUISTIC_CASING ,
2019-05-21 17:19:48 +02:00
{ ' I ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 16 */
" tr-TR " , NORM_LINGUISTIC_CASING ,
{ ' I ' , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , CSTR_LESS_THAN , TRUE
} ,
{ /* 17 */
" tr-TR " , NORM_LINGUISTIC_CASING ,
{ 0x130 , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , - 1 , TRUE
} ,
/* with LINGUISTIC_IGNORECASE */
{ /* 18 */
" tr-TR " , LINGUISTIC_IGNORECASE ,
{ ' i ' , 0 } , { ' I ' , 0 } , CSTR_EQUAL , - 1 , TRUE
} ,
{ /* 19 */
" tr-TR " , LINGUISTIC_IGNORECASE ,
2014-04-16 21:55:24 +02:00
{ ' i ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 20 */
" tr-TR " , LINGUISTIC_IGNORECASE ,
2014-04-16 21:55:24 +02:00
{ ' i ' , 0 } , { 0x131 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 21 */
" tr-TR " , LINGUISTIC_IGNORECASE ,
2019-05-21 17:19:48 +02:00
{ ' I ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 22 */
" tr-TR " , LINGUISTIC_IGNORECASE ,
2014-04-16 21:55:24 +02:00
{ ' I ' , 0 } , { 0x131 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 23 */
" tr-TR " , LINGUISTIC_IGNORECASE ,
{ 0x130 , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , - 1 , TRUE
} ,
/* with NORM_LINGUISTIC_CASING | NORM_IGNORECASE */
{ /* 24 */
" tr-TR " , NORM_LINGUISTIC_CASING | NORM_IGNORECASE ,
{ ' i ' , 0 } , { ' I ' , 0 } , CSTR_GREATER_THAN , CSTR_EQUAL , TRUE
} ,
{ /* 25 */
" tr-TR " , NORM_LINGUISTIC_CASING | NORM_IGNORECASE ,
2019-05-21 17:19:48 +02:00
{ ' i ' , 0 } , { 0x130 , 0 } , CSTR_EQUAL , CSTR_LESS_THAN , TRUE
2014-04-16 21:54:58 +02:00
} ,
{ /* 26 */
" tr-TR " , NORM_LINGUISTIC_CASING | NORM_IGNORECASE ,
{ ' i ' , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , CSTR_LESS_THAN , TRUE
} ,
{ /* 27 */
" tr-TR " , NORM_LINGUISTIC_CASING | NORM_IGNORECASE ,
2019-05-21 17:19:48 +02:00
{ ' I ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 28 */
" tr-TR " , NORM_LINGUISTIC_CASING | NORM_IGNORECASE ,
{ ' I ' , 0 } , { 0x131 , 0 } , CSTR_EQUAL , CSTR_LESS_THAN , TRUE
} ,
{ /* 29 */
" tr-TR " , NORM_LINGUISTIC_CASING | NORM_IGNORECASE ,
{ 0x130 , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , - 1 , TRUE
} ,
/* with NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE */
{ /* 30 */
" tr-TR " , NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE ,
{ ' i ' , 0 } , { ' I ' , 0 } , CSTR_GREATER_THAN , CSTR_EQUAL , TRUE
} ,
{ /* 31 */
" tr-TR " , NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE ,
{ ' i ' , 0 } , { 0x130 , 0 } , CSTR_EQUAL , CSTR_LESS_THAN , TRUE
} ,
{ /* 32 */
" tr-TR " , NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE ,
{ ' i ' , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , CSTR_LESS_THAN , TRUE
} ,
{ /* 33 */
" tr-TR " , NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE ,
2019-05-21 17:19:48 +02:00
{ ' I ' , 0 } , { 0x130 , 0 } , CSTR_LESS_THAN , - 1 , FALSE
2014-04-16 21:54:58 +02:00
} ,
{ /* 34 */
" tr-TR " , NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE ,
{ ' I ' , 0 } , { 0x131 , 0 } , CSTR_EQUAL , CSTR_LESS_THAN , TRUE
} ,
{ /* 35 */
" tr-TR " , NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE ,
{ 0x130 , 0 } , { 0x131 , 0 } , CSTR_GREATER_THAN , CSTR_LESS_THAN , TRUE
}
} ;
static void test_CompareStringEx ( void )
{
const char * op [ ] = { " ERROR " , " CSTR_LESS_THAN " , " CSTR_EQUAL " , " CSTR_GREATER_THAN " } ;
WCHAR locale [ 6 ] ;
INT ret , i ;
/* CompareStringEx is only available on Vista+ */
if ( ! pCompareStringEx )
{
win_skip ( " CompareStringEx not supported \n " ) ;
return ;
}
2018-06-22 19:50:38 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( comparestringex_tests ) ; i + + )
2014-04-16 21:54:58 +02:00
{
const struct comparestringex_test * e = & comparestringex_tests [ i ] ;
2018-06-22 19:50:38 +02:00
MultiByteToWideChar ( CP_ACP , 0 , e - > locale , - 1 , locale , ARRAY_SIZE ( locale ) ) ;
2014-04-16 21:54:58 +02:00
ret = pCompareStringEx ( locale , e - > flags , e - > first , - 1 , e - > second , - 1 , NULL , NULL , 0 ) ;
2016-02-15 21:06:44 +01:00
todo_wine_if ( e - > todo )
2014-04-16 21:54:58 +02:00
ok ( ret = = e - > ret | | broken ( ret = = e - > broken ) ,
" %d: got %s, expected %s \n " , i , op [ ret ] , op [ e - > ret ] ) ;
}
}
2016-09-22 17:06:07 +02:00
static const DWORD lcmap_invalid_flags [ ] = {
2016-09-22 17:06:10 +02:00
0 ,
2016-09-22 17:06:07 +02:00
LCMAP_HIRAGANA | LCMAP_KATAKANA ,
LCMAP_HALFWIDTH | LCMAP_FULLWIDTH ,
LCMAP_TRADITIONAL_CHINESE | LCMAP_SIMPLIFIED_CHINESE ,
LCMAP_LOWERCASE | SORT_STRINGSORT ,
2016-09-22 17:06:09 +02:00
LCMAP_UPPERCASE | NORM_IGNORESYMBOLS ,
LCMAP_LOWERCASE | NORM_IGNORESYMBOLS ,
LCMAP_UPPERCASE | NORM_IGNORENONSPACE ,
LCMAP_LOWERCASE | NORM_IGNORENONSPACE ,
2016-09-22 17:06:18 +02:00
LCMAP_HIRAGANA | NORM_IGNORENONSPACE ,
LCMAP_HIRAGANA | NORM_IGNORESYMBOLS ,
LCMAP_HIRAGANA | LCMAP_SIMPLIFIED_CHINESE ,
LCMAP_HIRAGANA | LCMAP_TRADITIONAL_CHINESE ,
2016-09-22 17:06:19 +02:00
LCMAP_KATAKANA | NORM_IGNORENONSPACE ,
LCMAP_KATAKANA | NORM_IGNORESYMBOLS ,
LCMAP_KATAKANA | LCMAP_SIMPLIFIED_CHINESE ,
LCMAP_KATAKANA | LCMAP_TRADITIONAL_CHINESE ,
2016-10-02 17:06:55 +02:00
LCMAP_FULLWIDTH | NORM_IGNORENONSPACE ,
LCMAP_FULLWIDTH | NORM_IGNORESYMBOLS ,
LCMAP_FULLWIDTH | LCMAP_SIMPLIFIED_CHINESE ,
LCMAP_FULLWIDTH | LCMAP_TRADITIONAL_CHINESE ,
2016-10-02 17:06:57 +02:00
LCMAP_HALFWIDTH | NORM_IGNORENONSPACE ,
LCMAP_HALFWIDTH | NORM_IGNORESYMBOLS ,
LCMAP_HALFWIDTH | LCMAP_SIMPLIFIED_CHINESE ,
LCMAP_HALFWIDTH | LCMAP_TRADITIONAL_CHINESE ,
2016-09-22 17:06:07 +02:00
} ;
2005-05-31 11:30:45 +02:00
static void test_LCMapStringA ( void )
2003-06-27 21:02:23 +02:00
{
2016-09-22 17:06:07 +02:00
int ret , ret2 , i ;
2003-06-27 21:02:23 +02:00
char buf [ 256 ] , buf2 [ 256 ] ;
static const char upper_case [ ] = " \t JUST! A, TEST; STRING 1/*+-. \r \n " ;
static const char lower_case [ ] = " \t just! a, test; string 1/*+-. \r \n " ;
static const char symbols_stripped [ ] = " justateststring1 " ;
2004-11-21 16:47:24 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LOCALE_USE_CP_ACP | LCMAP_LOWERCASE ,
lower_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret = = lstrlenA ( lower_case ) + 1 ,
2006-10-10 01:06:48 +02:00
" ret %d, error %d, expected value %d \n " ,
2004-11-21 16:47:24 +01:00
ret , GetLastError ( ) , lstrlenA ( lower_case ) + 1 ) ;
ok ( ! memcmp ( buf , lower_case , ret ) , " LCMapStringA should return %s, but not %s \n " , lower_case , buf ) ;
2003-06-27 21:02:23 +02:00
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_LOWERCASE | LCMAP_UPPERCASE ,
upper_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ! ret , " LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS ,
2006-10-10 01:06:48 +02:00
" unexpected error code %d \n " , GetLastError ( ) ) ;
2003-06-27 21:02:23 +02:00
2016-09-22 17:06:07 +02:00
/* test invalid flag combinations */
2018-06-22 19:50:38 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( lcmap_invalid_flags ) ; i + + ) {
2016-09-22 17:06:07 +02:00
lstrcpyA ( buf , " foo " ) ;
SetLastError ( 0xdeadbeef ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , lcmap_invalid_flags [ i ] ,
lower_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS ,
" LCMapStringA (flag %08x) unexpected error code %d \n " ,
lcmap_invalid_flags [ i ] , GetLastError ( ) ) ;
ok ( ! ret , " LCMapStringA (flag %08x) should return 0, got %d \n " ,
lcmap_invalid_flags [ i ] , ret ) ;
}
2003-06-27 21:02:23 +02:00
/* test LCMAP_LOWERCASE */
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_LOWERCASE ,
upper_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret = = lstrlenA ( upper_case ) + 1 ,
2006-10-10 01:06:48 +02:00
" ret %d, error %d, expected value %d \n " ,
2003-06-27 21:02:23 +02:00
ret , GetLastError ( ) , lstrlenA ( upper_case ) + 1 ) ;
ok ( ! lstrcmpA ( buf , lower_case ) , " LCMapStringA should return %s, but not %s \n " , lower_case , buf ) ;
/* test LCMAP_UPPERCASE */
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_UPPERCASE ,
lower_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret = = lstrlenA ( lower_case ) + 1 ,
2006-10-10 01:06:48 +02:00
" ret %d, error %d, expected value %d \n " ,
2003-06-27 21:02:23 +02:00
ret , GetLastError ( ) , lstrlenA ( lower_case ) + 1 ) ;
ok ( ! lstrcmpA ( buf , upper_case ) , " LCMapStringA should return %s, but not %s \n " , upper_case , buf ) ;
2003-11-22 01:00:53 +01:00
/* test buffer overflow */
SetLastError ( 0xdeadbeef ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_UPPERCASE ,
lower_case , - 1 , buf , 4 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d \n " , ret ) ;
2003-06-27 21:02:23 +02:00
/* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
lstrcpyA ( buf , lower_case ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_UPPERCASE ,
buf , - 1 , buf , sizeof ( buf ) ) ;
if ( ! ret ) /* Win9x */
trace ( " Ignoring LCMapStringA(LCMAP_UPPERCASE, buf, buf) error on Win9x \n " ) ;
else
{
ok ( ret = = lstrlenA ( lower_case ) + 1 ,
2006-10-10 01:06:48 +02:00
" ret %d, error %d, expected value %d \n " ,
2003-06-27 21:02:23 +02:00
ret , GetLastError ( ) , lstrlenA ( lower_case ) + 1 ) ;
ok ( ! lstrcmpA ( buf , upper_case ) , " LCMapStringA should return %s, but not %s \n " , upper_case , buf ) ;
}
lstrcpyA ( buf , upper_case ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_LOWERCASE ,
buf , - 1 , buf , sizeof ( buf ) ) ;
if ( ! ret ) /* Win9x */
trace ( " Ignoring LCMapStringA(LCMAP_LOWERCASE, buf, buf) error on Win9x \n " ) ;
else
{
ok ( ret = = lstrlenA ( upper_case ) + 1 ,
2006-10-10 01:06:48 +02:00
" ret %d, error %d, expected value %d \n " ,
2003-06-27 21:02:23 +02:00
ret , GetLastError ( ) , lstrlenA ( lower_case ) + 1 ) ;
ok ( ! lstrcmpA ( buf , lower_case ) , " LCMapStringA should return %s, but not %s \n " , lower_case , buf ) ;
}
/* otherwise src == dst should fail */
SetLastError ( 0xdeadbeef ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_SORTKEY | LCMAP_UPPERCASE ,
buf , 10 , buf , sizeof ( buf ) ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS /* NT */ | |
GetLastError ( ) = = ERROR_INVALID_PARAMETER /* Win9x */ ,
2006-10-10 01:06:48 +02:00
" unexpected error code %d \n " , GetLastError ( ) ) ;
2003-06-27 21:02:23 +02:00
ok ( ! ret , " src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail \n " ) ;
/* test whether '\0' is always appended */
2020-02-12 19:14:05 +01:00
memset ( buf , 0xff , sizeof ( buf ) ) ;
2003-06-27 21:02:23 +02:00
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_SORTKEY ,
upper_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret , " LCMapStringA must succeed \n " ) ;
2009-01-19 13:46:30 +01:00
ok ( buf [ ret - 1 ] = = 0 , " LCMapStringA not null-terminated \n " ) ;
2003-06-27 21:02:23 +02:00
ret2 = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_SORTKEY ,
upper_case , lstrlenA ( upper_case ) , buf2 , sizeof ( buf2 ) ) ;
2009-01-19 13:46:30 +01:00
ok ( ret2 , " LCMapStringA must succeed \n " ) ;
ok ( buf2 [ ret2 - 1 ] = = 0 , " LCMapStringA not null-terminated \n " ) ;
2003-06-27 21:02:23 +02:00
ok ( ret = = ret2 , " lengths of sort keys must be equal \n " ) ;
ok ( ! lstrcmpA ( buf , buf2 ) , " sort keys must be equal \n " ) ;
2019-03-05 10:58:31 +01:00
/* test we get the same length when no dest buffer is provided */
ret2 = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_SORTKEY ,
upper_case , lstrlenA ( upper_case ) , NULL , 0 ) ;
ok ( ret2 , " LCMapStringA must succeed \n " ) ;
ok ( ret = = ret2 , " lengths of sort keys must be equal (%d vs %d) \n " , ret , ret2 ) ;
2003-06-27 21:02:23 +02:00
/* test LCMAP_SORTKEY | NORM_IGNORECASE */
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_SORTKEY | NORM_IGNORECASE ,
upper_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret , " LCMapStringA must succeed \n " ) ;
ret2 = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_SORTKEY ,
lower_case , - 1 , buf2 , sizeof ( buf2 ) ) ;
ok ( ret2 , " LCMapStringA must succeed \n " ) ;
ok ( ret = = ret2 , " lengths of sort keys must be equal \n " ) ;
ok ( ! lstrcmpA ( buf , buf2 ) , " sort keys must be equal \n " ) ;
2009-09-01 12:19:35 +02:00
/* Don't test LCMAP_SORTKEY | NORM_IGNORENONSPACE, produces different
results from plain LCMAP_SORTKEY on Vista */
2003-06-30 23:06:12 +02:00
/* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
ret = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_SORTKEY | NORM_IGNORESYMBOLS ,
lower_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret , " LCMapStringA must succeed \n " ) ;
ret2 = LCMapStringA ( LOCALE_USER_DEFAULT , LCMAP_SORTKEY ,
symbols_stripped , - 1 , buf2 , sizeof ( buf2 ) ) ;
ok ( ret2 , " LCMapStringA must succeed \n " ) ;
ok ( ret = = ret2 , " lengths of sort keys must be equal \n " ) ;
ok ( ! lstrcmpA ( buf , buf2 ) , " sort keys must be equal \n " ) ;
2003-06-27 21:02:23 +02:00
/* test NORM_IGNORENONSPACE */
lstrcpyA ( buf , " foo " ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , NORM_IGNORENONSPACE ,
lower_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret = = lstrlenA ( lower_case ) + 1 , " LCMapStringA should return %d, ret = %d \n " ,
lstrlenA ( lower_case ) + 1 , ret ) ;
ok ( ! lstrcmpA ( buf , lower_case ) , " LCMapStringA should return %s, but not %s \n " , lower_case , buf ) ;
/* test NORM_IGNORESYMBOLS */
lstrcpyA ( buf , " foo " ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , NORM_IGNORESYMBOLS ,
lower_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret = = lstrlenA ( symbols_stripped ) + 1 , " LCMapStringA should return %d, ret = %d \n " ,
lstrlenA ( symbols_stripped ) + 1 , ret ) ;
ok ( ! lstrcmpA ( buf , symbols_stripped ) , " LCMapStringA should return %s, but not %s \n " , lower_case , buf ) ;
2003-11-22 01:00:53 +01:00
2016-09-22 17:06:09 +02:00
/* test NORM_IGNORESYMBOLS | NORM_IGNORENONSPACE */
lstrcpyA ( buf , " foo " ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , NORM_IGNORESYMBOLS | NORM_IGNORENONSPACE ,
lower_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( ret = = lstrlenA ( symbols_stripped ) + 1 , " LCMapStringA should return %d, ret = %d \n " ,
lstrlenA ( symbols_stripped ) + 1 , ret ) ;
ok ( ! lstrcmpA ( buf , symbols_stripped ) , " LCMapStringA should return %s, but not %s \n " , lower_case , buf ) ;
2003-11-22 01:00:53 +01:00
/* test srclen = 0 */
SetLastError ( 0xdeadbeef ) ;
ret = LCMapStringA ( LOCALE_USER_DEFAULT , 0 , upper_case , 0 , buf , sizeof ( buf ) ) ;
2004-02-06 06:24:34 +01:00
ok ( ! ret , " LCMapStringA should fail with srclen = 0 \n " ) ;
2003-11-22 01:00:53 +01:00
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2006-10-10 01:06:48 +02:00
" unexpected error code %d \n " , GetLastError ( ) ) ;
2003-06-27 21:02:23 +02:00
}
2012-06-04 22:53:55 +02:00
typedef INT ( * lcmapstring_wrapper ) ( DWORD , LPCWSTR , INT , LPWSTR , INT ) ;
static void test_lcmapstring_unicode ( lcmapstring_wrapper func_ptr , const char * func_name )
2003-06-27 21:02:23 +02:00
{
2016-09-22 17:06:13 +02:00
const static WCHAR japanese_text [ ] = {
2018-10-15 17:31:21 +02:00
0x3044 , 0x309d , 0x3084 , 0x3001 , 0x30a4 , 0x30fc , 0x30cf , 0x30c8 ,
0x30fc , 0x30f4 , 0x30a9 , 0x306e , 0x91ce , 0x539f , 0x306f , 0x5e83 ,
0x3044 , 0x3093 , 0x3060 , 0x3088 , 0x3002 , 0
2016-09-22 17:06:13 +02:00
} ;
const static WCHAR hiragana_text [ ] = {
2018-10-15 17:31:21 +02:00
0x3044 , 0x309d , 0x3084 , 0x3001 , 0x3044 , 0x30fc , 0x306f , 0x3068 ,
0x30fc , 0x3094 , 0x3049 , 0x306e , 0x91ce , 0x539f , 0x306f , 0x5e83 ,
0x3044 , 0x3093 , 0x3060 , 0x3088 , 0x3002 , 0
2016-09-22 17:06:13 +02:00
} ;
const static WCHAR katakana_text [ ] = {
2018-10-15 17:31:21 +02:00
0x30a4 , 0x30fd , 0x30e4 , 0x3001 , 0x30a4 , 0x30fc , 0x30cf , 0x30c8 ,
0x30fc , 0x30f4 , 0x30a9 , 0x30ce , 0x91ce , 0x539f , 0x30cf , 0x5e83 ,
0x30a4 , 0x30f3 , 0x30c0 , 0x30e8 , 0x3002 , 0
2016-09-22 17:06:13 +02:00
} ;
const static WCHAR halfwidth_text [ ] = {
2018-10-15 17:31:21 +02:00
0x3044 , 0x309d , 0x3084 , 0xff64 , 0xff72 , 0xff70 , 0xff8a , 0xff84 ,
0xff70 , 0xff73 , 0xff9e , 0xff6b , 0x306e , 0x91ce , 0x539f , 0x306f ,
0x5e83 , 0x3044 , 0x3093 , 0x3060 , 0x3088 , 0xff61 , 0
} ;
const static WCHAR halfwidth_text2 [ ] = {
0xff72 , 0x30fd , 0xff94 , 0xff64 , 0xff72 , 0xff70 , 0xff8a , 0xff84 ,
0xff70 , 0xff73 , 0xff9e , 0xff6b , 0xff89 , 0x91ce , 0x539f , 0xff8a ,
0x5e83 , 0xff72 , 0xff9d , 0xff80 , 0xff9e , 0xff96 , 0xff61 , 0
2016-09-22 17:06:13 +02:00
} ;
2016-09-22 17:06:07 +02:00
int ret , ret2 , i ;
2003-06-27 21:02:23 +02:00
WCHAR buf [ 256 ] , buf2 [ 256 ] ;
char * p_buf = ( char * ) buf , * p_buf2 = ( char * ) buf2 ;
2016-09-22 17:06:12 +02:00
/* LCMAP_LOWERCASE | LCMAP_UPPERCASE makes LCMAP_TITLECASE, so it's valid now. */
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_LOWERCASE | LCMAP_UPPERCASE , lower_case , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2016-09-22 17:06:12 +02:00
todo_wine ok ( ret = = lstrlenW ( title_case ) + 1 | | broken ( ! ret ) ,
" %s ret %d, error %d, expected value %d \n " , func_name ,
ret , GetLastError ( ) , lstrlenW ( title_case ) + 1 ) ;
todo_wine ok ( lstrcmpW ( buf , title_case ) = = 0 | | broken ( ! ret ) ,
" Expected title case string \n " ) ;
2003-06-27 21:02:23 +02:00
2016-09-22 17:06:07 +02:00
/* test invalid flag combinations */
2018-06-22 19:50:38 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( lcmap_invalid_flags ) ; i + + ) {
2016-09-22 17:06:07 +02:00
lstrcpyW ( buf , fooW ) ;
SetLastError ( 0xdeadbeef ) ;
ret = func_ptr ( lcmap_invalid_flags [ i ] ,
lower_case , - 1 , buf , sizeof ( buf ) ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS ,
" %s (flag %08x) unexpected error code %d \n " ,
func_name , lcmap_invalid_flags [ i ] , GetLastError ( ) ) ;
ok ( ! ret , " %s (flag %08x) should return 0, got %d \n " ,
func_name , lcmap_invalid_flags [ i ] , ret ) ;
}
2003-06-27 21:02:23 +02:00
/* test LCMAP_LOWERCASE */
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_LOWERCASE , upper_case , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret = = lstrlenW ( upper_case ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
2003-06-27 21:02:23 +02:00
ret , GetLastError ( ) , lstrlenW ( upper_case ) + 1 ) ;
2012-06-04 22:53:55 +02:00
ok ( ! lstrcmpW ( buf , lower_case ) , " %s string compare mismatch \n " , func_name ) ;
2003-06-27 21:02:23 +02:00
/* test LCMAP_UPPERCASE */
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_UPPERCASE , lower_case , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret = = lstrlenW ( lower_case ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
2003-06-27 21:02:23 +02:00
ret , GetLastError ( ) , lstrlenW ( lower_case ) + 1 ) ;
2012-06-04 22:53:55 +02:00
ok ( ! lstrcmpW ( buf , upper_case ) , " %s string compare mismatch \n " , func_name ) ;
2003-06-27 21:02:23 +02:00
2016-09-22 17:06:13 +02:00
/* test LCMAP_HIRAGANA */
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_HIRAGANA , japanese_text , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2016-09-22 17:06:13 +02:00
ok ( ret = = lstrlenW ( hiragana_text ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
ret , GetLastError ( ) , lstrlenW ( hiragana_text ) + 1 ) ;
2016-09-22 17:06:18 +02:00
ok ( ! lstrcmpW ( buf , hiragana_text ) , " %s string compare mismatch \n " , func_name ) ;
2016-09-22 17:06:13 +02:00
buf [ 0 ] = 0x30f5 ; /* KATAKANA LETTER SMALL KA */
ret = func_ptr ( LCMAP_HIRAGANA , buf , 1 , buf2 , 1 ) ;
ok ( ret = = 1 , " %s ret %d, error %d, expected value 1 \n " , func_name ,
ret , GetLastError ( ) ) ;
/* U+3095: HIRAGANA LETTER SMALL KA was added in Unicode 3.2 */
2016-09-22 17:06:18 +02:00
ok ( buf2 [ 0 ] = = 0x3095 | | broken ( buf2 [ 0 ] = = 0x30f5 /* Vista and earlier versions */ ) ,
2016-09-22 17:06:13 +02:00
" %s expected %04x, got %04x \n " , func_name , 0x3095 , buf2 [ 0 ] ) ;
/* test LCMAP_KATAKANA | LCMAP_LOWERCASE */
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_KATAKANA | LCMAP_LOWERCASE , japanese_text , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2016-09-22 17:06:13 +02:00
ok ( ret = = lstrlenW ( katakana_text ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
ret , GetLastError ( ) , lstrlenW ( katakana_text ) + 1 ) ;
2016-09-22 17:06:19 +02:00
ok ( ! lstrcmpW ( buf , katakana_text ) , " %s string compare mismatch \n " , func_name ) ;
2016-09-22 17:06:13 +02:00
/* test LCMAP_FULLWIDTH */
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_FULLWIDTH , halfwidth_text , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2016-10-02 17:06:55 +02:00
ok ( ret = = lstrlenW ( japanese_text ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
2016-09-22 17:06:13 +02:00
ret , GetLastError ( ) , lstrlenW ( japanese_text ) + 1 ) ;
2016-10-02 17:06:55 +02:00
ok ( ! lstrcmpW ( buf , japanese_text ) , " %s string compare mismatch \n " , func_name ) ;
2016-09-22 17:06:13 +02:00
ret2 = func_ptr ( LCMAP_FULLWIDTH , halfwidth_text , - 1 , NULL , 0 ) ;
ok ( ret = = ret2 , " %s ret %d, expected value %d \n " , func_name , ret2 , ret ) ;
/* test LCMAP_FULLWIDTH | LCMAP_HIRAGANA
2018-01-08 12:44:12 +01:00
( half - width katakana is converted into full - width hiragana ) */
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_FULLWIDTH | LCMAP_HIRAGANA , halfwidth_text , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2016-10-02 17:06:55 +02:00
ok ( ret = = lstrlenW ( hiragana_text ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
2016-09-22 17:06:13 +02:00
ret , GetLastError ( ) , lstrlenW ( hiragana_text ) + 1 ) ;
2016-10-02 17:06:55 +02:00
ok ( ! lstrcmpW ( buf , hiragana_text ) , " %s string compare mismatch \n " , func_name ) ;
2016-09-22 17:06:13 +02:00
ret2 = func_ptr ( LCMAP_FULLWIDTH | LCMAP_HIRAGANA , halfwidth_text , - 1 , NULL , 0 ) ;
ok ( ret = = ret2 , " %s ret %d, expected value %d \n " , func_name , ret , ret2 ) ;
/* test LCMAP_HALFWIDTH */
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_HALFWIDTH , japanese_text , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2016-10-02 17:06:57 +02:00
ok ( ret = = lstrlenW ( halfwidth_text ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
2016-09-22 17:06:13 +02:00
ret , GetLastError ( ) , lstrlenW ( halfwidth_text ) + 1 ) ;
2016-10-02 17:06:57 +02:00
ok ( ! lstrcmpW ( buf , halfwidth_text ) , " %s string compare mismatch \n " , func_name ) ;
2016-09-22 17:06:13 +02:00
ret2 = func_ptr ( LCMAP_HALFWIDTH , japanese_text , - 1 , NULL , 0 ) ;
ok ( ret = = ret2 , " %s ret %d, expected value %d \n " , func_name , ret , ret2 ) ;
2018-10-15 17:31:21 +02:00
/* test LCMAP_HALFWIDTH | LCMAP_KATAKANA
( hiragana character is converted into half - width katakana ) */
ret = func_ptr ( LCMAP_HALFWIDTH | LCMAP_KATAKANA , japanese_text , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
ok ( ret = = lstrlenW ( halfwidth_text2 ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
ret , GetLastError ( ) , lstrlenW ( halfwidth_text2 ) + 1 ) ;
ok ( ! lstrcmpW ( buf , halfwidth_text2 ) , " %s string compare mismatch \n " , func_name ) ;
ret2 = func_ptr ( LCMAP_HALFWIDTH | LCMAP_KATAKANA , japanese_text , - 1 , NULL , 0 ) ;
ok ( ret = = ret2 , " %s ret %d, expected value %d \n " , func_name , ret , ret2 ) ;
2003-11-22 01:00:53 +01:00
/* test buffer overflow */
SetLastError ( 0xdeadbeef ) ;
2012-06-04 22:53:55 +02:00
ret = func_ptr ( LCMAP_UPPERCASE ,
2003-11-22 01:00:53 +01:00
lower_case , - 1 , buf , 4 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
2012-06-04 22:53:55 +02:00
" %s should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d \n " , func_name , ret ) ;
2003-11-22 01:00:53 +01:00
2016-09-22 17:06:13 +02:00
/* KATAKANA LETTER GA (U+30AC) is converted into two half-width characters.
Thus , it requires two WCHARs . */
buf [ 0 ] = 0x30ac ;
SetLastError ( 0xdeadbeef ) ;
ret = func_ptr ( LCMAP_HALFWIDTH , buf , 1 , buf2 , 1 ) ;
2016-10-02 17:06:57 +02:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
2016-09-22 17:06:13 +02:00
" %s should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d \n " , func_name , ret ) ;
2018-07-12 16:30:28 +02:00
buf [ 0 ] = ' a ' ;
buf [ 1 ] = 0x30ac ;
ret = func_ptr ( LCMAP_HALFWIDTH | LCMAP_UPPERCASE , buf , 2 , buf2 , 0 ) ;
ok ( ret = = 3 , " %s ret %d, expected value 3 \n " , func_name , ret ) ;
SetLastError ( 0xdeadbeef ) ;
ret = func_ptr ( LCMAP_HALFWIDTH | LCMAP_UPPERCASE , buf , 2 , buf2 , 1 ) ;
2018-07-12 16:30:29 +02:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
2018-07-12 16:30:28 +02:00
" %s should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d \n " , func_name , ret ) ;
SetLastError ( 0xdeadbeef ) ;
ret = func_ptr ( LCMAP_HALFWIDTH | LCMAP_UPPERCASE , buf , 2 , buf2 , 2 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" %s should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d \n " , func_name , ret ) ;
ret = func_ptr ( LCMAP_HALFWIDTH | LCMAP_UPPERCASE , buf , 2 , buf2 , 3 ) ;
2018-07-12 16:30:29 +02:00
ok ( ret = = 3 , " %s ret %d, expected value 3 \n " , func_name , ret ) ;
2018-07-12 16:30:28 +02:00
ret = func_ptr ( LCMAP_HALFWIDTH | LCMAP_UPPERCASE , buf , 2 , buf2 , 4 ) ;
ok ( ret = = 3 , " %s ret %d, expected value 3 \n " , func_name , ret ) ;
2003-06-27 21:02:23 +02:00
/* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
lstrcpyW ( buf , lower_case ) ;
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_UPPERCASE , buf , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret = = lstrlenW ( lower_case ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
2003-06-27 21:02:23 +02:00
ret , GetLastError ( ) , lstrlenW ( lower_case ) + 1 ) ;
2012-06-04 22:53:55 +02:00
ok ( ! lstrcmpW ( buf , upper_case ) , " %s string compare mismatch \n " , func_name ) ;
2003-06-27 21:02:23 +02:00
lstrcpyW ( buf , upper_case ) ;
2018-06-22 19:50:38 +02:00
ret = func_ptr ( LCMAP_LOWERCASE , buf , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret = = lstrlenW ( upper_case ) + 1 , " %s ret %d, error %d, expected value %d \n " , func_name ,
2003-06-27 21:02:23 +02:00
ret , GetLastError ( ) , lstrlenW ( lower_case ) + 1 ) ;
2012-06-04 22:53:55 +02:00
ok ( ! lstrcmpW ( buf , lower_case ) , " %s string compare mismatch \n " , func_name ) ;
2003-09-18 00:40:07 +02:00
2003-06-27 21:02:23 +02:00
/* otherwise src == dst should fail */
SetLastError ( 0xdeadbeef ) ;
2012-06-04 22:53:55 +02:00
ret = func_ptr ( LCMAP_SORTKEY | LCMAP_UPPERCASE ,
2003-06-27 21:02:23 +02:00
buf , 10 , buf , sizeof ( buf ) ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS /* NT */ | |
2012-06-04 22:53:55 +02:00
GetLastError ( ) = = ERROR_INVALID_PARAMETER /* Win7+ */ ,
" %s unexpected error code %d \n " , func_name , GetLastError ( ) ) ;
ok ( ! ret , " %s src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail \n " , func_name ) ;
2003-06-27 21:02:23 +02:00
/* test whether '\0' is always appended */
2012-06-04 22:53:55 +02:00
ret = func_ptr ( LCMAP_SORTKEY ,
2003-06-27 21:02:23 +02:00
upper_case , - 1 , buf , sizeof ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret , " %s func_ptr must succeed \n " , func_name ) ;
ret2 = func_ptr ( LCMAP_SORTKEY ,
2003-06-27 21:02:23 +02:00
upper_case , lstrlenW ( upper_case ) , buf2 , sizeof ( buf2 ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret , " %s func_ptr must succeed \n " , func_name ) ;
ok ( ret = = ret2 , " %s lengths of sort keys must be equal \n " , func_name ) ;
ok ( ! lstrcmpA ( p_buf , p_buf2 ) , " %s sort keys must be equal \n " , func_name ) ;
2003-06-27 21:02:23 +02:00
/* test LCMAP_SORTKEY | NORM_IGNORECASE */
2012-06-04 22:53:55 +02:00
ret = func_ptr ( LCMAP_SORTKEY | NORM_IGNORECASE ,
2003-06-27 21:02:23 +02:00
upper_case , - 1 , buf , sizeof ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret , " %s func_ptr must succeed \n " , func_name ) ;
ret2 = func_ptr ( LCMAP_SORTKEY ,
2003-06-27 21:02:23 +02:00
lower_case , - 1 , buf2 , sizeof ( buf2 ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret2 , " %s func_ptr must succeed \n " , func_name ) ;
ok ( ret = = ret2 , " %s lengths of sort keys must be equal \n " , func_name ) ;
ok ( ! lstrcmpA ( p_buf , p_buf2 ) , " %s sort keys must be equal \n " , func_name ) ;
2003-06-27 21:02:23 +02:00
2009-09-01 12:19:35 +02:00
/* Don't test LCMAP_SORTKEY | NORM_IGNORENONSPACE, produces different
results from plain LCMAP_SORTKEY on Vista */
2003-06-30 23:06:12 +02:00
/* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
2012-06-04 22:53:55 +02:00
ret = func_ptr ( LCMAP_SORTKEY | NORM_IGNORESYMBOLS ,
2003-06-30 23:06:12 +02:00
lower_case , - 1 , buf , sizeof ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret , " %s func_ptr must succeed \n " , func_name ) ;
ret2 = func_ptr ( LCMAP_SORTKEY ,
2003-06-30 23:06:12 +02:00
symbols_stripped , - 1 , buf2 , sizeof ( buf2 ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret2 , " %s func_ptr must succeed \n " , func_name ) ;
ok ( ret = = ret2 , " %s lengths of sort keys must be equal \n " , func_name ) ;
ok ( ! lstrcmpA ( p_buf , p_buf2 ) , " %s sort keys must be equal \n " , func_name ) ;
2003-06-30 23:06:12 +02:00
2003-06-27 21:02:23 +02:00
/* test NORM_IGNORENONSPACE */
lstrcpyW ( buf , fooW ) ;
2018-06-22 19:50:38 +02:00
ret = func_ptr ( NORM_IGNORENONSPACE , lower_case , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret = = lstrlenW ( lower_case ) + 1 , " %s func_ptr should return %d, ret = %d \n " , func_name ,
lstrlenW ( lower_case ) + 1 , ret ) ;
ok ( ! lstrcmpW ( buf , lower_case ) , " %s string comparison mismatch \n " , func_name ) ;
2003-06-27 21:02:23 +02:00
/* test NORM_IGNORESYMBOLS */
lstrcpyW ( buf , fooW ) ;
2018-06-22 19:50:38 +02:00
ret = func_ptr ( NORM_IGNORESYMBOLS , lower_case , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ret = = lstrlenW ( symbols_stripped ) + 1 , " %s func_ptr should return %d, ret = %d \n " , func_name ,
lstrlenW ( symbols_stripped ) + 1 , ret ) ;
ok ( ! lstrcmpW ( buf , symbols_stripped ) , " %s string comparison mismatch \n " , func_name ) ;
2003-11-22 01:00:53 +01:00
2016-09-22 17:06:09 +02:00
/* test NORM_IGNORESYMBOLS | NORM_IGNORENONSPACE */
lstrcpyW ( buf , fooW ) ;
2018-06-22 19:50:38 +02:00
ret = func_ptr ( NORM_IGNORESYMBOLS | NORM_IGNORENONSPACE , lower_case , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2016-09-22 17:06:09 +02:00
ok ( ret = = lstrlenW ( symbols_stripped ) + 1 , " %s func_ptr should return %d, ret = %d \n " , func_name ,
lstrlenW ( symbols_stripped ) + 1 , ret ) ;
ok ( ! lstrcmpW ( buf , symbols_stripped ) , " %s string comparison mismatch \n " , func_name ) ;
2003-11-22 01:00:53 +01:00
/* test srclen = 0 */
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
ret = func_ptr ( 0 , upper_case , 0 , buf , ARRAY_SIZE ( buf ) ) ;
2012-06-04 22:53:55 +02:00
ok ( ! ret , " %s func_ptr should fail with srclen = 0 \n " , func_name ) ;
2003-11-22 01:00:53 +01:00
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2012-06-04 22:53:55 +02:00
" %s unexpected error code %d \n " , func_name , GetLastError ( ) ) ;
}
static INT LCMapStringW_wrapper ( DWORD flags , LPCWSTR src , INT srclen , LPWSTR dst , INT dstlen )
{
return LCMapStringW ( LOCALE_USER_DEFAULT , flags , src , srclen , dst , dstlen ) ;
}
static void test_LCMapStringW ( void )
{
2012-06-26 21:13:06 +02:00
int ret ;
WCHAR buf [ 256 ] ;
2012-06-04 22:53:55 +02:00
trace ( " testing LCMapStringW \n " ) ;
2012-06-26 21:13:06 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
ret = LCMapStringW ( ( LCID ) - 1 , LCMAP_LOWERCASE , upper_case , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-06-26 21:13:06 +02:00
todo_wine {
ok ( ! ret , " LCMapStringW should fail with bad lcid \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " unexpected error code %d \n " , GetLastError ( ) ) ;
}
2012-06-04 22:53:55 +02:00
test_lcmapstring_unicode ( LCMapStringW_wrapper , " LCMapStringW: " ) ;
}
static INT LCMapStringEx_wrapper ( DWORD flags , LPCWSTR src , INT srclen , LPWSTR dst , INT dstlen )
{
return pLCMapStringEx ( LOCALE_NAME_USER_DEFAULT , flags , src , srclen , dst , dstlen , NULL , NULL , 0 ) ;
}
static void test_LCMapStringEx ( void )
{
int ret ;
2012-08-15 15:42:52 +02:00
WCHAR buf [ 256 ] ;
2012-06-04 22:53:55 +02:00
if ( ! pLCMapStringEx )
{
2012-06-26 21:13:06 +02:00
win_skip ( " LCMapStringEx not available \n " ) ;
2012-06-04 22:53:55 +02:00
return ;
}
trace ( " testing LCMapStringEx \n " ) ;
2012-06-26 21:13:06 +02:00
SetLastError ( 0xdeadbeef ) ;
2017-01-17 11:51:44 +01:00
ret = pLCMapStringEx ( invalidW , LCMAP_LOWERCASE ,
2018-06-22 19:50:38 +02:00
upper_case , - 1 , buf , ARRAY_SIZE ( buf ) , NULL , NULL , 0 ) ;
2012-06-26 21:13:06 +02:00
todo_wine {
ok ( ! ret , " LCMapStringEx should fail with bad locale name \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " unexpected error code %d \n " , GetLastError ( ) ) ;
}
2012-06-04 22:53:55 +02:00
/* test reserved parameters */
ret = pLCMapStringEx ( LOCALE_NAME_USER_DEFAULT , LCMAP_LOWERCASE ,
2018-06-22 19:50:38 +02:00
upper_case , - 1 , buf , ARRAY_SIZE ( buf ) , NULL , NULL , 1 ) ;
2012-06-04 22:53:55 +02:00
ok ( ret = = lstrlenW ( upper_case ) + 1 , " ret %d, error %d, expected value %d \n " ,
ret , GetLastError ( ) , lstrlenW ( upper_case ) + 1 ) ;
ok ( ! lstrcmpW ( buf , lower_case ) , " string compare mismatch \n " ) ;
ret = pLCMapStringEx ( LOCALE_NAME_USER_DEFAULT , LCMAP_LOWERCASE ,
2018-06-22 19:50:38 +02:00
upper_case , - 1 , buf , ARRAY_SIZE ( buf ) , NULL , ( void * ) 1 , 0 ) ;
2012-06-04 22:53:55 +02:00
ok ( ret = = lstrlenW ( upper_case ) + 1 , " ret %d, error %d, expected value %d \n " ,
ret , GetLastError ( ) , lstrlenW ( upper_case ) + 1 ) ;
ok ( ! lstrcmpW ( buf , lower_case ) , " string compare mismatch \n " ) ;
/* crashes on native */
if ( 0 )
ret = pLCMapStringEx ( LOCALE_NAME_USER_DEFAULT , LCMAP_LOWERCASE ,
2018-06-22 19:50:38 +02:00
upper_case , - 1 , buf , ARRAY_SIZE ( buf ) , ( void * ) 1 , NULL , 0 ) ;
2012-06-04 22:53:55 +02:00
test_lcmapstring_unicode ( LCMapStringEx_wrapper , " LCMapStringEx: " ) ;
2003-11-22 01:00:53 +01:00
}
2012-07-26 09:20:46 +02:00
struct neutralsublang_name_t {
WCHAR name [ 3 ] ;
2017-01-24 21:44:05 +01:00
WCHAR sname [ 16 ] ;
2012-07-26 09:20:46 +02:00
LCID lcid ;
} ;
static const struct neutralsublang_name_t neutralsublang_names [ ] = {
2017-01-24 21:44:05 +01:00
{ { ' a ' , ' r ' , 0 } , { ' a ' , ' r ' , ' - ' , ' S ' , ' A ' , 0 } , MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_SAUDI_ARABIA ) , SORT_DEFAULT ) } ,
{ { ' a ' , ' z ' , 0 } , { ' a ' , ' z ' , ' - ' , ' L ' , ' a ' , ' t ' , ' n ' , ' - ' , ' A ' , ' Z ' , 0 } , MAKELCID ( MAKELANGID ( LANG_AZERI , SUBLANG_AZERI_LATIN ) , SORT_DEFAULT ) } ,
{ { ' d ' , ' e ' , 0 } , { ' d ' , ' e ' , ' - ' , ' D ' , ' E ' , 0 } , MAKELCID ( MAKELANGID ( LANG_GERMAN , SUBLANG_GERMAN ) , SORT_DEFAULT ) } ,
{ { ' e ' , ' n ' , 0 } , { ' e ' , ' n ' , ' - ' , ' U ' , ' S ' , 0 } , MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) } ,
{ { ' e ' , ' s ' , 0 } , { ' e ' , ' s ' , ' - ' , ' E ' , ' S ' , 0 } , MAKELCID ( MAKELANGID ( LANG_SPANISH , SUBLANG_SPANISH_MODERN ) , SORT_DEFAULT ) } ,
{ { ' g ' , ' a ' , 0 } , { ' g ' , ' a ' , ' - ' , ' I ' , ' E ' , 0 } , MAKELCID ( MAKELANGID ( LANG_IRISH , SUBLANG_IRISH_IRELAND ) , SORT_DEFAULT ) } ,
{ { ' i ' , ' t ' , 0 } , { ' i ' , ' t ' , ' - ' , ' I ' , ' T ' , 0 } , MAKELCID ( MAKELANGID ( LANG_ITALIAN , SUBLANG_ITALIAN ) , SORT_DEFAULT ) } ,
{ { ' m ' , ' s ' , 0 } , { ' m ' , ' s ' , ' - ' , ' M ' , ' Y ' , 0 } , MAKELCID ( MAKELANGID ( LANG_MALAY , SUBLANG_MALAY_MALAYSIA ) , SORT_DEFAULT ) } ,
{ { ' n ' , ' l ' , 0 } , { ' n ' , ' l ' , ' - ' , ' N ' , ' L ' , 0 } , MAKELCID ( MAKELANGID ( LANG_DUTCH , SUBLANG_DUTCH ) , SORT_DEFAULT ) } ,
{ { ' p ' , ' t ' , 0 } , { ' p ' , ' t ' , ' - ' , ' B ' , ' R ' , 0 } , MAKELCID ( MAKELANGID ( LANG_PORTUGUESE , SUBLANG_PORTUGUESE_BRAZILIAN ) , SORT_DEFAULT ) } ,
2021-02-04 00:48:36 +01:00
{ { ' s ' , ' r ' , 0 } , { ' s ' , ' r ' , ' - ' , ' L ' , ' a ' , ' t ' , ' n ' , ' - ' , ' R ' , ' S ' , 0 } , MAKELCID ( MAKELANGID ( LANG_SERBIAN , SUBLANG_SERBIAN_SERBIA_LATIN ) , SORT_DEFAULT ) } ,
2017-01-24 21:44:05 +01:00
{ { ' s ' , ' v ' , 0 } , { ' s ' , ' v ' , ' - ' , ' S ' , ' E ' , 0 } , MAKELCID ( MAKELANGID ( LANG_SWEDISH , SUBLANG_SWEDISH ) , SORT_DEFAULT ) } ,
{ { ' u ' , ' z ' , 0 } , { ' u ' , ' z ' , ' - ' , ' L ' , ' a ' , ' t ' , ' n ' , ' - ' , ' U ' , ' Z ' , 0 } , MAKELCID ( MAKELANGID ( LANG_UZBEK , SUBLANG_UZBEK_LATIN ) , SORT_DEFAULT ) } ,
{ { ' z ' , ' h ' , 0 } , { ' z ' , ' h ' , ' - ' , ' C ' , ' N ' , 0 } , MAKELCID ( MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_SIMPLIFIED ) , SORT_DEFAULT ) } ,
2012-07-26 09:20:46 +02:00
{ { 0 } }
} ;
static void test_LocaleNameToLCID ( void )
2012-03-18 19:28:41 +01:00
{
2019-11-19 10:08:27 +01:00
LCID lcid , expect ;
NTSTATUS status ;
2012-03-18 19:28:41 +01:00
INT ret ;
WCHAR buffer [ LOCALE_NAME_MAX_LENGTH ] ;
2019-11-19 10:08:27 +01:00
const struct neutralsublang_name_t * ptr ;
2012-07-26 09:20:46 +02:00
static const WCHAR enW [ ] = { ' e ' , ' n ' , 0 } ;
2017-01-24 21:44:11 +01:00
static const WCHAR esesW [ ] = { ' e ' , ' s ' , ' - ' , ' e ' , ' s ' , 0 } ;
2017-02-03 05:21:04 +01:00
static const WCHAR zhHansW [ ] = { ' z ' , ' h ' , ' - ' , ' H ' , ' a ' , ' n ' , ' s ' , 0 } ;
static const WCHAR zhhansW [ ] = { ' z ' , ' h ' , ' - ' , ' h ' , ' a ' , ' n ' , ' s ' , 0 } ;
static const WCHAR zhHantW [ ] = { ' z ' , ' h ' , ' - ' , ' H ' , ' a ' , ' n ' , ' t ' , 0 } ;
static const WCHAR zhhantW [ ] = { ' z ' , ' h ' , ' - ' , ' h ' , ' a ' , ' n ' , ' t ' , 0 } ;
static const WCHAR zhcnW [ ] = { ' z ' , ' h ' , ' - ' , ' C ' , ' N ' , 0 } ;
static const WCHAR zhhkW [ ] = { ' z ' , ' h ' , ' - ' , ' H ' , ' K ' , 0 } ;
2012-03-18 19:28:41 +01:00
if ( ! pLocaleNameToLCID )
{
win_skip ( " LocaleNameToLCID not available \n " ) ;
return ;
}
/* special cases */
buffer [ 0 ] = 0 ;
2012-08-17 00:46:31 +02:00
SetLastError ( 0xdeadbeef ) ;
2012-03-18 19:28:41 +01:00
lcid = pLocaleNameToLCID ( LOCALE_NAME_USER_DEFAULT , 0 ) ;
ok ( lcid = = GetUserDefaultLCID ( ) | | broken ( GetLastError ( ) = = ERROR_INVALID_PARAMETER /* Vista */ ) ,
2012-08-17 00:46:31 +02:00
" Expected lcid == %08x, got %08x, error %d \n " , GetUserDefaultLCID ( ) , lcid , GetLastError ( ) ) ;
2012-03-18 19:28:41 +01:00
ret = pLCIDToLocaleName ( lcid , buffer , LOCALE_NAME_MAX_LENGTH , 0 ) ;
ok ( ret > 0 , " Expected ret > 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
trace ( " %08x, %s \n " , lcid , wine_dbgstr_w ( buffer ) ) ;
buffer [ 0 ] = 0 ;
2012-08-17 00:46:31 +02:00
SetLastError ( 0xdeadbeef ) ;
2012-03-18 19:28:41 +01:00
lcid = pLocaleNameToLCID ( LOCALE_NAME_SYSTEM_DEFAULT , 0 ) ;
2012-08-17 00:46:31 +02:00
ok ( ! lcid & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected lcid == 0, got %08x, error %d \n " , lcid , GetLastError ( ) ) ;
2012-03-18 19:28:41 +01:00
ret = pLCIDToLocaleName ( lcid , buffer , LOCALE_NAME_MAX_LENGTH , 0 ) ;
ok ( ret > 0 , " Expected ret > 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
trace ( " %08x, %s \n " , lcid , wine_dbgstr_w ( buffer ) ) ;
buffer [ 0 ] = 0 ;
2012-08-17 00:46:31 +02:00
SetLastError ( 0xdeadbeef ) ;
2012-03-18 19:28:41 +01:00
lcid = pLocaleNameToLCID ( LOCALE_NAME_INVARIANT , 0 ) ;
2015-06-09 23:18:47 +02:00
ok ( lcid = = 0x7F , " Expected lcid = 0x7F, got %08x, error %d \n " , lcid , GetLastError ( ) ) ;
2012-03-18 19:28:41 +01:00
ret = pLCIDToLocaleName ( lcid , buffer , LOCALE_NAME_MAX_LENGTH , 0 ) ;
2015-08-26 08:08:04 +02:00
ok ( ret > 0 , " Expected ret > 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2012-03-18 19:28:41 +01:00
trace ( " %08x, %s \n " , lcid , wine_dbgstr_w ( buffer ) ) ;
2012-07-26 09:20:46 +02:00
2012-08-15 15:42:52 +02:00
/* bad name */
2012-08-17 00:46:31 +02:00
SetLastError ( 0xdeadbeef ) ;
2017-01-17 11:51:44 +01:00
lcid = pLocaleNameToLCID ( invalidW , 0 ) ;
2012-08-17 00:46:31 +02:00
ok ( ! lcid & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2016-06-22 23:35:06 +02:00
" Expected lcid == 0, got %08x, error %d \n " , lcid , GetLastError ( ) ) ;
2012-08-15 15:42:52 +02:00
2017-01-24 21:44:11 +01:00
/* lower-case */
lcid = pLocaleNameToLCID ( esesW , 0 ) ;
ok ( lcid = = MAKELCID ( MAKELANGID ( LANG_SPANISH , SUBLANG_SPANISH_MODERN ) , SORT_DEFAULT ) , " Got wrong lcid for es-es: 0x%x \n " , lcid ) ;
2012-07-26 09:20:46 +02:00
/* english neutral name */
2019-11-19 10:10:18 +01:00
lcid = pLocaleNameToLCID ( enW , LOCALE_ALLOW_NEUTRAL_NAMES ) ;
ok ( lcid = = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_NEUTRAL ) , SORT_DEFAULT ) | |
broken ( lcid = = 0 ) /* Vista */ , " got 0x%04x \n " , lcid ) ;
2012-07-26 09:20:46 +02:00
lcid = pLocaleNameToLCID ( enW , 0 ) ;
ok ( lcid = = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) | |
broken ( lcid = = 0 ) /* Vista */ , " got 0x%04x \n " , lcid ) ;
if ( lcid )
{
2019-11-19 10:08:27 +01:00
for ( ptr = neutralsublang_names ; * ptr - > name ; ptr + + )
2012-07-26 09:20:46 +02:00
{
lcid = pLocaleNameToLCID ( ptr - > name , 0 ) ;
2021-02-04 00:48:35 +01:00
ok ( lcid = = ptr - > lcid , " %s: got wrong lcid 0x%04x, expected 0x%04x \n " ,
wine_dbgstr_w ( ptr - > name ) , lcid , ptr - > lcid ) ;
2012-08-26 07:53:23 +02:00
* buffer = 0 ;
2018-06-22 19:50:38 +02:00
ret = pLCIDToLocaleName ( lcid , buffer , ARRAY_SIZE ( buffer ) , 0 ) ;
2012-08-26 07:53:23 +02:00
ok ( ret > 0 , " %s: got %d \n " , wine_dbgstr_w ( ptr - > name ) , ret ) ;
2017-01-24 21:44:05 +01:00
ok ( ! lstrcmpW ( ptr - > sname , buffer ) , " %s: got wrong locale name %s \n " ,
2012-08-26 07:53:23 +02:00
wine_dbgstr_w ( ptr - > name ) , wine_dbgstr_w ( buffer ) ) ;
2012-07-26 09:20:46 +02:00
}
2017-02-03 05:21:04 +01:00
2017-11-01 15:26:38 +01:00
/* zh-Hant has LCID 0x7c04, but LocaleNameToLCID actually returns 0x0c04, which is the LCID of zh-HK */
2017-02-03 05:21:04 +01:00
lcid = pLocaleNameToLCID ( zhHantW , 0 ) ;
2017-11-13 19:43:13 +01:00
ok ( lcid = = MAKELCID ( MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_HONGKONG ) , SORT_DEFAULT ) ,
2017-02-03 05:21:04 +01:00
" %s: got wrong lcid 0x%04x \n " , wine_dbgstr_w ( zhHantW ) , lcid ) ;
2018-06-22 19:50:38 +02:00
ret = pLCIDToLocaleName ( lcid , buffer , ARRAY_SIZE ( buffer ) , 0 ) ;
2017-02-03 05:21:04 +01:00
ok ( ret > 0 , " %s: got %d \n " , wine_dbgstr_w ( zhHantW ) , ret ) ;
2017-11-13 19:43:13 +01:00
ok ( ! lstrcmpW ( zhhkW , buffer ) , " %s: got wrong locale name %s \n " ,
2017-11-01 15:26:38 +01:00
wine_dbgstr_w ( zhHantW ) , wine_dbgstr_w ( buffer ) ) ;
/* check that 0x7c04 also works and is mapped to zh-HK */
2018-06-22 19:50:38 +02:00
ret = pLCIDToLocaleName ( MAKELANGID ( LANG_CHINESE_TRADITIONAL , SUBLANG_CHINESE_TRADITIONAL ) ,
buffer , ARRAY_SIZE ( buffer ) , 0 ) ;
2019-11-19 09:58:20 +01:00
ok ( ret > 0 , " %s: got %d \n " , wine_dbgstr_w ( zhHantW ) , ret ) ;
2017-11-13 19:43:13 +01:00
ok ( ! lstrcmpW ( zhhkW , buffer ) , " %s: got wrong locale name %s \n " ,
2017-02-03 05:21:04 +01:00
wine_dbgstr_w ( zhHantW ) , wine_dbgstr_w ( buffer ) ) ;
/* zh-hant */
lcid = pLocaleNameToLCID ( zhhantW , 0 ) ;
2017-11-13 19:43:13 +01:00
ok ( lcid = = MAKELCID ( MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_HONGKONG ) , SORT_DEFAULT ) ,
" %s: got wrong lcid 0x%04x \n " , wine_dbgstr_w ( zhhantW ) , lcid ) ;
2018-06-22 19:50:38 +02:00
ret = pLCIDToLocaleName ( lcid , buffer , ARRAY_SIZE ( buffer ) , 0 ) ;
2017-02-03 05:21:04 +01:00
ok ( ret > 0 , " %s: got %d \n " , wine_dbgstr_w ( zhhantW ) , ret ) ;
2017-11-13 19:43:13 +01:00
ok ( ! lstrcmpW ( zhhkW , buffer ) , " %s: got wrong locale name %s \n " ,
2017-02-03 05:21:04 +01:00
wine_dbgstr_w ( zhhantW ) , wine_dbgstr_w ( buffer ) ) ;
2017-11-01 15:26:38 +01:00
/* zh-Hans has LCID 0x0004, but LocaleNameToLCID actually returns 0x0804, which is the LCID of zh-CN */
2017-02-03 05:21:04 +01:00
lcid = pLocaleNameToLCID ( zhHansW , 0 ) ;
2017-11-01 15:26:38 +01:00
/* check that LocaleNameToLCID actually returns 0x0804 */
2017-11-13 19:43:13 +01:00
ok ( lcid = = MAKELCID ( MAKELANGID ( LANG_CHINESE_SIMPLIFIED , SUBLANG_CHINESE_SIMPLIFIED ) , SORT_DEFAULT ) ,
2017-02-03 05:21:04 +01:00
" %s: got wrong lcid 0x%04x \n " , wine_dbgstr_w ( zhHansW ) , lcid ) ;
2018-06-22 19:50:38 +02:00
ret = pLCIDToLocaleName ( lcid , buffer , ARRAY_SIZE ( buffer ) , 0 ) ;
2017-02-03 05:21:04 +01:00
ok ( ret > 0 , " %s: got %d \n " , wine_dbgstr_w ( zhHansW ) , ret ) ;
2017-11-13 19:43:13 +01:00
ok ( ! lstrcmpW ( zhcnW , buffer ) , " %s: got wrong locale name %s \n " ,
2017-02-03 05:21:04 +01:00
wine_dbgstr_w ( zhHansW ) , wine_dbgstr_w ( buffer ) ) ;
2017-11-01 15:26:38 +01:00
/* check that 0x0004 also works and is mapped to zh-CN */
2018-06-22 19:50:38 +02:00
ret = pLCIDToLocaleName ( MAKELANGID ( LANG_CHINESE , SUBLANG_NEUTRAL ) , buffer , ARRAY_SIZE ( buffer ) , 0 ) ;
2017-11-01 15:26:38 +01:00
ok ( ret > 0 , " %s: got %d \n " , wine_dbgstr_w ( zhHansW ) , ret ) ;
ok ( ! lstrcmpW ( zhcnW , buffer ) , " %s: got wrong locale name %s \n " ,
wine_dbgstr_w ( zhHansW ) , wine_dbgstr_w ( buffer ) ) ;
2017-02-03 05:21:04 +01:00
/* zh-hans */
lcid = pLocaleNameToLCID ( zhhansW , 0 ) ;
2017-11-13 19:43:13 +01:00
ok ( lcid = = MAKELCID ( MAKELANGID ( LANG_CHINESE_SIMPLIFIED , SUBLANG_CHINESE_SIMPLIFIED ) , SORT_DEFAULT ) ,
" %s: got wrong lcid 0x%04x \n " , wine_dbgstr_w ( zhhansW ) , lcid ) ;
2018-06-22 19:50:38 +02:00
ret = pLCIDToLocaleName ( lcid , buffer , ARRAY_SIZE ( buffer ) , 0 ) ;
2017-02-03 05:21:04 +01:00
ok ( ret > 0 , " %s: got %d \n " , wine_dbgstr_w ( zhhansW ) , ret ) ;
2017-11-13 19:43:13 +01:00
ok ( ! lstrcmpW ( zhcnW , buffer ) , " %s: got wrong locale name %s \n " ,
2017-02-03 05:21:04 +01:00
wine_dbgstr_w ( zhhansW ) , wine_dbgstr_w ( buffer ) ) ;
2012-07-26 09:20:46 +02:00
}
2019-11-19 10:08:27 +01:00
if ( pRtlLocaleNameToLcid )
{
status = pRtlLocaleNameToLcid ( LOCALE_NAME_USER_DEFAULT , & lcid , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_1 , " wrong error %x \n " , status ) ;
status = pRtlLocaleNameToLcid ( LOCALE_NAME_SYSTEM_DEFAULT , & lcid , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_1 , " wrong error %x \n " , status ) ;
status = pRtlLocaleNameToLcid ( invalidW , & lcid , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_1 , " wrong error %x \n " , status ) ;
lcid = 0 ;
status = pRtlLocaleNameToLcid ( LOCALE_NAME_INVARIANT , & lcid , 0 ) ;
ok ( ! status , " failed error %x \n " , status ) ;
ok ( lcid = = LANG_INVARIANT , " got %08x \n " , lcid ) ;
lcid = 0 ;
status = pRtlLocaleNameToLcid ( localeW , & lcid , 0 ) ;
ok ( ! status , " failed error %x \n " , status ) ;
ok ( lcid = = MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , " got %08x \n " , lcid ) ;
lcid = 0 ;
status = pRtlLocaleNameToLcid ( esesW , & lcid , 0 ) ;
ok ( ! status , " failed error %x \n " , status ) ;
ok ( lcid = = MAKELANGID ( LANG_SPANISH , SUBLANG_SPANISH_MODERN ) , " got %08x \n " , lcid ) ;
lcid = 0 ;
status = pRtlLocaleNameToLcid ( enW , & lcid , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_1 , " wrong error %x \n " , status ) ;
status = pRtlLocaleNameToLcid ( enW , & lcid , 1 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_1 , " wrong error %x \n " , status ) ;
status = pRtlLocaleNameToLcid ( enW , & lcid , 2 ) ;
ok ( ! status , " failed error %x \n " , status ) ;
ok ( lcid = = MAKELANGID ( LANG_ENGLISH , SUBLANG_NEUTRAL ) , " got %08x \n " , lcid ) ;
status = pRtlLocaleNameToLcid ( L " en-RR " , & lcid , 2 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_1 , " wrong error %x \n " , status ) ;
status = pRtlLocaleNameToLcid ( L " en-Latn-RR " , & lcid , 2 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_1 , " wrong error %x \n " , status ) ;
for ( ptr = neutralsublang_names ; * ptr - > name ; ptr + + )
{
switch ( LANGIDFROMLCID ( ptr - > lcid ) )
{
case MAKELANGID ( LANG_SERBIAN , SUBLANG_SERBIAN_SERBIA_LATIN ) : expect = LANG_SERBIAN_NEUTRAL ; break ;
case MAKELANGID ( LANG_SERBIAN , SUBLANG_SERBIAN_SERBIA_CYRILLIC ) : expect = 0x6c1a ; break ;
case MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_SIMPLIFIED ) : expect = 0x7804 ; break ;
case MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_HONGKONG ) : expect = LANG_CHINESE_TRADITIONAL ; break ;
default : expect = MAKELANGID ( PRIMARYLANGID ( ptr - > lcid ) , SUBLANG_NEUTRAL ) ; break ;
}
status = pRtlLocaleNameToLcid ( ptr - > name , & lcid , 2 ) ;
ok ( ! status | | broken ( ptr - > lcid = = MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_SIMPLIFIED ) ) , /* vista */
" %s failed error %x \n " , wine_dbgstr_w ( ptr - > name ) , status ) ;
if ( ! status ) ok ( lcid = = expect , " %s: got wrong lcid 0x%04x, expected 0x%04x \n " ,
wine_dbgstr_w ( ptr - > name ) , lcid , expect ) ;
status = pRtlLocaleNameToLcid ( ptr - > sname , & lcid , 0 ) ;
ok ( ! status | | broken ( ptr - > lcid = = MAKELANGID ( LANG_SERBIAN , SUBLANG_SERBIAN_SERBIA_LATIN ) ) , /* vista */
" %s failed error %x \n " , wine_dbgstr_w ( ptr - > name ) , status ) ;
if ( ! status ) ok ( lcid = = ptr - > lcid , " %s: got wrong lcid 0x%04x, expected 0x%04x \n " ,
wine_dbgstr_w ( ptr - > name ) , lcid , ptr - > lcid ) ;
}
}
else win_skip ( " RtlLocaleNameToLcid not available \n " ) ;
2012-03-18 19:28:41 +01:00
}
2005-06-02 12:30:57 +02:00
/* this requires collation table patch to make it MS compatible */
2008-09-17 04:38:51 +02:00
static const char * const strings_sorted [ ] =
2003-11-22 01:00:53 +01:00
{
" ' " ,
" - " ,
" ! " ,
" \" " ,
" . " ,
" : " ,
" \\ " ,
" _ " ,
" ` " ,
" { " ,
" } " ,
" + " ,
" 0 " ,
" 1 " ,
" 2 " ,
" 3 " ,
" 4 " ,
" 5 " ,
" 6 " ,
" 7 " ,
" 8 " ,
" 9 " ,
" a " ,
" A " ,
" b " ,
" B " ,
" c " ,
" C "
} ;
2008-09-17 04:38:51 +02:00
static const char * const strings [ ] =
2003-11-22 01:00:53 +01:00
{
" C " ,
" \" " ,
" 9 " ,
" ' " ,
" } " ,
" - " ,
" 7 " ,
" + " ,
" ` " ,
" 1 " ,
" a " ,
" 5 " ,
" \\ " ,
" 8 " ,
" B " ,
" 3 " ,
" _ " ,
" 6 " ,
" { " ,
" 2 " ,
" c " ,
" 4 " ,
" ! " ,
" 0 " ,
" A " ,
" : " ,
" b " ,
" . "
} ;
static int compare_string1 ( const void * e1 , const void * e2 )
{
2006-12-09 19:04:14 +01:00
const char * s1 = * ( const char * const * ) e1 ;
const char * s2 = * ( const char * const * ) e2 ;
2003-11-22 01:00:53 +01:00
return lstrcmpA ( s1 , s2 ) ;
}
static int compare_string2 ( const void * e1 , const void * e2 )
{
2006-12-09 19:04:14 +01:00
const char * s1 = * ( const char * const * ) e1 ;
const char * s2 = * ( const char * const * ) e2 ;
2003-11-22 01:00:53 +01:00
return CompareStringA ( 0 , 0 , s1 , - 1 , s2 , - 1 ) - 2 ;
}
static int compare_string3 ( const void * e1 , const void * e2 )
{
2006-12-09 19:04:14 +01:00
const char * s1 = * ( const char * const * ) e1 ;
const char * s2 = * ( const char * const * ) e2 ;
2003-11-22 01:00:53 +01:00
char key1 [ 256 ] , key2 [ 256 ] ;
LCMapStringA ( 0 , LCMAP_SORTKEY , s1 , - 1 , key1 , sizeof ( key1 ) ) ;
LCMapStringA ( 0 , LCMAP_SORTKEY , s2 , - 1 , key2 , sizeof ( key2 ) ) ;
return strcmp ( key1 , key2 ) ;
2003-06-27 21:02:23 +02:00
}
2002-05-29 02:30:32 +02:00
2003-11-22 01:00:53 +01:00
static void test_sorting ( void )
{
char buf [ 256 ] ;
char * * str_buf = ( char * * ) buf ;
int i ;
assert ( sizeof ( buf ) > = sizeof ( strings ) ) ;
2021-08-17 17:32:50 +02:00
/* this requires the collation table patch to make it MS compatible */
if ( strcmp ( winetest_platform , " wine " ) = = 0 )
{
skip ( " in Wine due to the lack of a compatible collation table \n " ) ;
return ;
}
2003-11-22 01:00:53 +01:00
/* 1. sort using lstrcmpA */
memcpy ( buf , strings , sizeof ( strings ) ) ;
2018-06-22 19:50:38 +02:00
qsort ( buf , ARRAY_SIZE ( strings ) , sizeof ( strings [ 0 ] ) , compare_string1 ) ;
for ( i = 0 ; i < ARRAY_SIZE ( strings ) ; i + + )
2003-11-22 01:00:53 +01:00
{
ok ( ! strcmp ( strings_sorted [ i ] , str_buf [ i ] ) ,
" qsort using lstrcmpA failed for element %d \n " , i ) ;
}
/* 2. sort using CompareStringA */
memcpy ( buf , strings , sizeof ( strings ) ) ;
2018-06-22 19:50:38 +02:00
qsort ( buf , ARRAY_SIZE ( strings ) , sizeof ( strings [ 0 ] ) , compare_string2 ) ;
for ( i = 0 ; i < ARRAY_SIZE ( strings ) ; i + + )
2003-11-22 01:00:53 +01:00
{
ok ( ! strcmp ( strings_sorted [ i ] , str_buf [ i ] ) ,
" qsort using CompareStringA failed for element %d \n " , i ) ;
}
/* 3. sort using sort keys */
memcpy ( buf , strings , sizeof ( strings ) ) ;
2018-06-22 19:50:38 +02:00
qsort ( buf , ARRAY_SIZE ( strings ) , sizeof ( strings [ 0 ] ) , compare_string3 ) ;
for ( i = 0 ; i < ARRAY_SIZE ( strings ) ; i + + )
2003-11-22 01:00:53 +01:00
{
ok ( ! strcmp ( strings_sorted [ i ] , str_buf [ i ] ) ,
" qsort using sort keys failed for element %d \n " , i ) ;
}
}
static void test_FoldStringA ( void )
2003-10-24 02:26:18 +02:00
{
2009-09-01 12:19:35 +02:00
int ret , i , j ;
BOOL is_special ;
2003-10-24 02:26:18 +02:00
char src [ 256 ] , dst [ 256 ] ;
static const char digits_src [ ] = { 0xB9 , 0xB2 , 0xB3 , ' \0 ' } ;
static const char digits_dst [ ] = { ' 1 ' , ' 2 ' , ' 3 ' , ' \0 ' } ;
static const char composite_src [ ] =
{
0x8a , 0x8e , 0x9a , 0x9e , 0x9f , 0xc0 , 0xc1 , 0xc2 ,
0xc3 , 0xc4 , 0xc5 , 0xc7 , 0xc8 , 0xc9 , 0xca , 0xcb ,
0xcc , 0xcd , 0xce , 0xcf , 0xd1 , 0xd2 , 0xd3 , 0xd4 ,
0xd5 , 0xd6 , 0xd8 , 0xd9 , 0xda , 0xdb , 0xdc , 0xdd ,
0xe0 , 0xe1 , 0xe2 , 0xe3 , 0xe4 , 0xe5 , 0xe7 , 0xe8 ,
0xe9 , 0xea , 0xeb , 0xec , 0xed , 0xee , 0xef , 0xf1 ,
0xf2 , 0xf3 , 0xf4 , 0xf5 , 0xf6 , 0xf8 , 0xf9 , 0xfa ,
0xfb , 0xfc , 0xfd , 0xff , ' \0 '
} ;
static const char composite_dst [ ] =
{
0x53 , 0x3f , 0x5a , 0x3f , 0x73 , 0x3f , 0x7a , 0x3f ,
0x59 , 0xa8 , 0x41 , 0x60 , 0x41 , 0xb4 , 0x41 , 0x5e ,
0x41 , 0x7e , 0x41 , 0xa8 , 0x41 , 0xb0 , 0x43 , 0xb8 ,
0x45 , 0x60 , 0x45 , 0xb4 , 0x45 , 0x5e , 0x45 , 0xa8 ,
0x49 , 0x60 , 0x49 , 0xb4 , 0x49 , 0x5e , 0x49 , 0xa8 ,
0x4e , 0x7e , 0x4f , 0x60 , 0x4f , 0xb4 , 0x4f , 0x5e ,
0x4f , 0x7e , 0x4f , 0xa8 , 0x4f , 0x3f , 0x55 , 0x60 ,
0x55 , 0xb4 , 0x55 , 0x5e , 0x55 , 0xa8 , 0x59 , 0xb4 ,
0x61 , 0x60 , 0x61 , 0xb4 , 0x61 , 0x5e , 0x61 , 0x7e ,
0x61 , 0xa8 , 0x61 , 0xb0 , 0x63 , 0xb8 , 0x65 , 0x60 ,
0x65 , 0xb4 , 0x65 , 0x5e , 0x65 , 0xa8 , 0x69 , 0x60 ,
0x69 , 0xb4 , 0x69 , 0x5e , 0x69 , 0xa8 , 0x6e , 0x7e ,
0x6f , 0x60 , 0x6f , 0xb4 , 0x6f , 0x5e , 0x6f , 0x7e ,
0x6f , 0xa8 , 0x6f , 0x3f , 0x75 , 0x60 , 0x75 , 0xb4 ,
0x75 , 0x5e , 0x75 , 0xa8 , 0x79 , 0xb4 , 0x79 , 0xa8 , ' \0 '
} ;
2009-09-01 12:19:35 +02:00
static const char composite_dst_alt [ ] =
{
0x53 , 0x3f , 0x5a , 0x3f , 0x73 , 0x3f , 0x7a , 0x3f ,
0x59 , 0xa8 , 0x41 , 0x60 , 0x41 , 0xb4 , 0x41 , 0x5e ,
0x41 , 0x7e , 0x41 , 0xa8 , 0x41 , 0xb0 , 0x43 , 0xb8 ,
0x45 , 0x60 , 0x45 , 0xb4 , 0x45 , 0x5e , 0x45 , 0xa8 ,
0x49 , 0x60 , 0x49 , 0xb4 , 0x49 , 0x5e , 0x49 , 0xa8 ,
0x4e , 0x7e , 0x4f , 0x60 , 0x4f , 0xb4 , 0x4f , 0x5e ,
0x4f , 0x7e , 0x4f , 0xa8 , 0xd8 , 0x55 , 0x60 , 0x55 ,
0xb4 , 0x55 , 0x5e , 0x55 , 0xa8 , 0x59 , 0xb4 , 0x61 ,
0x60 , 0x61 , 0xb4 , 0x61 , 0x5e , 0x61 , 0x7e , 0x61 ,
0xa8 , 0x61 , 0xb0 , 0x63 , 0xb8 , 0x65 , 0x60 , 0x65 ,
0xb4 , 0x65 , 0x5e , 0x65 , 0xa8 , 0x69 , 0x60 , 0x69 ,
0xb4 , 0x69 , 0x5e , 0x69 , 0xa8 , 0x6e , 0x7e , 0x6f ,
0x60 , 0x6f , 0xb4 , 0x6f , 0x5e , 0x6f , 0x7e , 0x6f ,
0xa8 , 0xf8 , 0x75 , 0x60 , 0x75 , 0xb4 , 0x75 , 0x5e ,
0x75 , 0xa8 , 0x79 , 0xb4 , 0x79 , 0xa8 , ' \0 '
} ;
2003-10-24 02:26:18 +02:00
static const char ligatures_src [ ] =
{
0x8C , 0x9C , 0xC6 , 0xDE , 0xDF , 0xE6 , 0xFE , ' \0 '
} ;
static const char ligatures_dst [ ] =
{
' O ' , ' E ' , ' o ' , ' e ' , ' A ' , ' E ' , ' T ' , ' H ' , ' s ' , ' s ' , ' a ' , ' e ' , ' t ' , ' h ' , ' \0 '
} ;
2009-09-01 12:19:35 +02:00
static const struct special
{
char src ;
char dst [ 4 ] ;
} foldczone_special [ ] =
{
/* src dst */
{ 0x85 , { 0x2e , 0x2e , 0x2e , 0x00 } } ,
{ 0x98 , { 0x20 , 0x7e , 0x00 } } ,
{ 0x99 , { 0x54 , 0x4d , 0x00 } } ,
{ 0xa0 , { 0x20 , 0x00 } } ,
{ 0xa8 , { 0x20 , 0xa8 , 0x00 } } ,
{ 0xaa , { 0x61 , 0x00 } } ,
{ 0xaf , { 0x20 , 0xaf , 0x00 } } ,
{ 0xb2 , { 0x32 , 0x00 } } ,
{ 0xb3 , { 0x33 , 0x00 } } ,
{ 0xb4 , { 0x20 , 0xb4 , 0x00 } } ,
{ 0xb8 , { 0x20 , 0xb8 , 0x00 } } ,
{ 0xb9 , { 0x31 , 0x00 } } ,
{ 0xba , { 0x6f , 0x00 } } ,
{ 0xbc , { 0x31 , 0x2f , 0x34 , 0x00 } } ,
{ 0xbd , { 0x31 , 0x2f , 0x32 , 0x00 } } ,
{ 0xbe , { 0x33 , 0x2f , 0x34 , 0x00 } } ,
{ 0x00 }
} ;
2003-10-24 02:26:18 +02:00
2003-11-22 01:00:53 +01:00
/* these tests are locale specific */
if ( GetACP ( ) ! = 1252 )
{
trace ( " Skipping FoldStringA tests for a not Latin 1 locale \n " ) ;
return ;
}
2003-10-24 02:26:18 +02:00
/* MAP_FOLDDIGITS */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringA ( MAP_FOLDDIGITS , digits_src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 4 , " Expected ret == 4, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
ok ( strcmp ( dst , digits_dst ) = = 0 ,
" MAP_FOLDDIGITS: Expected '%s', got '%s' \n " , digits_dst , dst ) ;
for ( i = 1 ; i < 256 ; i + + )
{
if ( ! strchr ( digits_src , i ) )
{
src [ 0 ] = i ;
src [ 1 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
ret = FoldStringA ( MAP_FOLDDIGITS , src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 2 , " Expected ret == 2, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
ok ( dst [ 0 ] = = src [ 0 ] ,
" MAP_FOLDDIGITS: Expected '%s', got '%s' \n " , src , dst ) ;
}
}
2020-01-06 19:28:45 +01:00
/* MAP_EXPAND_LIGATURES */
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringA ( MAP_EXPAND_LIGATURES , ligatures_src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = sizeof ( ligatures_dst ) , " Got %d, error %d \n " , ret , GetLastError ( ) ) ;
2004-05-30 05:11:24 +02:00
ok ( strcmp ( dst , ligatures_dst ) = = 0 ,
" MAP_EXPAND_LIGATURES: Expected '%s', got '%s' \n " , ligatures_dst , dst ) ;
for ( i = 1 ; i < 256 ; i + + )
2003-10-24 02:26:18 +02:00
{
2004-05-30 05:11:24 +02:00
if ( ! strchr ( ligatures_src , i ) )
{
src [ 0 ] = i ;
src [ 1 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
ret = FoldStringA ( MAP_EXPAND_LIGATURES , src , - 1 , dst , 256 ) ;
2009-09-01 12:19:35 +02:00
if ( ret = = 3 )
{
/* Vista */
ok ( ( i = = 0xDC & & lstrcmpA ( dst , " UE " ) = = 0 ) | |
( i = = 0xFC & & lstrcmpA ( dst , " ue " ) = = 0 ) ,
" Got %s for %d \n " , dst , i ) ;
}
else
{
ok ( ret = = 2 , " Expected ret == 2, got %d, error %d \n " , ret , GetLastError ( ) ) ;
ok ( dst [ 0 ] = = src [ 0 ] ,
" MAP_EXPAND_LIGATURES: Expected '%s', got '%s' \n " , src , dst ) ;
}
2004-05-30 05:11:24 +02:00
}
2003-10-24 02:26:18 +02:00
}
/* MAP_COMPOSITE */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringA ( MAP_COMPOSITE , composite_src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret , " Expected ret != 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2020-01-06 19:28:45 +01:00
ok ( GetLastError ( ) = = 0xdeadbeef | | broken ( ! GetLastError ( ) ) , /* vista */
" wrong error %u \n " , GetLastError ( ) ) ;
2009-09-01 12:19:35 +02:00
ok ( ret = = 121 | | ret = = 119 , " Expected 121 or 119, got %d \n " , ret ) ;
ok ( strcmp ( dst , composite_dst ) = = 0 | | strcmp ( dst , composite_dst_alt ) = = 0 ,
" MAP_COMPOSITE: Mismatch, got '%s' \n " , dst ) ;
2003-10-24 02:26:18 +02:00
for ( i = 1 ; i < 256 ; i + + )
{
if ( ! strchr ( composite_src , i ) )
{
src [ 0 ] = i ;
src [ 1 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
ret = FoldStringA ( MAP_COMPOSITE , src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 2 , " Expected ret == 2, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
ok ( dst [ 0 ] = = src [ 0 ] ,
" 0x%02x, 0x%02x,0x%02x,0x%02x, \n " , ( unsigned char ) src [ 0 ] ,
( unsigned char ) dst [ 0 ] , ( unsigned char ) dst [ 1 ] , ( unsigned char ) dst [ 2 ] ) ;
}
}
/* MAP_FOLDCZONE */
for ( i = 1 ; i < 256 ; i + + )
{
src [ 0 ] = i ;
src [ 1 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringA ( MAP_FOLDCZONE , src , - 1 , dst , 256 ) ;
2009-09-01 12:19:35 +02:00
is_special = FALSE ;
for ( j = 0 ; foldczone_special [ j ] . src ! = 0 & & ! is_special ; j + + )
{
if ( foldczone_special [ j ] . src = = src [ 0 ] )
{
ok ( ret = = 2 | | ret = = lstrlenA ( foldczone_special [ j ] . dst ) + 1 ,
" Expected ret == 2 or %d, got %d, error %d \n " ,
2009-09-02 11:53:06 +02:00
lstrlenA ( foldczone_special [ j ] . dst ) + 1 , ret , GetLastError ( ) ) ;
2009-09-01 12:19:35 +02:00
ok ( src [ 0 ] = = dst [ 0 ] | | lstrcmpA ( foldczone_special [ j ] . dst , dst ) = = 0 ,
" MAP_FOLDCZONE: string mismatch for 0x%02x \n " ,
( unsigned char ) src [ 0 ] ) ;
is_special = TRUE ;
}
}
if ( ! is_special )
{
ok ( ret = = 2 , " Expected ret == 2, got %d, error %d \n " , ret , GetLastError ( ) ) ;
ok ( src [ 0 ] = = dst [ 0 ] ,
" MAP_FOLDCZONE: Expected 0x%02x, got 0x%02x \n " ,
( unsigned char ) src [ 0 ] , ( unsigned char ) dst [ 0 ] ) ;
}
2003-10-24 02:26:18 +02:00
}
/* MAP_PRECOMPOSED */
for ( i = 1 ; i < 256 ; i + + )
{
src [ 0 ] = i ;
src [ 1 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
ret = FoldStringA ( MAP_PRECOMPOSED , src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 2 , " Expected ret == 2, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
ok ( src [ 0 ] = = dst [ 0 ] ,
" MAP_PRECOMPOSED: Expected 0x%02x, got 0x%02x \n " ,
( unsigned char ) src [ 0 ] , ( unsigned char ) dst [ 0 ] ) ;
}
}
2003-11-22 01:00:53 +01:00
static void test_FoldStringW ( void )
2003-10-24 02:26:18 +02:00
{
int ret ;
2019-11-19 15:36:22 +01:00
WORD type ;
2009-09-01 12:19:35 +02:00
unsigned int i , j ;
2003-10-24 02:26:18 +02:00
WCHAR src [ 256 ] , dst [ 256 ] , ch , prev_ch = 1 ;
static const DWORD badFlags [ ] =
{
0 ,
MAP_PRECOMPOSED | MAP_COMPOSITE ,
MAP_PRECOMPOSED | MAP_EXPAND_LIGATURES ,
MAP_COMPOSITE | MAP_EXPAND_LIGATURES
} ;
/* Ranges of digits 0-9 : Must be sorted! */
static const WCHAR digitRanges [ ] =
{
0x0030 , /* '0'-'9' */
0x0660 , /* Eastern Arabic */
0x06F0 , /* Arabic - Hindu */
2014-03-07 13:37:14 +01:00
0x07C0 , /* Nko */
2003-10-24 02:26:18 +02:00
0x0966 , /* Devengari */
0x09E6 , /* Bengalii */
0x0A66 , /* Gurmukhi */
0x0AE6 , /* Gujarati */
0x0B66 , /* Oriya */
0x0BE6 , /* Tamil - No 0 */
0x0C66 , /* Telugu */
0x0CE6 , /* Kannada */
0x0D66 , /* Maylayalam */
2014-06-23 16:05:36 +02:00
0x0DE6 , /* Sinhala Lith */
2003-10-24 02:26:18 +02:00
0x0E50 , /* Thai */
0x0ED0 , /* Laos */
2014-03-07 13:37:14 +01:00
0x0F20 , /* Tibet */
0x0F29 , /* Tibet half - 0 is out of sequence */
0x1040 , /* Myanmar */
0x1090 , /* Myanmar Shan */
0x1368 , /* Ethiopic - no 0 */
0x17E0 , /* Khmer */
0x1810 , /* Mongolian */
0x1946 , /* Limbu */
0x19D0 , /* New Tai Lue */
0x1A80 , /* Tai Tham Hora */
0x1A90 , /* Tai Tham Tham */
0x1B50 , /* Balinese */
0x1BB0 , /* Sundanese */
0x1C40 , /* Lepcha */
0x1C50 , /* Ol Chiki */
2003-10-24 02:26:18 +02:00
0x2070 , /* Superscript - 1, 2, 3 are out of sequence */
0x2080 , /* Subscript */
0x245F , /* Circled - 0 is out of sequence */
0x2473 , /* Bracketed */
0x2487 , /* Full stop */
2014-03-07 13:37:14 +01:00
0x24F4 , /* Double Circled */
2003-10-24 02:26:18 +02:00
0x2775 , /* Inverted circled - No 0 */
0x277F , /* Patterned circled - No 0 */
0x2789 , /* Inverted Patterned circled - No 0 */
2009-09-01 12:19:35 +02:00
0x3020 , /* Hangzhou */
2014-03-07 13:37:14 +01:00
0xA620 , /* Vai */
0xA8D0 , /* Saurashtra */
0xA900 , /* Kayah Li */
0xA9D0 , /* Javanese */
2014-06-23 16:05:36 +02:00
0xA9F0 , /* Myanmar Tai Laing */
2014-03-07 13:37:14 +01:00
0xAA50 , /* Cham */
0xABF0 , /* Meetei Mayek */
2003-10-24 02:26:18 +02:00
0xff10 , /* Pliene chasse (?) */
0xffff /* Terminator */
} ;
/* Digits which are represented, but out of sequence */
static const WCHAR outOfSequenceDigits [ ] =
{
0xB9 , /* Superscript 1 */
0xB2 , /* Superscript 2 */
0xB3 , /* Superscript 3 */
2014-03-07 13:37:14 +01:00
0x0C78 , /* Telugu Fraction 0 */
0x0C79 , /* Telugu Fraction 1 */
0x0C7A , /* Telugu Fraction 2 */
0x0C7B , /* Telugu Fraction 3 */
0x0C7C , /* Telugu Fraction 1 */
0x0C7D , /* Telugu Fraction 2 */
0x0C7E , /* Telugu Fraction 3 */
2009-09-01 12:19:35 +02:00
0x0F33 , /* Tibetan half zero */
2014-03-07 13:37:14 +01:00
0x19DA , /* New Tai Lue Tham 1 */
2003-10-24 02:26:18 +02:00
0x24EA , /* Circled 0 */
2014-03-07 13:37:14 +01:00
0x24FF , /* Negative Circled 0 */
2009-09-01 12:19:35 +02:00
0x3007 , /* Ideographic number zero */
2003-10-24 02:26:18 +02:00
' \0 ' /* Terminator */
} ;
/* Digits in digitRanges for which no representation is available */
static const WCHAR noDigitAvailable [ ] =
{
0x0BE6 , /* No Tamil 0 */
2009-09-01 12:19:35 +02:00
0x0F29 , /* No Tibetan half zero (out of sequence) */
2014-03-07 13:37:14 +01:00
0x1368 , /* No Ethiopic 0 */
2003-10-24 02:26:18 +02:00
0x2473 , /* No Bracketed 0 */
0x2487 , /* No 0 Full stop */
2014-03-07 13:37:14 +01:00
0x24F4 , /* No double circled 0 */
2003-10-24 02:26:18 +02:00
0x2775 , /* No inverted circled 0 */
0x277F , /* No patterned circled */
0x2789 , /* No inverted Patterned circled */
2009-09-01 12:19:35 +02:00
0x3020 , /* No Hangzhou 0 */
2003-10-24 02:26:18 +02:00
' \0 ' /* Terminator */
} ;
2009-09-01 12:19:35 +02:00
static const WCHAR foldczone_src [ ] =
2003-10-24 02:26:18 +02:00
{
2009-09-01 12:19:35 +02:00
' W ' , ' i ' , ' n ' , ' e ' , 0x0348 , 0x0551 , 0x1323 , 0x280d ,
2019-11-28 09:04:33 +01:00
0xff37 , 0xff49 , 0xff4e , 0xff45 , 0x3c5 , 0x308 , 0x6a , 0x30c , 0xa0 , 0xaa , 0
2003-10-24 02:26:18 +02:00
} ;
2009-09-01 12:19:35 +02:00
static const WCHAR foldczone_dst [ ] =
2003-10-24 02:26:18 +02:00
{
2019-11-28 09:04:33 +01:00
' W ' , ' i ' , ' n ' , ' e ' , 0x0348 , 0x0551 , 0x1323 , 0x280d , ' W ' , ' i ' , ' n ' , ' e ' , 0x3cb , 0x1f0 , ' ' , ' a ' , 0
2003-10-24 02:26:18 +02:00
} ;
2019-11-28 09:04:33 +01:00
static const WCHAR foldczone_broken_dst [ ] =
2012-04-24 16:11:12 +02:00
{
2019-12-08 03:59:35 +01:00
' W ' , ' i ' , ' n ' , ' e ' , 0x0348 , 0x0551 , 0x1323 , 0x280d , ' W ' , ' i ' , ' n ' , ' e ' , 0x03c5 , 0x0308 , ' j ' , 0x030c , 0x00a0 , 0x00aa , 0
2012-04-24 16:11:12 +02:00
} ;
2003-10-24 02:26:18 +02:00
static const WCHAR ligatures_src [ ] =
{
2009-09-01 12:19:35 +02:00
' W ' , ' i ' , ' n ' , ' e ' , 0x03a6 , 0x03b9 , 0x03bd , 0x03b5 ,
2003-10-24 02:26:18 +02:00
0x00c6 , 0x00de , 0x00df , 0x00e6 , 0x00fe , 0x0132 , 0x0133 , 0x0152 ,
0x0153 , 0x01c4 , 0x01c5 , 0x01c6 , 0x01c7 , 0x01c8 , 0x01c9 , 0x01ca ,
0x01cb , 0x01cc , 0x01e2 , 0x01e3 , 0x01f1 , 0x01f2 , 0x01f3 , 0x01fc ,
0x01fd , 0x05f0 , 0x05f1 , 0x05f2 , 0xfb00 , 0xfb01 , 0xfb02 , 0xfb03 ,
0xfb04 , 0xfb05 , 0xfb06 , ' \0 '
} ;
static const WCHAR ligatures_dst [ ] =
{
2009-09-01 12:19:35 +02:00
' W ' , ' i ' , ' n ' , ' e ' , 0x03a6 , 0x03b9 , 0x03bd , 0x03b5 ,
2003-10-24 02:26:18 +02:00
' A ' , ' E ' , ' T ' , ' H ' , ' s ' , ' s ' , ' a ' , ' e ' , ' t ' , ' h ' , ' I ' , ' J ' , ' i ' , ' j ' , ' O ' , ' E ' , ' o ' , ' e ' ,
' D ' , 0x017d , ' D ' , 0x017e , ' d ' , 0x017e , ' L ' , ' J ' , ' L ' , ' j ' , ' l ' , ' j ' , ' N ' , ' J ' , ' N ' , ' j ' ,
' n ' , ' j ' , 0x0100 , 0x0112 , 0x0101 , 0x0113 , ' D ' , ' Z ' , ' D ' , ' z ' , ' d ' , ' z ' , 0x00c1 , 0x00c9 ,
0x00e1 , 0x00e9 , 0x05d5 , 0x05d5 , 0x05d5 , 0x05d9 , 0x05d9 , 0x05d9 , ' f ' , ' f ' , ' f ' , ' i ' ,
' f ' , ' l ' , ' f ' , ' f ' , ' i ' , ' f ' , ' f ' , ' l ' , 0x017f , ' t ' , ' s ' , ' t ' , ' \0 '
} ;
/* Invalid flag combinations */
2018-06-22 19:50:38 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( badFlags ) ; i + + )
2003-10-24 02:26:18 +02:00
{
src [ 0 ] = dst [ 0 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringW ( badFlags [ i ] , src , 256 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_FLAGS ,
" Expected ERROR_INVALID_FLAGS, got %d \n " , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
}
/* src & dst cannot be the same */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringW ( MAP_FOLDCZONE , src , - 1 , src , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
/* src can't be NULL */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringW ( MAP_FOLDCZONE , NULL , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
/* srclen can't be 0 */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringW ( MAP_FOLDCZONE , src , 0 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
/* dstlen can't be < 0 */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringW ( MAP_FOLDCZONE , src , - 1 , dst , - 1 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
/* Ret includes terminating NUL which is appended if srclen = -1 */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-10-24 02:26:18 +02:00
src [ 0 ] = ' A ' ;
src [ 1 ] = ' \0 ' ;
dst [ 0 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
ret = FoldStringW ( MAP_FOLDCZONE , src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 2 , " Expected ret == 2, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
ok ( dst [ 0 ] = = ' A ' & & dst [ 1 ] = = ' \0 ' ,
2006-10-10 01:06:48 +02:00
" srclen=-1: Expected ret=2 [%d,%d], got ret=%d [%d,%d], err=%d \n " ,
2003-10-24 02:26:18 +02:00
' A ' , ' \0 ' , ret , dst [ 0 ] , dst [ 1 ] , GetLastError ( ) ) ;
/* If size is given, result is not NUL terminated */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-10-24 02:26:18 +02:00
src [ 0 ] = ' A ' ;
src [ 1 ] = ' A ' ;
dst [ 0 ] = ' X ' ;
dst [ 1 ] = ' X ' ;
2020-01-06 19:28:45 +01:00
ret = FoldStringW ( MAP_FOLDCZONE , src , 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 1 , " Expected ret == 1, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
ok ( dst [ 0 ] = = ' A ' & & dst [ 1 ] = = ' X ' ,
2006-10-10 01:06:48 +02:00
" srclen=1: Expected ret=1, [%d,%d], got ret=%d,[%d,%d], err=%d \n " ,
2003-10-24 02:26:18 +02:00
' A ' , ' X ' , ret , dst [ 0 ] , dst [ 1 ] , GetLastError ( ) ) ;
/* MAP_FOLDDIGITS */
2018-06-22 19:50:38 +02:00
for ( j = 0 ; j < ARRAY_SIZE ( digitRanges ) ; j + + )
2003-10-24 02:26:18 +02:00
{
/* Check everything before this range */
for ( ch = prev_ch ; ch < digitRanges [ j ] ; ch + + )
{
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-10-24 02:26:18 +02:00
src [ 0 ] = ch ;
src [ 1 ] = dst [ 0 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
ret = FoldStringW ( MAP_FOLDDIGITS , src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 2 , " Expected ret == 2, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
2019-11-19 15:36:22 +01:00
ok ( dst [ 0 ] = = ch | | wcschr ( outOfSequenceDigits , ch ) | |
2014-03-07 13:37:14 +01:00
( ch > = 0xa8e0 & & ch < = 0xa8e9 ) , /* combining Devanagari on Win8 */
" MAP_FOLDDIGITS: ch 0x%04x Expected unchanged got %04x \n " , ch , dst [ 0 ] ) ;
2019-11-19 15:36:22 +01:00
GetStringTypeW ( CT_CTYPE1 , & ch , 1 , & type ) ;
ok ( ! ( type & C1_DIGIT ) | | wcschr ( outOfSequenceDigits , ch ) | |
2014-03-07 13:37:14 +01:00
broken ( ch > = 0xbf0 & & ch < = 0xbf2 ) , /* win2k */
" char %04x should not be a digit \n " , ch ) ;
2003-10-24 02:26:18 +02:00
}
if ( digitRanges [ j ] = = 0xffff )
break ; /* Finished the whole code point space */
for ( ch = digitRanges [ j ] ; ch < digitRanges [ j ] + 10 ; ch + + )
{
WCHAR c ;
/* Map out of sequence characters */
if ( ch = = 0x2071 ) c = 0x00B9 ; /* Superscript 1 */
else if ( ch = = 0x2072 ) c = 0x00B2 ; /* Superscript 2 */
else if ( ch = = 0x2073 ) c = 0x00B3 ; /* Superscript 3 */
else if ( ch = = 0x245F ) c = 0x24EA ; /* Circled 0 */
else c = ch ;
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-10-24 02:26:18 +02:00
src [ 0 ] = c ;
src [ 1 ] = dst [ 0 ] = ' \0 ' ;
2020-01-06 19:28:45 +01:00
ret = FoldStringW ( MAP_FOLDDIGITS , src , - 1 , dst , 256 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret = = 2 , " Expected ret == 2, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2003-10-24 02:26:18 +02:00
ok ( ( dst [ 0 ] = = ' 0 ' + ch - digitRanges [ j ] & & dst [ 1 ] = = ' \0 ' ) | |
2008-11-20 21:39:48 +01:00
broken ( dst [ 0 ] = = ch ) | | /* old Windows versions don't have all mappings */
2009-09-01 12:19:35 +02:00
( digitRanges [ j ] = = 0x3020 & & dst [ 0 ] = = ch ) | | /* Hangzhou not present in all Windows versions */
( digitRanges [ j ] = = 0x0F29 & & dst [ 0 ] = = ch ) | | /* Tibetan not present in all Windows versions */
2019-11-19 15:36:22 +01:00
wcschr ( noDigitAvailable , c ) ,
2014-03-07 13:37:14 +01:00
" MAP_FOLDDIGITS: ch %04x Expected %04x got %04x \n " ,
2003-10-24 02:26:18 +02:00
ch , ' 0 ' + digitRanges [ j ] - ch , dst [ 0 ] ) ;
}
prev_ch = ch ;
}
/* MAP_FOLDCZONE */
2020-01-06 19:28:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringW ( MAP_FOLDCZONE , foldczone_src , - 1 , dst , 256 ) ;
2019-12-08 03:59:35 +01:00
ok ( ret = = ARRAY_SIZE ( foldczone_dst )
| | broken ( ret = = ARRAY_SIZE ( foldczone_broken_dst ) ) , /* winxp, win2003 */
" Got %d, error %d. \n " , ret , GetLastError ( ) ) ;
2019-11-28 09:04:33 +01:00
ok ( ! memcmp ( dst , foldczone_dst , sizeof ( foldczone_dst ) )
2019-12-08 03:59:35 +01:00
| | broken ( ! memcmp ( dst , foldczone_broken_dst , sizeof ( foldczone_broken_dst ) ) ) , /* winxp, win2003 */
2019-12-08 03:59:34 +01:00
" Got unexpected string %s. \n " , wine_dbgstr_w ( dst ) ) ;
2003-10-24 02:26:18 +02:00
2020-01-06 19:28:45 +01:00
/* MAP_EXPAND_LIGATURES */
SetLastError ( 0xdeadbeef ) ;
ret = FoldStringW ( MAP_EXPAND_LIGATURES , ligatures_src , - 1 , dst , 256 ) ;
2018-06-22 19:50:38 +02:00
ok ( ret = = ARRAY_SIZE ( ligatures_dst ) , " Got %d, error %d \n " , ret , GetLastError ( ) ) ;
2004-05-30 05:11:24 +02:00
ok ( ! memcmp ( dst , ligatures_dst , sizeof ( ligatures_dst ) ) ,
2019-12-08 03:59:34 +01:00
" Got unexpected string %s. \n " , wine_dbgstr_w ( dst ) ) ;
2003-10-24 02:26:18 +02:00
/* FIXME: MAP_PRECOMPOSED : MAP_COMPOSITE */
}
2003-09-24 20:52:39 +02:00
# define LCID_OK(l) \
2006-10-10 01:06:48 +02:00
ok ( lcid = = l , " Expected lcid = %08x, got %08x \n " , l , lcid )
2003-09-24 20:52:39 +02:00
# define MKLCID(x,y,z) MAKELCID(MAKELANGID(x, y), z)
2019-11-19 09:58:20 +01:00
# define LCID_RES(src, res) do { lcid = ConvertDefaultLocale(src); LCID_OK(res); } while (0)
2003-09-24 20:52:39 +02:00
# define TEST_LCIDLANG(a,b) LCID_RES(MAKELCID(a,b), MAKELCID(a,b))
# define TEST_LCID(a,b,c) LCID_RES(MKLCID(a,b,c), MKLCID(a,b,c))
static void test_ConvertDefaultLocale ( void )
{
2019-11-19 09:58:20 +01:00
/* some languages use a different default than SUBLANG_DEFAULT */
static const struct { WORD lang , sublang ; } nondefault_langs [ ] =
{
{ LANG_CHINESE , SUBLANG_CHINESE_SIMPLIFIED } ,
{ LANG_SPANISH , SUBLANG_SPANISH_MODERN } ,
{ LANG_IRISH , SUBLANG_IRISH_IRELAND } ,
{ LANG_BENGALI , SUBLANG_BENGALI_BANGLADESH } ,
{ LANG_SINDHI , SUBLANG_SINDHI_AFGHANISTAN } ,
{ LANG_INUKTITUT , SUBLANG_INUKTITUT_CANADA_LATIN } ,
{ LANG_TAMAZIGHT , SUBLANG_TAMAZIGHT_ALGERIA_LATIN } ,
{ LANG_FULAH , SUBLANG_FULAH_SENEGAL } ,
{ LANG_TIGRINYA , SUBLANG_TIGRINYA_ERITREA }
} ;
LCID lcid ;
unsigned int i ;
2003-09-24 20:52:39 +02:00
/* Doesn't change lcid, even if non default sublang/sort used */
TEST_LCID ( LANG_ENGLISH , SUBLANG_ENGLISH_US , SORT_DEFAULT ) ;
TEST_LCID ( LANG_ENGLISH , SUBLANG_ENGLISH_UK , SORT_DEFAULT ) ;
TEST_LCID ( LANG_JAPANESE , SUBLANG_DEFAULT , SORT_DEFAULT ) ;
TEST_LCID ( LANG_JAPANESE , SUBLANG_DEFAULT , SORT_JAPANESE_UNICODE ) ;
2019-11-19 09:58:20 +01:00
lcid = ConvertDefaultLocale ( MKLCID ( LANG_JAPANESE , SUBLANG_NEUTRAL , SORT_JAPANESE_UNICODE ) ) ;
ok ( lcid = = MKLCID ( LANG_JAPANESE , SUBLANG_NEUTRAL , SORT_JAPANESE_UNICODE ) | |
broken ( lcid = = MKLCID ( LANG_JAPANESE , SUBLANG_DEFAULT , SORT_JAPANESE_UNICODE ) ) , /* <= vista */
" Expected lcid = %08x got %08x \n " ,
MKLCID ( LANG_JAPANESE , SUBLANG_NEUTRAL , SORT_JAPANESE_UNICODE ) , lcid ) ;
lcid = ConvertDefaultLocale ( MKLCID ( LANG_IRISH , SUBLANG_NEUTRAL , SORT_JAPANESE_UNICODE ) ) ;
ok ( lcid = = MKLCID ( LANG_IRISH , SUBLANG_NEUTRAL , SORT_JAPANESE_UNICODE ) | |
broken ( lcid = = MKLCID ( LANG_IRISH , SUBLANG_DEFAULT , SORT_JAPANESE_UNICODE ) ) , /* <= vista */
" Expected lcid = %08x got %08x \n " ,
MKLCID ( LANG_IRISH , SUBLANG_NEUTRAL , SORT_JAPANESE_UNICODE ) , lcid ) ;
2003-09-24 20:52:39 +02:00
/* SUBLANG_NEUTRAL -> SUBLANG_DEFAULT */
LCID_RES ( MKLCID ( LANG_ENGLISH , SUBLANG_NEUTRAL , SORT_DEFAULT ) ,
MKLCID ( LANG_ENGLISH , SUBLANG_DEFAULT , SORT_DEFAULT ) ) ;
LCID_RES ( MKLCID ( LANG_JAPANESE , SUBLANG_NEUTRAL , SORT_DEFAULT ) ,
MKLCID ( LANG_JAPANESE , SUBLANG_DEFAULT , SORT_DEFAULT ) ) ;
2019-11-19 09:58:20 +01:00
for ( i = 0 ; i < ARRAY_SIZE ( nondefault_langs ) ; i + + )
{
lcid = ConvertDefaultLocale ( MAKELANGID ( nondefault_langs [ i ] . lang , SUBLANG_NEUTRAL ) ) ;
ok ( lcid = = MAKELANGID ( nondefault_langs [ i ] . lang , nondefault_langs [ i ] . sublang ) | |
broken ( lcid = = MAKELANGID ( nondefault_langs [ i ] . lang , SUBLANG_DEFAULT ) ) | | /* <= vista */
broken ( lcid = = MAKELANGID ( nondefault_langs [ i ] . lang , SUBLANG_NEUTRAL ) ) , /* w7 */
" Expected lcid = %08x got %08x \n " ,
MAKELANGID ( nondefault_langs [ i ] . lang , nondefault_langs [ i ] . sublang ) , lcid ) ;
}
lcid = ConvertDefaultLocale ( 0x7804 ) ;
ok ( lcid = = MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_SIMPLIFIED ) | |
broken ( lcid = = 0x7804 ) , /* <= vista */
" Expected lcid = %08x got %08x \n " , MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_SIMPLIFIED ) , lcid ) ;
lcid = ConvertDefaultLocale ( 0x7c04 ) ;
ok ( lcid = = MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_HONGKONG ) | |
broken ( lcid = = 0x7c04 ) | | /* winxp */
broken ( lcid = = 0x0404 ) , /* vista */
" Expected lcid = %08x got %08x \n " , MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_HONGKONG ) , lcid ) ;
2021-02-04 00:48:34 +01:00
lcid = ConvertDefaultLocale ( LANG_SERBIAN_NEUTRAL ) ;
ok ( lcid = = MAKELANGID ( LANG_SERBIAN , SUBLANG_SERBIAN_SERBIA_LATIN ) | |
broken ( lcid = = MAKELANGID ( LANG_SERBIAN , SUBLANG_SERBIAN_LATIN ) ) , /* <= vista */
" Expected lcid = %08x got %08x \n " , MAKELANGID ( LANG_SERBIAN , SUBLANG_SERBIAN_SERBIA_LATIN ) , lcid ) ;
2003-09-24 20:52:39 +02:00
/* Invariant language is not treated specially */
TEST_LCID ( LANG_INVARIANT , SUBLANG_DEFAULT , SORT_DEFAULT ) ;
/* User/system default languages alone are not mapped */
TEST_LCIDLANG ( LANG_SYSTEM_DEFAULT , SORT_JAPANESE_UNICODE ) ;
TEST_LCIDLANG ( LANG_USER_DEFAULT , SORT_JAPANESE_UNICODE ) ;
/* Default lcids */
LCID_RES ( LOCALE_SYSTEM_DEFAULT , GetSystemDefaultLCID ( ) ) ;
LCID_RES ( LOCALE_USER_DEFAULT , GetUserDefaultLCID ( ) ) ;
LCID_RES ( LOCALE_NEUTRAL , GetUserDefaultLCID ( ) ) ;
2015-08-17 23:36:19 +02:00
lcid = ConvertDefaultLocale ( LOCALE_INVARIANT ) ;
ok ( lcid = = LOCALE_INVARIANT | | broken ( lcid = = 0x47f ) /* win2k[3]/winxp */ ,
" Expected lcid = %08x, got %08x \n " , LOCALE_INVARIANT , lcid ) ;
2003-09-24 20:52:39 +02:00
}
static BOOL CALLBACK langgrp_procA ( LGRPID lgrpid , LPSTR lpszNum , LPSTR lpszName ,
DWORD dwFlags , LONG_PTR lParam )
{
2015-05-08 17:46:30 +02:00
if ( winetest_debug > 1 )
trace ( " %08x, %s, %s, %08x, %08lx \n " ,
lgrpid , lpszNum , lpszName , dwFlags , lParam ) ;
2003-09-24 20:52:39 +02:00
2003-12-08 23:20:44 +01:00
ok ( pIsValidLanguageGroup ( lgrpid , dwFlags ) = = TRUE ,
2006-10-10 01:06:48 +02:00
" Enumerated grp %d not valid (flags %d) \n " , lgrpid , dwFlags ) ;
2003-09-24 20:52:39 +02:00
/* If lParam is one, we are calling with flags defaulted from 0 */
2003-11-22 01:00:53 +01:00
ok ( ! lParam | | ( dwFlags = = LGRPID_INSTALLED | | dwFlags = = LGRPID_SUPPORTED ) ,
2006-10-10 01:06:48 +02:00
" Expected dwFlags == LGRPID_INSTALLED || dwFlags == LGRPID_SUPPORTED, got %d \n " , dwFlags ) ;
2003-09-24 20:52:39 +02:00
return TRUE ;
}
static void test_EnumSystemLanguageGroupsA ( void )
{
2008-10-06 14:02:44 +02:00
BOOL ret ;
2003-12-08 23:20:44 +01:00
if ( ! pEnumSystemLanguageGroupsA | | ! pIsValidLanguageGroup )
2008-10-06 14:02:44 +02:00
{
win_skip ( " EnumSystemLanguageGroupsA and/or IsValidLanguageGroup are not available \n " ) ;
2003-09-24 20:52:39 +02:00
return ;
2008-10-06 14:02:44 +02:00
}
2003-09-24 20:52:39 +02:00
/* No enumeration proc */
SetLastError ( 0 ) ;
2008-10-06 17:32:09 +02:00
ret = pEnumSystemLanguageGroupsA ( 0 , LGRPID_INSTALLED , 0 ) ;
2008-11-26 12:04:32 +01:00
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
2008-10-06 14:02:44 +02:00
{
win_skip ( " EnumSystemLanguageGroupsA is not implemented \n " ) ;
return ;
}
2008-11-20 21:39:48 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
/* Invalid flags */
SetLastError ( 0 ) ;
pEnumSystemLanguageGroupsA ( langgrp_procA , LGRPID_INSTALLED | LGRPID_SUPPORTED , 0 ) ;
2008-11-20 21:39:48 +01:00
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS , " Expected ERROR_INVALID_FLAGS, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
/* No flags - defaults to LGRPID_INSTALLED */
2008-11-20 21:39:48 +01:00
SetLastError ( 0xdeadbeef ) ;
2003-09-24 20:52:39 +02:00
pEnumSystemLanguageGroupsA ( langgrp_procA , 0 , 1 ) ;
2008-11-20 21:39:48 +01:00
ok ( GetLastError ( ) = = 0xdeadbeef , " got error %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
pEnumSystemLanguageGroupsA ( langgrp_procA , LGRPID_INSTALLED , 0 ) ;
pEnumSystemLanguageGroupsA ( langgrp_procA , LGRPID_SUPPORTED , 0 ) ;
}
2010-09-27 14:03:12 +02:00
static BOOL CALLBACK enum_func ( LPWSTR name , DWORD flags , LPARAM lparam )
{
2015-05-08 17:46:30 +02:00
if ( winetest_debug > 1 )
trace ( " %s %x \n " , wine_dbgstr_w ( name ) , flags ) ;
2010-09-27 14:03:12 +02:00
return TRUE ;
}
static void test_EnumSystemLocalesEx ( void )
{
BOOL ret ;
if ( ! pEnumSystemLocalesEx )
{
win_skip ( " EnumSystemLocalesEx not available \n " ) ;
return ;
}
SetLastError ( 0xdeadbeef ) ;
ret = pEnumSystemLocalesEx ( enum_func , LOCALE_ALL , 0 , ( void * ) 1 ) ;
ok ( ! ret , " should have failed \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pEnumSystemLocalesEx ( enum_func , 0 , 0 , NULL ) ;
ok ( ret , " failed err %u \n " , GetLastError ( ) ) ;
}
2003-09-24 20:52:39 +02:00
static BOOL CALLBACK lgrplocale_procA ( LGRPID lgrpid , LCID lcid , LPSTR lpszNum ,
LONG_PTR lParam )
{
2015-05-08 17:46:30 +02:00
if ( winetest_debug > 1 )
trace ( " %08x, %08x, %s, %08lx \n " , lgrpid , lcid , lpszNum , lParam ) ;
2003-09-24 20:52:39 +02:00
2008-05-23 10:10:46 +02:00
/* invalid locale enumerated on some platforms */
if ( lcid = = 0 )
return TRUE ;
2003-12-08 23:20:44 +01:00
ok ( pIsValidLanguageGroup ( lgrpid , LGRPID_SUPPORTED ) = = TRUE ,
2006-10-10 01:06:48 +02:00
" Enumerated grp %d not valid \n " , lgrpid ) ;
2003-09-24 20:52:39 +02:00
ok ( IsValidLocale ( lcid , LCID_SUPPORTED ) = = TRUE ,
2013-06-19 12:55:17 +02:00
" Enumerated grp locale %04x not valid \n " , lcid ) ;
2003-09-24 20:52:39 +02:00
return TRUE ;
}
static void test_EnumLanguageGroupLocalesA ( void )
{
2008-10-06 14:02:44 +02:00
BOOL ret ;
2003-12-08 23:20:44 +01:00
if ( ! pEnumLanguageGroupLocalesA | | ! pIsValidLanguageGroup )
2008-10-06 14:02:44 +02:00
{
win_skip ( " EnumLanguageGroupLocalesA and/or IsValidLanguageGroup are not available \n " ) ;
2003-12-08 23:20:44 +01:00
return ;
2008-10-06 14:02:44 +02:00
}
2003-09-24 20:52:39 +02:00
/* No enumeration proc */
SetLastError ( 0 ) ;
2008-10-06 14:02:44 +02:00
ret = pEnumLanguageGroupLocalesA ( 0 , LGRPID_WESTERN_EUROPE , 0 , 0 ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
win_skip ( " EnumLanguageGroupLocalesA is not implemented \n " ) ;
return ;
}
2008-11-20 21:39:48 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
/* lgrpid too small */
SetLastError ( 0 ) ;
2008-11-20 21:39:48 +01:00
ret = pEnumLanguageGroupLocalesA ( lgrplocale_procA , 0 , 0 , 0 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
/* lgrpid too big */
SetLastError ( 0 ) ;
2008-11-20 21:39:48 +01:00
ret = pEnumLanguageGroupLocalesA ( lgrplocale_procA , LGRPID_ARMENIAN + 1 , 0 , 0 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
/* dwFlags is reserved */
SetLastError ( 0 ) ;
2008-11-20 21:39:48 +01:00
ret = pEnumLanguageGroupLocalesA ( 0 , LGRPID_WESTERN_EUROPE , 0x1 , 0 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
pEnumLanguageGroupLocalesA ( lgrplocale_procA , LGRPID_WESTERN_EUROPE , 0 , 0 ) ;
}
static void test_SetLocaleInfoA ( void )
{
BOOL bRet ;
LCID lcid = GetUserDefaultLCID ( ) ;
/* Null data */
SetLastError ( 0 ) ;
bRet = SetLocaleInfoA ( lcid , LOCALE_SDATE , 0 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! bRet & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
/* IDATE */
SetLastError ( 0 ) ;
2011-05-29 23:31:03 +02:00
bRet = SetLocaleInfoA ( lcid , LOCALE_IDATE , " test_SetLocaleInfoA " ) ;
2008-11-20 21:39:48 +01:00
ok ( ! bRet & & GetLastError ( ) = = ERROR_INVALID_FLAGS ,
" Expected ERROR_INVALID_FLAGS, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
/* ILDATE */
SetLastError ( 0 ) ;
2011-05-29 23:31:03 +02:00
bRet = SetLocaleInfoA ( lcid , LOCALE_ILDATE , " test_SetLocaleInfoA " ) ;
2008-11-20 21:39:48 +01:00
ok ( ! bRet & & GetLastError ( ) = = ERROR_INVALID_FLAGS ,
" Expected ERROR_INVALID_FLAGS, got %d \n " , GetLastError ( ) ) ;
2003-09-24 20:52:39 +02:00
}
2005-06-02 12:30:57 +02:00
static BOOL CALLBACK luilocale_proc1A ( LPSTR value , LONG_PTR lParam )
{
2015-05-08 17:46:30 +02:00
if ( winetest_debug > 1 )
trace ( " %s %08lx \n " , value , lParam ) ;
2004-11-01 22:06:28 +01:00
return ( TRUE ) ;
}
2005-06-02 12:30:57 +02:00
static BOOL CALLBACK luilocale_proc2A ( LPSTR value , LONG_PTR lParam )
{
2004-11-01 22:06:28 +01:00
ok ( ! enumCount , " callback called again unexpected \n " ) ;
enumCount + + ;
return ( FALSE ) ;
}
2005-06-02 12:30:57 +02:00
static BOOL CALLBACK luilocale_proc3A ( LPSTR value , LONG_PTR lParam )
{
2004-11-01 22:06:28 +01:00
ok ( 0 , " callback called unexpected \n " ) ;
return ( FALSE ) ;
}
static void test_EnumUILanguageA ( void )
2005-06-02 12:30:57 +02:00
{
BOOL ret ;
2004-11-01 22:06:28 +01:00
if ( ! pEnumUILanguagesA ) {
2009-02-24 00:03:07 +01:00
win_skip ( " EnumUILanguagesA is not available on Win9x or NT4 \n " ) ;
2004-11-01 22:06:28 +01:00
return ;
}
SetLastError ( ERROR_SUCCESS ) ;
ret = pEnumUILanguagesA ( luilocale_proc1A , 0 , 0 ) ;
2008-10-06 20:36:15 +02:00
if ( ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
2008-10-06 14:02:44 +02:00
{
win_skip ( " EnumUILanguagesA is not implemented \n " ) ;
return ;
}
2008-11-20 21:39:48 +01:00
ok ( ret , " Expected ret != 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2004-11-01 22:06:28 +01:00
enumCount = 0 ;
SetLastError ( ERROR_SUCCESS ) ;
ret = pEnumUILanguagesA ( luilocale_proc2A , 0 , 0 ) ;
2008-11-20 21:39:48 +01:00
ok ( ret , " Expected ret != 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
2019-02-13 13:47:58 +01:00
ok ( enumCount = = 1 , " enumCount = %u \n " , enumCount ) ;
enumCount = 0 ;
SetLastError ( ERROR_SUCCESS ) ;
ret = pEnumUILanguagesA ( luilocale_proc2A , MUI_LANGUAGE_ID , 0 ) ;
ok ( ret | | broken ( ! ret & & GetLastError ( ) = = ERROR_INVALID_FLAGS ) , /* winxp */
" Expected ret != 0, got %d, error %d \n " , ret , GetLastError ( ) ) ;
if ( ret ) ok ( enumCount = = 1 , " enumCount = %u \n " , enumCount ) ;
2004-11-01 22:06:28 +01:00
SetLastError ( ERROR_SUCCESS ) ;
ret = pEnumUILanguagesA ( NULL , 0 , 0 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret , " Expected return value FALSE, got %u \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2004-11-01 22:06:28 +01:00
SetLastError ( ERROR_SUCCESS ) ;
ret = pEnumUILanguagesA ( luilocale_proc3A , 0x5a5a5a5a , 0 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret , " Expected return value FALSE, got %u \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS , " Expected ERROR_INVALID_FLAGS, got %d \n " , GetLastError ( ) ) ;
2004-11-01 22:06:28 +01:00
SetLastError ( ERROR_SUCCESS ) ;
ret = pEnumUILanguagesA ( NULL , 0x5a5a5a5a , 0 ) ;
2008-11-20 21:39:48 +01:00
ok ( ! ret , " Expected return value FALSE, got %u \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" Expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2004-11-01 22:06:28 +01:00
}
2005-07-27 17:15:02 +02:00
static char date_fmt_buf [ 1024 ] ;
2015-11-10 15:40:07 +01:00
static WCHAR date_fmt_bufW [ 1024 ] ;
2005-07-27 17:15:02 +02:00
2005-07-28 12:16:02 +02:00
static BOOL CALLBACK enum_datetime_procA ( LPSTR fmt )
2005-07-27 17:15:02 +02:00
{
lstrcatA ( date_fmt_buf , fmt ) ;
lstrcatA ( date_fmt_buf , " \n " ) ;
return TRUE ;
}
2015-11-10 15:40:07 +01:00
static BOOL CALLBACK enum_datetime_procW ( WCHAR * fmt )
{
lstrcatW ( date_fmt_bufW , fmt ) ;
return FALSE ;
}
2005-07-27 17:15:02 +02:00
static void test_EnumDateFormatsA ( void )
{
char * p , buf [ 256 ] ;
BOOL ret ;
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
date_fmt_buf [ 0 ] = 0 ;
2008-10-06 13:33:27 +02:00
SetLastError ( 0xdeadbeef ) ;
2005-07-28 12:16:02 +02:00
ret = EnumDateFormatsA ( enum_datetime_procA , lcid , 0 ) ;
2008-10-06 13:33:27 +02:00
if ( ! ret & & ( GetLastError ( ) = = ERROR_INVALID_FLAGS ) )
{
win_skip ( " 0 for dwFlags is not supported \n " ) ;
}
else
{
ok ( ret , " EnumDateFormatsA(0) error %d \n " , GetLastError ( ) ) ;
2014-06-17 10:58:46 +02:00
trace ( " EnumDateFormatsA(0): %s \n " , date_fmt_buf ) ;
2008-10-06 13:33:27 +02:00
/* test the 1st enumerated format */
if ( ( p = strchr ( date_fmt_buf , ' \n ' ) ) ) * p = 0 ;
ret = GetLocaleInfoA ( lcid , LOCALE_SSHORTDATE , buf , sizeof ( buf ) ) ;
ok ( ret , " GetLocaleInfoA(LOCALE_SSHORTDATE) error %d \n " , GetLastError ( ) ) ;
ok ( ! lstrcmpA ( date_fmt_buf , buf ) , " expected \" %s \" got \" %s \" \n " , date_fmt_buf , buf ) ;
}
2005-07-27 17:15:02 +02:00
date_fmt_buf [ 0 ] = 0 ;
2008-10-06 13:33:27 +02:00
SetLastError ( 0xdeadbeef ) ;
2005-07-28 12:16:02 +02:00
ret = EnumDateFormatsA ( enum_datetime_procA , lcid , LOCALE_USE_CP_ACP ) ;
2008-10-06 13:33:27 +02:00
if ( ! ret & & ( GetLastError ( ) = = ERROR_INVALID_FLAGS ) )
{
win_skip ( " LOCALE_USE_CP_ACP is not supported \n " ) ;
}
else
{
ok ( ret , " EnumDateFormatsA(LOCALE_USE_CP_ACP) error %d \n " , GetLastError ( ) ) ;
2014-06-17 10:58:46 +02:00
trace ( " EnumDateFormatsA(LOCALE_USE_CP_ACP): %s \n " , date_fmt_buf ) ;
2008-10-06 13:33:27 +02:00
/* test the 1st enumerated format */
if ( ( p = strchr ( date_fmt_buf , ' \n ' ) ) ) * p = 0 ;
ret = GetLocaleInfoA ( lcid , LOCALE_SSHORTDATE , buf , sizeof ( buf ) ) ;
ok ( ret , " GetLocaleInfoA(LOCALE_SSHORTDATE) error %d \n " , GetLastError ( ) ) ;
ok ( ! lstrcmpA ( date_fmt_buf , buf ) , " expected \" %s \" got \" %s \" \n " , date_fmt_buf , buf ) ;
}
2005-07-27 17:15:02 +02:00
date_fmt_buf [ 0 ] = 0 ;
2005-07-28 12:16:02 +02:00
ret = EnumDateFormatsA ( enum_datetime_procA , lcid , DATE_SHORTDATE ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " EnumDateFormatsA(DATE_SHORTDATE) error %d \n " , GetLastError ( ) ) ;
2014-06-17 10:58:46 +02:00
trace ( " EnumDateFormatsA(DATE_SHORTDATE): %s \n " , date_fmt_buf ) ;
2005-07-27 17:15:02 +02:00
/* test the 1st enumerated format */
if ( ( p = strchr ( date_fmt_buf , ' \n ' ) ) ) * p = 0 ;
ret = GetLocaleInfoA ( lcid , LOCALE_SSHORTDATE , buf , sizeof ( buf ) ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " GetLocaleInfoA(LOCALE_SSHORTDATE) error %d \n " , GetLastError ( ) ) ;
2005-07-27 17:15:02 +02:00
ok ( ! lstrcmpA ( date_fmt_buf , buf ) , " expected \" %s \" got \" %s \" \n " , date_fmt_buf , buf ) ;
date_fmt_buf [ 0 ] = 0 ;
2005-07-28 12:16:02 +02:00
ret = EnumDateFormatsA ( enum_datetime_procA , lcid , DATE_LONGDATE ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " EnumDateFormatsA(DATE_LONGDATE) error %d \n " , GetLastError ( ) ) ;
2014-06-17 10:58:46 +02:00
trace ( " EnumDateFormatsA(DATE_LONGDATE): %s \n " , date_fmt_buf ) ;
2005-07-27 17:15:02 +02:00
/* test the 1st enumerated format */
if ( ( p = strchr ( date_fmt_buf , ' \n ' ) ) ) * p = 0 ;
ret = GetLocaleInfoA ( lcid , LOCALE_SLONGDATE , buf , sizeof ( buf ) ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " GetLocaleInfoA(LOCALE_SLONGDATE) error %d \n " , GetLastError ( ) ) ;
2005-07-27 17:15:02 +02:00
ok ( ! lstrcmpA ( date_fmt_buf , buf ) , " expected \" %s \" got \" %s \" \n " , date_fmt_buf , buf ) ;
date_fmt_buf [ 0 ] = 0 ;
2008-03-12 09:50:37 +01:00
SetLastError ( 0xdeadbeef ) ;
2005-07-28 12:16:02 +02:00
ret = EnumDateFormatsA ( enum_datetime_procA , lcid , DATE_YEARMONTH ) ;
2008-03-12 09:50:37 +01:00
if ( ! ret & & ( GetLastError ( ) = = ERROR_INVALID_FLAGS ) )
{
2014-07-18 11:26:29 +02:00
win_skip ( " DATE_YEARMONTH is only present on W2K and later \n " ) ;
2008-03-12 09:50:37 +01:00
return ;
}
2006-10-10 01:06:48 +02:00
ok ( ret , " EnumDateFormatsA(DATE_YEARMONTH) error %d \n " , GetLastError ( ) ) ;
2014-06-17 10:58:46 +02:00
trace ( " EnumDateFormatsA(DATE_YEARMONTH): %s \n " , date_fmt_buf ) ;
2005-07-27 17:15:02 +02:00
/* test the 1st enumerated format */
if ( ( p = strchr ( date_fmt_buf , ' \n ' ) ) ) * p = 0 ;
ret = GetLocaleInfoA ( lcid , LOCALE_SYEARMONTH , buf , sizeof ( buf ) ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " GetLocaleInfoA(LOCALE_SYEARMONTH) error %d \n " , GetLastError ( ) ) ;
2008-11-20 21:39:48 +01:00
ok ( ! lstrcmpA ( date_fmt_buf , buf ) | | broken ( ! buf [ 0 ] ) /* win9x */ ,
" expected \" %s \" got \" %s \" \n " , date_fmt_buf , buf ) ;
2005-07-27 17:15:02 +02:00
}
2005-07-28 12:16:02 +02:00
static void test_EnumTimeFormatsA ( void )
{
char * p , buf [ 256 ] ;
BOOL ret ;
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
date_fmt_buf [ 0 ] = 0 ;
ret = EnumTimeFormatsA ( enum_datetime_procA , lcid , 0 ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " EnumTimeFormatsA(0) error %d \n " , GetLastError ( ) ) ;
2014-06-17 10:58:46 +02:00
trace ( " EnumTimeFormatsA(0): %s \n " , date_fmt_buf ) ;
2005-07-28 12:16:02 +02:00
/* test the 1st enumerated format */
if ( ( p = strchr ( date_fmt_buf , ' \n ' ) ) ) * p = 0 ;
ret = GetLocaleInfoA ( lcid , LOCALE_STIMEFORMAT , buf , sizeof ( buf ) ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " GetLocaleInfoA(LOCALE_STIMEFORMAT) error %d \n " , GetLastError ( ) ) ;
2005-07-28 12:16:02 +02:00
ok ( ! lstrcmpA ( date_fmt_buf , buf ) , " expected \" %s \" got \" %s \" \n " , date_fmt_buf , buf ) ;
date_fmt_buf [ 0 ] = 0 ;
ret = EnumTimeFormatsA ( enum_datetime_procA , lcid , LOCALE_USE_CP_ACP ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " EnumTimeFormatsA(LOCALE_USE_CP_ACP) error %d \n " , GetLastError ( ) ) ;
2014-06-17 10:58:46 +02:00
trace ( " EnumTimeFormatsA(LOCALE_USE_CP_ACP): %s \n " , date_fmt_buf ) ;
2005-07-28 12:16:02 +02:00
/* test the 1st enumerated format */
if ( ( p = strchr ( date_fmt_buf , ' \n ' ) ) ) * p = 0 ;
ret = GetLocaleInfoA ( lcid , LOCALE_STIMEFORMAT , buf , sizeof ( buf ) ) ;
2006-10-10 01:06:48 +02:00
ok ( ret , " GetLocaleInfoA(LOCALE_STIMEFORMAT) error %d \n " , GetLastError ( ) ) ;
2005-07-28 12:16:02 +02:00
ok ( ! lstrcmpA ( date_fmt_buf , buf ) , " expected \" %s \" got \" %s \" \n " , date_fmt_buf , buf ) ;
}
2015-11-10 15:40:07 +01:00
static void test_EnumTimeFormatsW ( void )
{
LCID lcid = MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) ;
WCHAR bufW [ 256 ] ;
BOOL ret ;
date_fmt_bufW [ 0 ] = 0 ;
ret = EnumTimeFormatsW ( enum_datetime_procW , lcid , 0 ) ;
ok ( ret , " EnumTimeFormatsW(0) error %d \n " , GetLastError ( ) ) ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid , LOCALE_STIMEFORMAT , bufW , ARRAY_SIZE ( bufW ) ) ;
2015-11-10 15:40:07 +01:00
ok ( ret , " GetLocaleInfoW(LOCALE_STIMEFORMAT) error %d \n " , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( date_fmt_bufW , bufW ) , " expected \" %s \" got \" %s \" \n " , wine_dbgstr_w ( date_fmt_bufW ) ,
wine_dbgstr_w ( bufW ) ) ;
date_fmt_bufW [ 0 ] = 0 ;
ret = EnumTimeFormatsW ( enum_datetime_procW , lcid , LOCALE_USE_CP_ACP ) ;
ok ( ret , " EnumTimeFormatsW(LOCALE_USE_CP_ACP) error %d \n " , GetLastError ( ) ) ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid , LOCALE_STIMEFORMAT , bufW , ARRAY_SIZE ( bufW ) ) ;
2015-11-10 15:40:07 +01:00
ok ( ret , " GetLocaleInfoW(LOCALE_STIMEFORMAT) error %d \n " , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( date_fmt_bufW , bufW ) , " expected \" %s \" got \" %s \" \n " , wine_dbgstr_w ( date_fmt_bufW ) ,
wine_dbgstr_w ( bufW ) ) ;
/* TIME_NOSECONDS is Win7+ feature */
date_fmt_bufW [ 0 ] = 0 ;
ret = EnumTimeFormatsW ( enum_datetime_procW , lcid , TIME_NOSECONDS ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_INVALID_FLAGS )
2015-11-10 15:40:09 +01:00
win_skip ( " EnumTimeFormatsW doesn't support TIME_NOSECONDS \n " ) ;
2015-11-10 15:40:07 +01:00
else {
char buf [ 256 ] ;
ok ( ret , " EnumTimeFormatsW(TIME_NOSECONDS) error %d \n " , GetLastError ( ) ) ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( lcid , LOCALE_SSHORTTIME , bufW , ARRAY_SIZE ( bufW ) ) ;
2015-11-10 15:40:07 +01:00
ok ( ret , " GetLocaleInfoW(LOCALE_SSHORTTIME) error %d \n " , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( date_fmt_bufW , bufW ) , " expected \" %s \" got \" %s \" \n " , wine_dbgstr_w ( date_fmt_bufW ) ,
wine_dbgstr_w ( bufW ) ) ;
/* EnumTimeFormatsA doesn't support this flag */
ret = EnumTimeFormatsA ( enum_datetime_procA , lcid , TIME_NOSECONDS ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_FLAGS , " EnumTimeFormatsA(TIME_NOSECONDS) ret %d, error %d \n " , ret ,
GetLastError ( ) ) ;
ret = EnumTimeFormatsA ( NULL , lcid , TIME_NOSECONDS ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_FLAGS , " EnumTimeFormatsA(TIME_NOSECONDS) ret %d, error %d \n " , ret ,
GetLastError ( ) ) ;
2015-11-10 15:40:08 +01:00
2015-11-10 15:40:07 +01:00
/* And it's not supported by GetLocaleInfoA either */
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoA ( lcid , LOCALE_SSHORTTIME , buf , ARRAY_SIZE ( buf ) ) ;
2015-11-10 15:40:07 +01:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_FLAGS , " GetLocaleInfoA(LOCALE_SSHORTTIME) ret %d, error %d \n " , ret ,
GetLastError ( ) ) ;
}
}
2019-11-26 17:56:04 +01:00
2007-04-01 13:16:42 +02:00
static void test_GetCPInfo ( void )
{
BOOL ret ;
CPINFO cpinfo ;
SetLastError ( 0xdeadbeef ) ;
ret = GetCPInfo ( CP_SYMBOL , & cpinfo ) ;
ok ( ! ret , " GetCPInfo(CP_SYMBOL) should fail \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" expected ERROR_INVALID_PARAMETER, got %u \n " , GetLastError ( ) ) ;
2021-11-22 12:43:28 +01:00
memset ( cpinfo . LeadByte , ' - ' , ARRAY_SIZE ( cpinfo . LeadByte ) ) ;
2007-04-01 13:16:42 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = GetCPInfo ( CP_UTF7 , & cpinfo ) ;
2008-05-09 16:35:07 +02:00
if ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER )
{
2014-07-18 11:26:29 +02:00
win_skip ( " Codepage CP_UTF7 is not installed/available \n " ) ;
2008-05-09 16:35:07 +02:00
}
else
{
2021-11-22 12:43:28 +01:00
unsigned int i ;
2008-05-09 16:35:07 +02:00
ok ( ret , " GetCPInfo(CP_UTF7) error %u \n " , GetLastError ( ) ) ;
ok ( cpinfo . DefaultChar [ 0 ] = = 0x3f , " expected 0x3f, got 0x%x \n " , cpinfo . DefaultChar [ 0 ] ) ;
ok ( cpinfo . DefaultChar [ 1 ] = = 0 , " expected 0, got 0x%x \n " , cpinfo . DefaultChar [ 1 ] ) ;
2021-11-22 12:43:29 +01:00
for ( i = 0 ; i < sizeof ( cpinfo . LeadByte ) ; i + + )
ok ( ! cpinfo . LeadByte [ i ] , " expected NUL byte in index %u \n " , i ) ;
2008-05-09 16:35:07 +02:00
ok ( cpinfo . MaxCharSize = = 5 , " expected 5, got 0x%x \n " , cpinfo . MaxCharSize ) ;
}
2007-04-01 13:16:42 +02:00
2021-11-22 12:43:28 +01:00
memset ( cpinfo . LeadByte , ' - ' , ARRAY_SIZE ( cpinfo . LeadByte ) ) ;
2007-04-01 13:16:42 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = GetCPInfo ( CP_UTF8 , & cpinfo ) ;
2008-05-09 16:35:07 +02:00
if ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER )
{
2014-07-18 11:26:29 +02:00
win_skip ( " Codepage CP_UTF8 is not installed/available \n " ) ;
2008-05-09 16:35:07 +02:00
}
else
{
2021-11-22 12:43:28 +01:00
unsigned int i ;
2008-05-09 16:35:07 +02:00
ok ( ret , " GetCPInfo(CP_UTF8) error %u \n " , GetLastError ( ) ) ;
ok ( cpinfo . DefaultChar [ 0 ] = = 0x3f , " expected 0x3f, got 0x%x \n " , cpinfo . DefaultChar [ 0 ] ) ;
ok ( cpinfo . DefaultChar [ 1 ] = = 0 , " expected 0, got 0x%x \n " , cpinfo . DefaultChar [ 1 ] ) ;
2021-11-22 12:43:29 +01:00
for ( i = 0 ; i < sizeof ( cpinfo . LeadByte ) ; i + + )
ok ( ! cpinfo . LeadByte [ i ] , " expected NUL byte in index %u \n " , i ) ;
2008-11-20 21:39:48 +01:00
ok ( cpinfo . MaxCharSize = = 4 | | broken ( cpinfo . MaxCharSize = = 3 ) /* win9x */ ,
" expected 4, got %u \n " , cpinfo . MaxCharSize ) ;
2008-05-09 16:35:07 +02:00
}
2019-11-26 17:56:04 +01:00
if ( pNtGetNlsSectionPtr )
{
CPTABLEINFO table ;
NTSTATUS status ;
void * ptr , * ptr2 ;
SIZE_T size ;
int i ;
for ( i = 0 ; i < 100 ; i + + )
{
ptr = NULL ;
size = 0 ;
status = pNtGetNlsSectionPtr ( i , 9999 , NULL , & ptr , & size ) ;
switch ( i )
{
2020-10-15 20:17:46 +02:00
case 9 : /* sortkeys */
2019-11-26 17:56:04 +01:00
case 13 : /* unknown */
ok ( status = = STATUS_INVALID_PARAMETER_1 | | status = = STATUS_INVALID_PARAMETER_3 , /* vista */
" %u: failed %x \n " , i , status ) ;
break ;
case 10 : /* casemap */
ok ( status = = STATUS_INVALID_PARAMETER_1 | | status = = STATUS_UNSUCCESSFUL ,
" %u: failed %x \n " , i , status ) ;
break ;
case 11 : /* codepage */
case 12 : /* normalization */
ok ( status = = STATUS_OBJECT_NAME_NOT_FOUND , " %u: failed %x \n " , i , status ) ;
break ;
default :
ok ( status = = STATUS_INVALID_PARAMETER_1 , " %u: failed %x \n " , i , status ) ;
break ;
}
}
/* casemap table */
status = pNtGetNlsSectionPtr ( 10 , 0 , NULL , & ptr , & size ) ;
if ( status ! = STATUS_INVALID_PARAMETER_1 )
{
ok ( ! status , " failed %x \n " , status ) ;
ok ( size > 0x1000 & & size < = 0x8000 , " wrong size %lx \n " , size ) ;
status = pNtGetNlsSectionPtr ( 10 , 0 , NULL , & ptr2 , & size ) ;
2021-12-27 00:15:31 +01:00
ok ( ! status , " failed %x \n " , status ) ;
2019-11-26 17:56:04 +01:00
ok ( ptr ! = ptr2 , " got same pointer \n " ) ;
ret = UnmapViewOfFile ( ptr ) ;
2020-10-15 20:17:46 +02:00
ok ( ret , " UnmapViewOfFile failed err %u \n " , GetLastError ( ) ) ;
2019-11-26 17:56:04 +01:00
ret = UnmapViewOfFile ( ptr2 ) ;
2020-10-15 20:17:46 +02:00
ok ( ret , " UnmapViewOfFile failed err %u \n " , GetLastError ( ) ) ;
2019-11-26 17:56:04 +01:00
}
/* codepage tables */
ptr = ( void * ) 0xdeadbeef ;
size = 0xdeadbeef ;
status = pNtGetNlsSectionPtr ( 11 , 437 , NULL , & ptr , & size ) ;
ok ( ! status , " failed %x \n " , status ) ;
ok ( size > 0x10000 & & size < = 0x20000 , " wrong size %lx \n " , size ) ;
memset ( & table , 0xcc , sizeof ( table ) ) ;
if ( pRtlInitCodePageTable )
{
pRtlInitCodePageTable ( ptr , & table ) ;
ok ( table . CodePage = = 437 , " wrong codepage %u \n " , table . CodePage ) ;
ok ( table . MaximumCharacterSize = = 1 , " wrong char size %u \n " , table . MaximumCharacterSize ) ;
ok ( table . DefaultChar = = ' ? ' , " wrong default char %x \n " , table . DefaultChar ) ;
ok ( ! table . DBCSCodePage , " wrong dbcs %u \n " , table . DBCSCodePage ) ;
}
ret = UnmapViewOfFile ( ptr ) ;
2020-10-15 20:17:46 +02:00
ok ( ret , " UnmapViewOfFile failed err %u \n " , GetLastError ( ) ) ;
2019-11-26 17:56:04 +01:00
2019-12-06 17:17:52 +01:00
status = pNtGetNlsSectionPtr ( 11 , 936 , NULL , & ptr , & size ) ;
2019-11-26 17:56:04 +01:00
ok ( ! status , " failed %x \n " , status ) ;
2019-12-06 17:17:52 +01:00
ok ( size > 0x30000 & & size < = 0x40000 , " wrong size %lx \n " , size ) ;
2019-11-26 17:56:04 +01:00
memset ( & table , 0xcc , sizeof ( table ) ) ;
if ( pRtlInitCodePageTable )
{
pRtlInitCodePageTable ( ptr , & table ) ;
2019-12-06 17:17:52 +01:00
ok ( table . CodePage = = 936 , " wrong codepage %u \n " , table . CodePage ) ;
2019-11-26 17:56:04 +01:00
ok ( table . MaximumCharacterSize = = 2 , " wrong char size %u \n " , table . MaximumCharacterSize ) ;
ok ( table . DefaultChar = = ' ? ' , " wrong default char %x \n " , table . DefaultChar ) ;
ok ( table . DBCSCodePage = = TRUE , " wrong dbcs %u \n " , table . DBCSCodePage ) ;
2019-12-06 17:17:52 +01:00
if ( pRtlCustomCPToUnicodeN )
{
static const unsigned char buf [ ] = { 0xbf , 0xb4 , 0xc7 , 0 , 0x78 } ;
static const WCHAR expect [ ] [ 4 ] = { { 0xcccc , 0xcccc , 0xcccc , 0xcccc } ,
{ 0x0000 , 0xcccc , 0xcccc , 0xcccc } ,
{ 0x770b , 0xcccc , 0xcccc , 0xcccc } ,
{ 0x770b , 0x0000 , 0xcccc , 0xcccc } ,
{ 0x770b , 0x003f , 0xcccc , 0xcccc } ,
{ 0x770b , 0x003f , 0x0078 , 0xcccc } } ;
WCHAR wbuf [ 5 ] ;
DWORD i , j , reslen ;
for ( i = 0 ; i < = sizeof ( buf ) ; i + + )
{
memset ( wbuf , 0xcc , sizeof ( wbuf ) ) ;
2020-03-02 07:30:35 +01:00
pRtlCustomCPToUnicodeN ( & table , wbuf , sizeof ( wbuf ) , & reslen , ( char * ) buf , i ) ;
2019-12-06 17:17:52 +01:00
for ( j = 0 ; j < 4 ; j + + ) if ( expect [ i ] [ j ] = = 0xcccc ) break ;
ok ( reslen = = j * sizeof ( WCHAR ) , " %u: wrong len %u \n " , i , reslen ) ;
for ( j = 0 ; j < 4 ; j + + )
ok ( wbuf [ j ] = = expect [ i ] [ j ] , " %u: char %u got %04x \n " , i , j , wbuf [ j ] ) ;
}
}
2019-11-26 17:56:04 +01:00
}
ret = UnmapViewOfFile ( ptr ) ;
2020-10-15 20:17:46 +02:00
ok ( ret , " UnmapViewOfFile failed err %u \n " , GetLastError ( ) ) ;
2019-11-26 17:56:04 +01:00
/* normalization tables */
for ( i = 0 ; i < 100 ; i + + )
{
status = pNtGetNlsSectionPtr ( 12 , i , NULL , & ptr , & size ) ;
switch ( i )
{
case NormalizationC :
case NormalizationD :
case NormalizationKC :
case NormalizationKD :
case 13 : /* IDN */
2020-02-18 11:26:21 +01:00
ok ( ! status , " %u: failed %x \n " , i , status ) ;
2019-11-26 17:56:04 +01:00
if ( status ) break ;
ok ( size > 0x8000 & & size < = 0x30000 , " wrong size %lx \n " , size ) ;
ret = UnmapViewOfFile ( ptr ) ;
2020-10-15 20:17:46 +02:00
ok ( ret , " UnmapViewOfFile failed err %u \n " , GetLastError ( ) ) ;
2019-11-26 17:56:04 +01:00
break ;
default :
ok ( status = = STATUS_OBJECT_NAME_NOT_FOUND , " %u: failed %x \n " , i , status ) ;
break ;
}
}
}
else win_skip ( " NtGetNlsSectionPtr not supported \n " ) ;
2007-04-01 13:16:42 +02:00
}
2010-07-19 20:52:57 +02:00
/*
* The CT_TYPE1 has varied over windows version .
* The current target for correct behavior is windows 7.
* There was a big shift between windows 2000 ( first introduced ) and windows Xp
* Most of the old values below are from windows 2000.
* A smaller subset of changes happened between windows Xp and Window vista / 7
*/
static void test_GetStringTypeW ( void )
{
static const WCHAR blanks [ ] = { 0x9 , 0x20 , 0xa0 , 0x3000 , 0xfeff } ;
static const WORD blanks_new [ ] = { C1_SPACE | C1_CNTRL | C1_BLANK | C1_DEFINED ,
C1_SPACE | C1_BLANK | C1_DEFINED ,
C1_SPACE | C1_BLANK | C1_DEFINED ,
C1_SPACE | C1_BLANK | C1_DEFINED ,
C1_CNTRL | C1_BLANK | C1_DEFINED } ;
static const WORD blanks_old [ ] = { C1_SPACE | C1_CNTRL | C1_BLANK ,
C1_SPACE | C1_BLANK ,
C1_SPACE | C1_BLANK ,
C1_SPACE | C1_BLANK ,
C1_SPACE | C1_BLANK } ;
2013-07-22 11:26:45 +02:00
static const WCHAR undefined [ ] = { 0x378 , 0x379 , 0x5ff , 0xfff8 , 0xfffe } ;
2010-07-19 20:52:57 +02:00
/* Lu, Ll, Lt */
static const WCHAR alpha [ ] = { 0x47 , 0x67 , 0x1c5 } ;
static const WORD alpha_old [ ] = { C1_UPPER | C1_ALPHA ,
C1_LOWER | C1_ALPHA ,
C1_UPPER | C1_LOWER | C1_ALPHA ,
C1_ALPHA } ;
/* Sk, Sk, Mn, So, Me */
static const WCHAR oldpunc [ ] = { 0x2c2 , 0x2e5 , 0x322 , 0x482 , 0x6de ,
/* Sc, Sm, No,*/
0xffe0 , 0xffe9 , 0x2153 } ;
/* Lm, Nl, Cf, 0xad(Cf), 0x1f88 (Lt), Lo, Mc */
static const WCHAR changed [ ] = { 0x2b0 , 0x2160 , 0x600 , 0xad , 0x1f88 , 0x294 , 0x903 } ;
static const WORD changed_old [ ] = { C1_PUNCT , C1_PUNCT , 0 , C1_PUNCT , C1_UPPER | C1_ALPHA , C1_ALPHA , C1_PUNCT } ;
static const WORD changed_xp [ ] = { C1_ALPHA | C1_DEFINED ,
C1_ALPHA | C1_DEFINED ,
C1_CNTRL | C1_DEFINED ,
C1_PUNCT | C1_DEFINED ,
C1_UPPER | C1_LOWER | C1_ALPHA | C1_DEFINED ,
C1_ALPHA | C1_LOWER | C1_DEFINED ,
C1_ALPHA | C1_DEFINED } ;
static const WORD changed_new [ ] = { C1_ALPHA | C1_DEFINED ,
C1_ALPHA | C1_DEFINED ,
C1_CNTRL | C1_DEFINED ,
C1_PUNCT | C1_CNTRL | C1_DEFINED ,
C1_UPPER | C1_LOWER | C1_ALPHA | C1_DEFINED ,
C1_ALPHA | C1_DEFINED ,
C1_DEFINED
} ;
/* Pc, Pd, Ps, Pe, Pi, Pf, Po*/
static const WCHAR punct [ ] = { 0x5f , 0x2d , 0x28 , 0x29 , 0xab , 0xbb , 0x21 } ;
static const WCHAR punct_special [ ] = { 0x24 , 0x2b , 0x3c , 0x3e , 0x5e , 0x60 ,
0x7c , 0x7e , 0xa2 , 0xbe , 0xd7 , 0xf7 } ;
static const WCHAR digit_special [ ] = { 0xb2 , 0xb3 , 0xb9 } ;
static const WCHAR lower_special [ ] = { 0x2071 , 0x207f } ;
static const WCHAR cntrl_special [ ] = { 0x070f , 0x200c , 0x200d ,
0x200e , 0x200f , 0x202a , 0x202b , 0x202c , 0x202d , 0x202e ,
0x206a , 0x206b , 0x206c , 0x206d , 0x206e , 0x206f , 0xfeff ,
0xfff9 , 0xfffa , 0xfffb } ;
static const WCHAR space_special [ ] = { 0x09 , 0x0d , 0x85 } ;
WORD types [ 20 ] ;
2016-02-18 23:39:07 +01:00
WCHAR ch [ 2 ] ;
2015-05-16 15:52:18 +02:00
BOOL ret ;
2010-07-19 20:52:57 +02:00
int i ;
2015-05-16 15:52:18 +02:00
/* NULL src */
SetLastError ( 0xdeadbeef ) ;
ret = GetStringTypeW ( CT_CTYPE1 , NULL , 0 , NULL ) ;
ok ( ! ret , " got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " got error %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = GetStringTypeW ( CT_CTYPE1 , NULL , 0 , types ) ;
ok ( ! ret , " got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " got error %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = GetStringTypeW ( CT_CTYPE1 , NULL , 5 , types ) ;
ok ( ! ret , " got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " got error %d \n " , GetLastError ( ) ) ;
2010-07-19 20:52:57 +02:00
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , blanks , 5 , types ) ;
for ( i = 0 ; i < 5 ; i + + )
ok ( types [ i ] = = blanks_new [ i ] | | broken ( types [ i ] = = blanks_old [ i ] | | broken ( types [ i ] = = 0 ) ) , " incorrect type1 returned for %x -> (%x != %x) \n " , blanks [ i ] , types [ i ] , blanks_new [ i ] ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , alpha , 3 , types ) ;
for ( i = 0 ; i < 3 ; i + + )
ok ( types [ i ] = = ( C1_DEFINED | alpha_old [ i ] ) | | broken ( types [ i ] = = alpha_old [ i ] ) | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x != %x) \n " , alpha [ i ] , types [ i ] , ( C1_DEFINED | alpha_old [ i ] ) ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , undefined , 5 , types ) ;
for ( i = 0 ; i < 5 ; i + + )
ok ( types [ i ] = = 0 , " incorrect types returned for %x -> (%x != 0) \n " , undefined [ i ] , types [ i ] ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , oldpunc , 8 , types ) ;
for ( i = 0 ; i < 8 ; i + + )
ok ( types [ i ] = = C1_DEFINED | | broken ( types [ i ] = = C1_PUNCT ) | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x != %x) \n " , oldpunc [ i ] , types [ i ] , C1_DEFINED ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , changed , 7 , types ) ;
for ( i = 0 ; i < 7 ; i + + )
ok ( types [ i ] = = changed_new [ i ] | | broken ( types [ i ] = = changed_old [ i ] ) | | broken ( types [ i ] = = changed_xp [ i ] ) | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x != %x) \n " , changed [ i ] , types [ i ] , changed_new [ i ] ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , punct , 7 , types ) ;
for ( i = 0 ; i < 7 ; i + + )
ok ( types [ i ] = = ( C1_PUNCT | C1_DEFINED ) | | broken ( types [ i ] = = C1_PUNCT ) | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x != %x) \n " , punct [ i ] , types [ i ] , ( C1_PUNCT | C1_DEFINED ) ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , punct_special , 12 , types ) ;
for ( i = 0 ; i < 12 ; i + + )
ok ( types [ i ] & C1_PUNCT | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x doest not have %x) \n " , punct_special [ i ] , types [ i ] , C1_PUNCT ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , digit_special , 3 , types ) ;
for ( i = 0 ; i < 3 ; i + + )
ok ( types [ i ] & C1_DIGIT | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x doest not have = %x) \n " , digit_special [ i ] , types [ i ] , C1_DIGIT ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , lower_special , 2 , types ) ;
for ( i = 0 ; i < 2 ; i + + )
ok ( types [ i ] & C1_LOWER | | broken ( types [ i ] = = C1_PUNCT ) | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x does not have %x) \n " , lower_special [ i ] , types [ i ] , C1_LOWER ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , cntrl_special , 20 , types ) ;
for ( i = 0 ; i < 20 ; i + + )
ok ( types [ i ] & C1_CNTRL | | broken ( types [ i ] = = ( C1_BLANK | C1_SPACE ) ) | | broken ( types [ i ] = = C1_PUNCT ) | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x does not have %x) \n " , cntrl_special [ i ] , types [ i ] , C1_CNTRL ) ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , space_special , 3 , types ) ;
for ( i = 0 ; i < 3 ; i + + )
ok ( types [ i ] & C1_SPACE | | broken ( types [ i ] = = C1_CNTRL ) | | broken ( types [ i ] = = 0 ) , " incorrect types returned for %x -> (%x does not have %x) \n " , space_special [ i ] , types [ i ] , C1_SPACE ) ;
2014-06-29 18:05:22 +02:00
/* surrogate pairs */
2016-02-18 23:39:07 +01:00
ch [ 0 ] = 0xd800 ;
2014-06-29 18:05:22 +02:00
memset ( types , 0 , sizeof ( types ) ) ;
2016-02-18 23:39:07 +01:00
GetStringTypeW ( CT_CTYPE3 , ch , 1 , types ) ;
2014-06-29 18:05:22 +02:00
if ( types [ 0 ] = = C3_NOTAPPLICABLE )
win_skip ( " C3_HIGHSURROGATE/C3_LOWSURROGATE are not supported. \n " ) ;
else {
ok ( types [ 0 ] = = C3_HIGHSURROGATE , " got %x \n " , types [ 0 ] ) ;
2016-02-18 23:39:07 +01:00
ch [ 0 ] = 0xdc00 ;
2014-06-29 18:05:22 +02:00
memset ( types , 0 , sizeof ( types ) ) ;
2016-02-18 23:39:07 +01:00
GetStringTypeW ( CT_CTYPE3 , ch , 1 , types ) ;
2014-06-29 18:05:22 +02:00
ok ( types [ 0 ] = = C3_LOWSURROGATE , " got %x \n " , types [ 0 ] ) ;
}
2016-02-18 23:39:07 +01:00
/* Zl, Zp categories */
ch [ 0 ] = 0x2028 ;
ch [ 1 ] = 0x2029 ;
memset ( types , 0 , sizeof ( types ) ) ;
GetStringTypeW ( CT_CTYPE1 , ch , 2 , types ) ;
ok ( types [ 0 ] = = ( C1_DEFINED | C1_SPACE ) , " got %x \n " , types [ 0 ] ) ;
ok ( types [ 1 ] = = ( C1_DEFINED | C1_SPACE ) , " got %x \n " , types [ 1 ] ) ;
2016-05-15 09:30:33 +02:00
/* check Arabic range for kashida flag */
for ( ch [ 0 ] = 0x600 ; ch [ 0 ] < = 0x6ff ; ch [ 0 ] + = 1 )
{
types [ 0 ] = 0 ;
ret = GetStringTypeW ( CT_CTYPE3 , ch , 1 , types ) ;
ok ( ret , " %#x: failed %d \n " , ch [ 0 ] , ret ) ;
if ( ch [ 0 ] = = 0x640 ) /* ARABIC TATWEEL (Kashida) */
ok ( types [ 0 ] & C3_KASHIDA , " %#x: type %#x \n " , ch [ 0 ] , types [ 0 ] ) ;
else
ok ( ! ( types [ 0 ] & C3_KASHIDA ) , " %#x: type %#x \n " , ch [ 0 ] , types [ 0 ] ) ;
}
2010-07-19 20:52:57 +02:00
}
2012-04-24 16:11:52 +02:00
static void test_IdnToNameprepUnicode ( void )
{
struct {
2020-02-28 15:25:22 +01:00
int in_len ;
const WCHAR in [ 80 ] ;
DWORD flags ;
2012-04-24 16:11:52 +02:00
DWORD ret ;
2013-11-16 16:31:13 +01:00
DWORD broken_ret ;
2020-02-28 15:25:22 +01:00
const WCHAR out [ 80 ] ;
NTSTATUS status ;
NTSTATUS broken_status ;
2012-04-24 16:11:52 +02:00
} test_data [ ] = {
2020-02-28 15:25:22 +01:00
/* 0 */
{ 5 , L " test " , 0 , 5 , 5 , L " test " } ,
{ 3 , L " a \xe111 z " , 0 , 0 , 0 , L " a \xe111 z " , 0 , STATUS_NO_UNICODE_TRANSLATION } ,
{ 4 , L " t \0 e " , 0 , 0 , 0 , { 0 } , STATUS_NO_UNICODE_TRANSLATION , STATUS_NO_UNICODE_TRANSLATION } ,
2020-03-02 16:28:17 +01:00
{ 1 , L " T " , 0 , 1 , 1 , L " T " } ,
2020-02-28 15:25:22 +01:00
{ 1 , { 0 } , 0 , 0 } ,
/* 5 */
{ 6 , L " -/[] " , 0 , 6 , 6 , L " -/[] " } ,
{ 3 , L " a-a " , IDN_USE_STD3_ASCII_RULES , 3 , 3 , L " a-a " } ,
{ 3 , L " aa- " , IDN_USE_STD3_ASCII_RULES , 0 , 0 , L " aa- " } ,
{ - 1 , L " T \xdf \x130 \x143 \x37a \x6a \x30c \xaa " , 0 , 12 , 12 , L " tssi \x307 \x144 \x3b9 \x1f0 a " } ,
2020-03-02 16:28:17 +01:00
{ 11 , L " t \xad \x34f \x1806 \x180b \x180c \x180d \x200b \x200c \x200d " , 0 , 0 , 2 , L " t " ,
2020-02-28 15:25:22 +01:00
STATUS_NO_UNICODE_TRANSLATION } ,
/* 10 */
{ 2 , { 0x3b0 } , 0 , 2 , 2 , { 0x3b0 } } ,
{ 2 , { 0x380 } , 0 , 0 , 2 , { 0x380 } } ,
{ 2 , { 0x380 } , IDN_ALLOW_UNASSIGNED , 2 , 2 , { 0x380 } } ,
{ 5 , L " a..a " , 0 , 0 , 0 , L " a..a " } ,
{ 3 , L " a. " , 0 , 3 , 3 , L " a. " } ,
/* 15 */
2020-03-02 16:28:17 +01:00
{ 5 , L " T. \x105 .A " , 0 , 5 , 5 , L " t. \x105 .a " } ,
{ 5 , L " T.*.A " , 0 , 5 , 5 , L " T.*.A " } ,
{ 5 , L " X \xff0e .Z " , 0 , 0 , 0 , L " x..z " } ,
2020-02-28 15:25:22 +01:00
{ 63 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " , 0 ,
63 , 63 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " } ,
{ 64 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " , 0 ,
0 , 0 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " } ,
2012-04-24 16:11:52 +02:00
} ;
WCHAR buf [ 1024 ] ;
DWORD i , ret , err ;
ret = pIdnToNameprepUnicode ( 0 , test_data [ 0 ] . in ,
test_data [ 0 ] . in_len , NULL , 0 ) ;
ok ( ret = = test_data [ 0 ] . ret , " ret = %d \n " , ret ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pIdnToNameprepUnicode ( 0 , test_data [ 1 ] . in ,
test_data [ 1 ] . in_len , NULL , 0 ) ;
err = GetLastError ( ) ;
ok ( ret = = test_data [ 1 ] . ret , " ret = %d \n " , ret ) ;
2020-02-28 15:25:22 +01:00
ok ( err = = ret ? 0xdeadbeef : ERROR_INVALID_NAME , " err = %d \n " , err ) ;
2012-04-24 16:11:52 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
ret = pIdnToNameprepUnicode ( 0 , test_data [ 0 ] . in , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-04-24 16:11:52 +02:00
err = GetLastError ( ) ;
ok ( ret = = test_data [ 0 ] . ret , " ret = %d \n " , ret ) ;
ok ( err = = 0xdeadbeef , " err = %d \n " , err ) ;
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
ret = pIdnToNameprepUnicode ( 0 , test_data [ 0 ] . in , - 2 , buf , ARRAY_SIZE ( buf ) ) ;
2012-04-24 16:11:52 +02:00
err = GetLastError ( ) ;
ok ( ret = = 0 , " ret = %d \n " , ret ) ;
ok ( err = = ERROR_INVALID_PARAMETER , " err = %d \n " , err ) ;
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
ret = pIdnToNameprepUnicode ( 0 , test_data [ 0 ] . in , 0 , buf , ARRAY_SIZE ( buf ) ) ;
2012-04-24 16:11:52 +02:00
err = GetLastError ( ) ;
ok ( ret = = 0 , " ret = %d \n " , ret ) ;
ok ( err = = ERROR_INVALID_NAME , " err = %d \n " , err ) ;
ret = pIdnToNameprepUnicode ( IDN_ALLOW_UNASSIGNED | IDN_USE_STD3_ASCII_RULES ,
2018-06-22 19:50:38 +02:00
test_data [ 0 ] . in , - 1 , buf , ARRAY_SIZE ( buf ) ) ;
2012-04-24 16:11:52 +02:00
ok ( ret = = test_data [ 0 ] . ret , " ret = %d \n " , ret ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pIdnToNameprepUnicode ( 0 , NULL , 0 , NULL , 0 ) ;
err = GetLastError ( ) ;
ok ( ret = = 0 , " ret = %d \n " , ret ) ;
ok ( err = = ERROR_INVALID_PARAMETER , " err = %d \n " , err ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pIdnToNameprepUnicode ( 4 , NULL , 0 , NULL , 0 ) ;
err = GetLastError ( ) ;
ok ( ret = = 0 , " ret = %d \n " , ret ) ;
2013-11-01 10:34:01 +01:00
ok ( err = = ERROR_INVALID_FLAGS | | err = = ERROR_INVALID_PARAMETER /* Win8 */ ,
" err = %d \n " , err ) ;
2012-04-24 16:11:52 +02:00
2018-06-22 19:50:38 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + )
2012-04-24 16:11:52 +02:00
{
SetLastError ( 0xdeadbeef ) ;
2020-02-28 15:25:22 +01:00
memset ( buf , 0xcc , sizeof ( buf ) ) ;
2018-06-22 19:50:38 +02:00
ret = pIdnToNameprepUnicode ( test_data [ i ] . flags , test_data [ i ] . in , test_data [ i ] . in_len ,
buf , ARRAY_SIZE ( buf ) ) ;
2012-04-24 16:11:52 +02:00
err = GetLastError ( ) ;
2013-11-16 16:31:13 +01:00
2019-11-28 09:04:33 +01:00
ok ( ret = = test_data [ i ] . ret | | broken ( ret = = test_data [ i ] . broken_ret ) , " %d: ret = %d \n " , i , ret ) ;
2016-02-15 21:06:44 +01:00
2020-02-28 15:25:22 +01:00
if ( ret = = test_data [ i ] . ret )
{
ok ( err = = ret ? 0xdeadbeef : ERROR_INVALID_NAME , " %d: err = %d \n " , i , err ) ;
2020-03-02 16:28:17 +01:00
ok ( ! wcsncmp ( test_data [ i ] . out , buf , ret ) , " %d: buf = %s \n " , i , wine_dbgstr_wn ( buf , ret ) ) ;
2020-02-28 15:25:22 +01:00
}
if ( pRtlNormalizeString )
{
NTSTATUS status ;
int len = ARRAY_SIZE ( buf ) ;
memset ( buf , 0xcc , sizeof ( buf ) ) ;
status = pRtlNormalizeString ( 13 , test_data [ i ] . in , test_data [ i ] . in_len , buf , & len ) ;
ok ( status = = test_data [ i ] . status | | broken ( status = = test_data [ i ] . broken_status ) ,
" %d: failed %x \n " , i , status ) ;
2020-03-02 16:28:17 +01:00
if ( ! status ) ok ( ! wcsnicmp ( test_data [ i ] . out , buf , len ) , " %d: buf = %s \n " , i , wine_dbgstr_wn ( buf , len ) ) ;
2020-02-28 15:25:22 +01:00
}
2012-04-24 16:11:52 +02:00
}
}
2012-04-30 17:27:56 +02:00
static void test_IdnToAscii ( void )
{
struct {
2020-02-28 15:25:22 +01:00
int in_len ;
const WCHAR in [ 80 ] ;
2012-04-30 17:27:56 +02:00
DWORD flags ;
2020-02-28 15:25:22 +01:00
DWORD ret ;
DWORD broken_ret ;
const WCHAR out [ 80 ] ;
2012-04-30 17:27:56 +02:00
} test_data [ ] = {
2020-02-28 15:25:22 +01:00
/* 0 */
{ 5 , L " Test " , 0 , 5 , 5 , L " Test " } ,
{ 5 , L " Te \x017c st " , 0 , 12 , 12 , L " xn--test-cbb " } ,
{ 12 , L " te \x0105 st.te \x017c st " , 0 , 26 , 26 , L " xn--test-cta.xn--test-cbb " } ,
{ 3 , { 0x0105 , ' . ' , 0 } , 0 , 9 , 9 , L " xn--2da. " } ,
{ 10 , L " http://t \x106 " , 0 , 17 , 17 , L " xn--http://t-78a " } ,
/* 5 */
{ - 1 , L " \x4e3a \x8bf4 \x4e0d \x4ed6 \x5011 \x10d \x11b \x305c \x306a " , 0 ,
35 , 35 , L " xn--bea2a1631avbav44tyha32b91egs2t " } ,
{ 2 , L " \x380 " , IDN_ALLOW_UNASSIGNED , 8 , 8 , L " xn--7va " } ,
{ 63 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " , 0 ,
63 , 63 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " } ,
{ 64 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " , 0 , 0 } ,
{ - 1 , L " \xe4 z123456789012345678901234567890123456789012345678901234 " , 0 ,
64 , 64 , L " xn--z123456789012345678901234567890123456789012345678901234-9te " } ,
/* 10 */
{ - 1 , L " \xd803 \xde78 \x46b5 - \xa861 . \x2e87 " , 0 , 28 , 0 , L " xn----bm3an932a1l5d.xn--xvj " } ,
{ - 1 , L " \x06ef \x06ef " , 0 , 9 , 0 , L " xn--cmba " } ,
{ - 1 , L " - \x07e1 \xff61 \x2184 " , 0 , 18 , 0 , L " xn----8cd.xn--r5g " } ,
2012-04-30 17:27:56 +02:00
} ;
WCHAR buf [ 1024 ] ;
DWORD i , ret , err ;
2018-06-22 19:50:38 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + )
2012-04-30 17:27:56 +02:00
{
SetLastError ( 0xdeadbeef ) ;
2020-02-28 15:25:22 +01:00
ret = pIdnToAscii ( test_data [ i ] . flags , test_data [ i ] . in , test_data [ i ] . in_len , buf , ARRAY_SIZE ( buf ) ) ;
2012-04-30 17:27:56 +02:00
err = GetLastError ( ) ;
2020-02-28 15:25:22 +01:00
ok ( ret = = test_data [ i ] . ret | | broken ( ret = = test_data [ i ] . broken_ret ) , " %d: ret = %d \n " , i , ret ) ;
ok ( err = = ret ? 0xdeadbeef : ERROR_INVALID_NAME , " %d: err = %d \n " , i , err ) ;
2020-03-02 16:28:17 +01:00
ok ( ! wcsnicmp ( test_data [ i ] . out , buf , ret ) , " %d: buf = %s \n " , i , wine_dbgstr_wn ( buf , ret ) ) ;
2012-04-30 17:27:56 +02:00
}
}
2012-04-30 17:28:20 +02:00
static void test_IdnToUnicode ( void )
{
struct {
2020-02-28 15:25:22 +01:00
int in_len ;
const WCHAR in [ 80 ] ;
2012-04-30 17:28:20 +02:00
DWORD flags ;
2020-02-28 15:25:22 +01:00
DWORD ret ;
DWORD broken_ret ;
const WCHAR out [ 80 ] ;
2012-04-30 17:28:20 +02:00
} test_data [ ] = {
2020-02-28 15:25:22 +01:00
/* 0 */
{ 5 , L " Tes. " , 0 , 5 , 5 , L " Tes. " } ,
{ 2 , L " \x105 " , 0 , 0 } ,
{ 33 , L " xn--4dbcagdahymbxekheh6e0a7fei0b " , 0 ,
23 , 23 , L " \x05dc \x05de \x05d4 \x05d4 \x05dd \x05e4 \x05e9 \x05d5 \x05d8 \x05dc \x05d0 \x05de \x05d3 \x05d1 \x05e8 \x05d9 \x05dd \x05e2 \x05d1 \x05e8 \x05d9 \x05ea " } ,
{ 34 , L " test.xn--kda9ag5e9jnfsj.xn--pz-fna " , 0 ,
16 , 16 , L " test. \x0105 \x0119 \x015b \x0107 \x0142 \x00f3 \x017c .p \x0119 z " } ,
{ 63 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " , 0 ,
63 , 63 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " } ,
/* 5 */
{ 64 , L " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " , 0 , 0 } ,
{ 8 , L " xn--7va " , IDN_ALLOW_UNASSIGNED , 2 , 2 , L " \x380 " } ,
2020-03-02 16:28:48 +01:00
{ 8 , L " xn--7va " , 0 , 0 , 0 , L " \x380 " } ,
2020-02-28 15:25:22 +01:00
{ - 1 , L " xn----bm3an932a1l5d.xn--xvj " , 0 , 8 , 0 , L " \xd803 \xde78 \x46b5 - \xa861 . \x2e87 " } ,
{ - 1 , L " xn--z123456789012345678901234567890123456789012345678901234-9te " , 0 ,
57 , 57 , L " \xe4 z123456789012345678901234567890123456789012345678901234 " } ,
2020-03-02 16:28:48 +01:00
/* 10 */
2020-02-28 15:25:22 +01:00
{ - 1 , L " foo.bar " , 0 , 8 , 8 , L " foo.bar " } ,
2020-03-02 16:28:48 +01:00
{ - 1 , L " d.xn----dha " , 0 , 5 , 5 , L " d. \x00fc - " } ,
2012-04-30 17:28:20 +02:00
} ;
WCHAR buf [ 1024 ] ;
DWORD i , ret , err ;
2020-02-28 15:25:22 +01:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; i + + )
{
ret = pIdnToUnicode ( test_data [ i ] . flags , test_data [ i ] . in , test_data [ i ] . in_len , NULL , 0 ) ;
ok ( ret = = test_data [ i ] . ret | | broken ( ret = = test_data [ i ] . broken_ret ) , " %d: ret = %d \n " , i , ret ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pIdnToUnicode ( test_data [ i ] . flags , test_data [ i ] . in , test_data [ i ] . in_len , buf , ARRAY_SIZE ( buf ) ) ;
err = GetLastError ( ) ;
ok ( ret = = test_data [ i ] . ret | | broken ( ret = = test_data [ i ] . broken_ret ) , " %d: ret = %d \n " , i , ret ) ;
ok ( err = = ret ? 0xdeadbeef : ERROR_INVALID_NAME , " %d: err = %d \n " , i , err ) ;
ok ( ! wcsncmp ( test_data [ i ] . out , buf , ret ) , " %d: buf = %s \n " , i , wine_dbgstr_wn ( buf , ret ) ) ;
}
}
static BOOL is_idn_error ( const WCHAR * str )
{
WCHAR * p , err [ 256 ] ;
lstrcpyW ( err , str ) ;
for ( p = wcstok ( err , L " [] " ) ; p ; p = wcstok ( NULL , L " [] " ) )
{
if ( * p = = ' B ' | | ! wcscmp ( p , L " V8 " ) ) continue ; /* BiDi */
2020-03-02 16:28:48 +01:00
if ( ! wcscmp ( p , L " V2 " ) ) continue ; /* CheckHyphens */
if ( ! wcscmp ( p , L " V5 " ) ) continue ; /* Combining marks */
2020-02-28 15:25:22 +01:00
return TRUE ;
}
return FALSE ;
}
static void test_Idn ( void )
{
FILE * f ;
if ( ! pIdnToAscii | | ! pIdnToUnicode | | ! pIdnToNameprepUnicode )
2012-04-30 17:28:20 +02:00
{
2020-02-28 15:25:22 +01:00
win_skip ( " Idn support is not available \n " ) ;
2012-04-30 17:28:20 +02:00
return ;
}
2020-02-28 15:25:22 +01:00
test_IdnToNameprepUnicode ( ) ;
test_IdnToAscii ( ) ;
test_IdnToUnicode ( ) ;
/* optionally run the full test file from Unicode.org
* available at https : //www.unicode.org/Public/idna/latest/IdnaTestV2.txt
*/
if ( ( f = fopen ( " IdnaTestV2.txt " , " r " ) ) )
2012-04-30 17:28:20 +02:00
{
2020-02-28 15:25:22 +01:00
char * p , * end , buffer [ 2048 ] ;
WCHAR columns [ 7 ] [ 256 ] , dst [ 256 ] , * expect , * error ;
int i , ret , line = 0 ;
2013-03-28 16:10:44 +01:00
2020-02-28 15:25:22 +01:00
while ( fgets ( buffer , sizeof ( buffer ) , f ) )
{
line + + ;
if ( ( p = strchr ( buffer , ' # ' ) ) ) * p = 0 ;
if ( ! ( p = strtok ( buffer , " ; " ) ) ) continue ;
for ( i = 0 ; i < 7 & & p ; i + + )
{
while ( * p = = ' ' ) p + + ;
for ( end = p + strlen ( p ) ; end > p ; end - - ) if ( end [ - 1 ] ! = ' ' ) break ;
* end = 0 ;
MultiByteToWideChar ( CP_UTF8 , 0 , p , - 1 , columns [ i ] , 256 ) ;
p = strtok ( NULL , " ; " ) ;
}
if ( i < 7 ) continue ;
expect = columns [ 5 ] ;
if ( ! * expect ) expect = columns [ 3 ] ;
if ( ! * expect ) expect = columns [ 1 ] ;
if ( ! * expect ) expect = columns [ 0 ] ;
error = columns [ 6 ] ;
if ( ! * error ) error = columns [ 4 ] ;
if ( ! * error ) error = columns [ 2 ] ;
SetLastError ( 0xdeadbeef ) ;
memset ( dst , 0xcc , sizeof ( dst ) ) ;
ret = pIdnToAscii ( 0 , columns [ 0 ] , - 1 , dst , ARRAY_SIZE ( dst ) ) ;
if ( ! is_idn_error ( error ) )
{
2020-03-02 16:28:41 +01:00
ok ( ret , " line %u: toAscii failed for %s expected %s \n " , line ,
debugstr_w ( columns [ 0 ] ) , debugstr_w ( expect ) ) ;
2020-02-28 15:25:22 +01:00
if ( ret ) ok ( ! wcscmp ( dst , expect ) , " line %u: got %s expected %s \n " ,
line , debugstr_w ( dst ) , debugstr_w ( expect ) ) ;
}
2020-03-02 16:28:41 +01:00
else
{
ok ( ! ret , " line %u: toAscii didn't fail for %s got %s expected error %s \n " ,
line , debugstr_w ( columns [ 0 ] ) , debugstr_w ( dst ) , debugstr_w ( error ) ) ;
}
2020-02-28 15:25:22 +01:00
expect = columns [ 1 ] ;
if ( ! * expect ) expect = columns [ 0 ] ;
error = columns [ 2 ] ;
SetLastError ( 0xdeadbeef ) ;
memset ( dst , 0xcc , sizeof ( dst ) ) ;
2020-03-02 16:28:48 +01:00
ret = pIdnToUnicode ( IDN_USE_STD3_ASCII_RULES , columns [ 0 ] , - 1 , dst , ARRAY_SIZE ( dst ) ) ;
2020-02-28 15:25:22 +01:00
for ( i = 0 ; columns [ 0 ] [ i ] ; i + + ) if ( columns [ 0 ] [ i ] > 0x7f ) break ;
if ( columns [ 0 ] [ i ] )
{
ok ( ! ret , " line %u: didn't fail for unicode chars in %s \n " , line , debugstr_w ( columns [ 0 ] ) ) ;
}
else if ( ! is_idn_error ( error ) )
{
2020-03-02 16:28:48 +01:00
ok ( ret , " line %u: toUnicode failed for %s expected %s \n " , line ,
debugstr_w ( columns [ 0 ] ) , debugstr_w ( expect ) ) ;
2020-02-28 15:25:22 +01:00
if ( ret ) ok ( ! wcscmp ( dst , expect ) , " line %u: got %s expected %s \n " ,
line , debugstr_w ( dst ) , debugstr_w ( expect ) ) ;
}
2020-03-02 16:28:48 +01:00
else
{
ok ( ! ret , " line %u: toUnicode didn't fail for %s got %s expected error %s \n " ,
line , debugstr_w ( columns [ 0 ] ) , debugstr_w ( dst ) , debugstr_w ( error ) ) ;
}
2020-02-28 15:25:22 +01:00
}
fclose ( f ) ;
2012-04-30 17:28:20 +02:00
}
}
2020-02-28 15:25:22 +01:00
2012-07-26 09:20:46 +02:00
static void test_GetLocaleInfoEx ( void )
{
static const WCHAR enW [ ] = { ' e ' , ' n ' , 0 } ;
2016-08-26 22:13:17 +02:00
WCHAR bufferW [ 80 ] , buffer2 [ 80 ] ;
2012-07-26 09:20:46 +02:00
INT ret ;
if ( ! pGetLocaleInfoEx )
{
win_skip ( " GetLocaleInfoEx not supported \n " ) ;
return ;
}
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( enW , LOCALE_SNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
ok ( ret | | broken ( ret = = 0 ) /* Vista */ , " got %d \n " , ret ) ;
if ( ret )
{
static const WCHAR statesW [ ] = { ' U ' , ' n ' , ' i ' , ' t ' , ' e ' , ' d ' , ' ' , ' S ' , ' t ' , ' a ' , ' t ' , ' e ' , ' s ' , 0 } ;
static const WCHAR dummyW [ ] = { ' d ' , ' u ' , ' m ' , ' m ' , ' y ' , 0 } ;
static const WCHAR enusW [ ] = { ' e ' , ' n ' , ' - ' , ' U ' , ' S ' , 0 } ;
static const WCHAR usaW [ ] = { ' U ' , ' S ' , ' A ' , 0 } ;
static const WCHAR enuW [ ] = { ' E ' , ' N ' , ' U ' , 0 } ;
const struct neutralsublang_name_t * ptr = neutralsublang_names ;
DWORD val ;
2012-08-26 07:53:23 +02:00
ok ( ret = = lstrlenW ( bufferW ) + 1 , " got %d \n " , ret ) ;
2012-07-26 09:20:46 +02:00
ok ( ! lstrcmpW ( bufferW , enW ) , " got %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2012-08-26 07:53:23 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = pGetLocaleInfoEx ( enW , LOCALE_SNAME , bufferW , 2 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " got %d, %d \n " , ret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetLocaleInfoEx ( enW , LOCALE_SNAME , NULL , 0 ) ;
ok ( ret = = 3 & & GetLastError ( ) = = 0xdeadbeef , " got %d, %d \n " , ret , GetLastError ( ) ) ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( enusW , LOCALE_SNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-08-26 07:53:23 +02:00
ok ( ret = = lstrlenW ( bufferW ) + 1 , " got %d \n " , ret ) ;
2012-07-26 09:20:46 +02:00
ok ( ! lstrcmpW ( bufferW , enusW ) , " got %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( enW , LOCALE_SABBREVCTRYNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-08-26 07:53:23 +02:00
ok ( ret = = lstrlenW ( bufferW ) + 1 , " got %d \n " , ret ) ;
2012-07-26 09:20:46 +02:00
ok ( ! lstrcmpW ( bufferW , usaW ) , " got %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( enW , LOCALE_SABBREVLANGNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-08-26 07:53:23 +02:00
ok ( ret = = lstrlenW ( bufferW ) + 1 , " got %d \n " , ret ) ;
2012-07-26 09:20:46 +02:00
ok ( ! lstrcmpW ( bufferW , enuW ) , " got %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( enusW , LOCALE_SPARENT , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2017-11-28 19:36:16 +01:00
ok ( ret = = lstrlenW ( bufferW ) + 1 , " got %d \n " , ret ) ;
ok ( ! lstrcmpW ( bufferW , enW ) , " got %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( enW , LOCALE_SPARENT , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2017-11-28 19:36:16 +01:00
ok ( ret = = 1 , " got %d \n " , ret ) ;
ok ( ! bufferW [ 0 ] , " got %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( enW , LOCALE_SPARENT | LOCALE_NOUSEROVERRIDE , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2018-05-22 17:15:01 +02:00
ok ( ret = = 1 , " got %d \n " , ret ) ;
ok ( ! bufferW [ 0 ] , " got %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( enW , LOCALE_SCOUNTRY , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-08-26 07:53:23 +02:00
ok ( ret = = lstrlenW ( bufferW ) + 1 , " got %d \n " , ret ) ;
2013-02-11 00:03:30 +01:00
if ( ( PRIMARYLANGID ( LANGIDFROMLCID ( GetSystemDefaultLCID ( ) ) ) ! = LANG_ENGLISH ) | |
( PRIMARYLANGID ( LANGIDFROMLCID ( GetThreadLocale ( ) ) ) ! = LANG_ENGLISH ) )
{
skip ( " Non-English locale \n " ) ;
}
else
ok ( ! lstrcmpW ( bufferW , statesW ) , " got %s \n " , wine_dbgstr_w ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
bufferW [ 0 ] = 0 ;
2012-08-26 07:53:23 +02:00
SetLastError ( 0xdeadbeef ) ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( dummyW , LOCALE_SNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-08-26 07:53:23 +02:00
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " got %d, error %d \n " , ret , GetLastError ( ) ) ;
2012-07-26 09:20:46 +02:00
while ( * ptr - > name )
{
val = 0 ;
pGetLocaleInfoEx ( ptr - > name , LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER , ( WCHAR * ) & val , sizeof ( val ) / sizeof ( WCHAR ) ) ;
2021-02-04 00:48:35 +01:00
ok ( val = = ptr - > lcid , " %s: got wrong lcid 0x%04x, expected 0x%04x \n " , wine_dbgstr_w ( ptr - > name ) , val , ptr - > lcid ) ;
2012-07-26 11:14:15 +02:00
bufferW [ 0 ] = 0 ;
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( ptr - > name , LOCALE_SNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2012-08-26 07:53:23 +02:00
ok ( ret = = lstrlenW ( bufferW ) + 1 , " %s: got ret value %d \n " , wine_dbgstr_w ( ptr - > name ) , ret ) ;
2012-07-26 11:14:15 +02:00
ok ( ! lstrcmpW ( bufferW , ptr - > name ) , " %s: got wrong LOCALE_SNAME %s \n " , wine_dbgstr_w ( ptr - > name ) , wine_dbgstr_w ( bufferW ) ) ;
2012-07-26 09:20:46 +02:00
ptr + + ;
}
2016-08-26 22:13:17 +02:00
2018-06-22 19:50:38 +02:00
ret = pGetLocaleInfoEx ( LOCALE_NAME_USER_DEFAULT , LOCALE_SNAME , bufferW , ARRAY_SIZE ( bufferW ) ) ;
2016-08-26 22:13:17 +02:00
ok ( ret & & ret = = lstrlenW ( bufferW ) + 1 , " got ret value %d \n " , ret ) ;
2018-06-22 19:50:38 +02:00
ret = GetLocaleInfoW ( GetUserDefaultLCID ( ) , LOCALE_SNAME , buffer2 , ARRAY_SIZE ( buffer2 ) ) ;
2016-08-26 22:13:17 +02:00
ok ( ret & & ret = = lstrlenW ( buffer2 ) + 1 , " got ret value %d \n " , ret ) ;
ok ( ! lstrcmpW ( bufferW , buffer2 ) , " LOCALE_SNAMEs don't match %s %s \n " , wine_dbgstr_w ( bufferW ) , wine_dbgstr_w ( buffer2 ) ) ;
2012-07-26 09:20:46 +02:00
}
}
2012-07-27 05:00:24 +02:00
static void test_IsValidLocaleName ( void )
{
static const WCHAR enusW [ ] = { ' e ' , ' n ' , ' - ' , ' U ' , ' S ' , 0 } ;
2019-11-19 10:10:18 +01:00
static const WCHAR enW [ ] = { ' e ' , ' n ' , 0 } ;
2012-07-27 05:00:24 +02:00
static const WCHAR zzW [ ] = { ' z ' , ' z ' , 0 } ;
2017-01-17 11:51:44 +01:00
static const WCHAR zz_zzW [ ] = { ' z ' , ' z ' , ' - ' , ' Z ' , ' Z ' , 0 } ;
static const WCHAR zzzzW [ ] = { ' z ' , ' z ' , ' z ' , ' z ' , 0 } ;
2012-07-27 05:00:24 +02:00
BOOL ret ;
if ( ! pIsValidLocaleName )
{
win_skip ( " IsValidLocaleName not supported \n " ) ;
return ;
}
ret = pIsValidLocaleName ( enusW ) ;
ok ( ret , " IsValidLocaleName failed \n " ) ;
2019-11-19 10:10:18 +01:00
ret = pIsValidLocaleName ( enW ) ;
ok ( ret | | broken ( ! ret ) , " IsValidLocaleName failed \n " ) ;
2012-07-27 05:00:24 +02:00
ret = pIsValidLocaleName ( zzW ) ;
2017-01-17 11:51:44 +01:00
ok ( ! ret | | broken ( ret ) , " IsValidLocaleName should have failed \n " ) ;
ret = pIsValidLocaleName ( zz_zzW ) ;
ok ( ! ret | | broken ( ret ) , " IsValidLocaleName should have failed \n " ) ;
2012-07-27 05:00:24 +02:00
ret = pIsValidLocaleName ( zzzzW ) ;
ok ( ! ret , " IsValidLocaleName should have failed \n " ) ;
2015-06-09 23:18:47 +02:00
ret = pIsValidLocaleName ( LOCALE_NAME_INVARIANT ) ;
ok ( ret , " IsValidLocaleName failed \n " ) ;
2016-05-15 09:29:43 +02:00
ret = pIsValidLocaleName ( NULL ) ;
ok ( ! ret , " IsValidLocaleName should have failed \n " ) ;
2012-07-27 05:00:24 +02:00
}
2012-11-04 11:06:40 +01:00
static void test_CompareStringOrdinal ( void )
2012-10-31 09:56:39 +01:00
{
INT ret ;
WCHAR test1 [ ] = { ' t ' , ' e ' , ' s ' , ' t ' , 0 } ;
WCHAR test2 [ ] = { ' T ' , ' e ' , ' S ' , ' t ' , 0 } ;
WCHAR test3 [ ] = { ' t ' , ' e ' , ' s ' , ' t ' , ' 3 ' , 0 } ;
WCHAR null1 [ ] = { ' a ' , 0 , ' a ' , 0 } ;
WCHAR null2 [ ] = { ' a ' , 0 , ' b ' , 0 } ;
WCHAR bills1 [ ] = { ' b ' , ' i ' , ' l ' , ' l ' , ' \' ' , ' s ' , 0 } ;
WCHAR bills2 [ ] = { ' b ' , ' i ' , ' l ' , ' l ' , ' s ' , 0 } ;
WCHAR coop1 [ ] = { ' c ' , ' o ' , ' - ' , ' o ' , ' p ' , 0 } ;
WCHAR coop2 [ ] = { ' c ' , ' o ' , ' o ' , ' p ' , 0 } ;
WCHAR nonascii1 [ ] = { 0x0102 , 0 } ;
WCHAR nonascii2 [ ] = { 0x0201 , 0 } ;
2016-06-14 10:08:46 +02:00
WCHAR ch1 , ch2 ;
2012-10-31 09:56:39 +01:00
if ( ! pCompareStringOrdinal )
{
win_skip ( " CompareStringOrdinal not supported \n " ) ;
return ;
}
/* Check errors */
SetLastError ( 0xdeadbeef ) ;
ret = pCompareStringOrdinal ( NULL , 0 , NULL , 0 , FALSE ) ;
ok ( ! ret , " Got %u, expected 0 \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " Got %x, expected %x \n " , GetLastError ( ) , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pCompareStringOrdinal ( test1 , - 1 , NULL , 0 , FALSE ) ;
ok ( ! ret , " Got %u, expected 0 \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " Got %x, expected %x \n " , GetLastError ( ) , ERROR_INVALID_PARAMETER ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pCompareStringOrdinal ( NULL , 0 , test1 , - 1 , FALSE ) ;
ok ( ! ret , " Got %u, expected 0 \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " Got %x, expected %x \n " , GetLastError ( ) , ERROR_INVALID_PARAMETER ) ;
/* Check case */
ret = pCompareStringOrdinal ( test1 , - 1 , test1 , - 1 , FALSE ) ;
ok ( ret = = CSTR_EQUAL , " Got %u, expected %u \n " , ret , CSTR_EQUAL ) ;
ret = pCompareStringOrdinal ( test1 , - 1 , test2 , - 1 , FALSE ) ;
ok ( ret = = CSTR_GREATER_THAN , " Got %u, expected %u \n " , ret , CSTR_GREATER_THAN ) ;
ret = pCompareStringOrdinal ( test2 , - 1 , test1 , - 1 , FALSE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
ret = pCompareStringOrdinal ( test1 , - 1 , test2 , - 1 , TRUE ) ;
ok ( ret = = CSTR_EQUAL , " Got %u, expected %u \n " , ret , CSTR_EQUAL ) ;
/* Check different sizes */
ret = pCompareStringOrdinal ( test1 , 3 , test2 , - 1 , TRUE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
ret = pCompareStringOrdinal ( test1 , - 1 , test2 , 3 , TRUE ) ;
ok ( ret = = CSTR_GREATER_THAN , " Got %u, expected %u \n " , ret , CSTR_GREATER_THAN ) ;
/* Check null character */
ret = pCompareStringOrdinal ( null1 , 3 , null2 , 3 , FALSE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
ret = pCompareStringOrdinal ( null1 , 3 , null2 , 3 , TRUE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
ret = pCompareStringOrdinal ( test1 , 5 , test3 , 5 , FALSE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
ret = pCompareStringOrdinal ( test1 , 4 , test1 , 5 , FALSE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
/* Check ordinal behaviour */
ret = pCompareStringOrdinal ( bills1 , - 1 , bills2 , - 1 , FALSE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
ret = pCompareStringOrdinal ( coop2 , - 1 , coop1 , - 1 , FALSE ) ;
ok ( ret = = CSTR_GREATER_THAN , " Got %u, expected %u \n " , ret , CSTR_GREATER_THAN ) ;
ret = pCompareStringOrdinal ( nonascii1 , - 1 , nonascii2 , - 1 , FALSE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
ret = pCompareStringOrdinal ( nonascii1 , - 1 , nonascii2 , - 1 , TRUE ) ;
ok ( ret = = CSTR_LESS_THAN , " Got %u, expected %u \n " , ret , CSTR_LESS_THAN ) ;
2016-06-14 10:08:46 +02:00
for ( ch1 = 0 ; ch1 < 512 ; ch1 + + )
{
for ( ch2 = 0 ; ch2 < 1024 ; ch2 + + )
{
int diff = ch1 - ch2 ;
ret = pCompareStringOrdinal ( & ch1 , 1 , & ch2 , 1 , FALSE ) ;
ok ( ret = = ( diff > 0 ? CSTR_GREATER_THAN : diff < 0 ? CSTR_LESS_THAN : CSTR_EQUAL ) ,
" wrong result %d %04x %04x \n " , ret , ch1 , ch2 ) ;
diff = pRtlUpcaseUnicodeChar ( ch1 ) - pRtlUpcaseUnicodeChar ( ch2 ) ;
ret = pCompareStringOrdinal ( & ch1 , 1 , & ch2 , 1 , TRUE ) ;
ok ( ret = = ( diff > 0 ? CSTR_GREATER_THAN : diff < 0 ? CSTR_LESS_THAN : CSTR_EQUAL ) ,
" wrong result %d %04x %04x \n " , ret , ch1 , ch2 ) ;
}
}
2012-10-31 09:56:39 +01:00
}
2014-07-11 04:36:18 +02:00
static void test_GetGeoInfo ( void )
{
char buffA [ 20 ] ;
INT ret ;
if ( ! pGetGeoInfoA )
{
win_skip ( " GetGeoInfo is not available. \n " ) ;
return ;
}
/* unassigned id */
SetLastError ( 0xdeadbeef ) ;
ret = pGetGeoInfoA ( 344 , GEO_ISO2 , NULL , 0 , 0 ) ;
ok ( ret = = 0 , " got %d \n " , ret ) ;
2018-03-29 19:28:57 +02:00
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER | |
broken ( GetLastError ( ) = = 0xdeadbeef /* Win10 */ ) , " got %d \n " , GetLastError ( ) ) ;
2014-07-11 04:36:18 +02:00
ret = pGetGeoInfoA ( 203 , GEO_ISO2 , NULL , 0 , 0 ) ;
ok ( ret = = 3 , " got %d \n " , ret ) ;
ret = pGetGeoInfoA ( 203 , GEO_ISO3 , NULL , 0 , 0 ) ;
ok ( ret = = 4 , " got %d \n " , ret ) ;
ret = pGetGeoInfoA ( 203 , GEO_ISO2 , buffA , 3 , 0 ) ;
ok ( ret = = 3 , " got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " RU " ) , " got %s \n " , buffA ) ;
/* buffer pointer not NULL, length is 0 - return required length */
buffA [ 0 ] = ' a ' ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetGeoInfoA ( 203 , GEO_ISO2 , buffA , 0 , 0 ) ;
ok ( ret = = 3 , " got %d \n " , ret ) ;
ok ( buffA [ 0 ] = = ' a ' , " got %c \n " , buffA [ 0 ] ) ;
ret = pGetGeoInfoA ( 203 , GEO_ISO3 , buffA , 4 , 0 ) ;
ok ( ret = = 4 , " got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " RUS " ) , " got %s \n " , buffA ) ;
/* shorter buffer */
SetLastError ( 0xdeadbeef ) ;
buffA [ 1 ] = buffA [ 2 ] = 0 ;
ret = pGetGeoInfoA ( 203 , GEO_ISO2 , buffA , 2 , 0 ) ;
ok ( ret = = 0 , " got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " RU " ) , " got %s \n " , buffA ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " got %d \n " , GetLastError ( ) ) ;
2019-12-02 22:39:44 +01:00
/* GEO_NATION returns GEOID in a string form, but only for GEOCLASS_NATION-type IDs */
ret = pGetGeoInfoA ( 203 , GEO_NATION , buffA , 20 , 0 ) ; /* GEOCLASS_NATION */
ok ( ret = = 4 , " GEO_NATION of nation: expected 4, got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " 203 " ) , " GEO_NATION of nation: expected 203, got %s \n " , buffA ) ;
2014-07-11 04:36:18 +02:00
buffA [ 0 ] = 0 ;
2019-12-02 22:39:44 +01:00
ret = pGetGeoInfoA ( 39070 , GEO_NATION , buffA , 20 , 0 ) ; /* GEOCLASS_REGION */
ok ( ret = = 0 , " GEO_NATION of region: expected 0, got %d \n " , ret ) ;
ok ( * buffA = = 0 , " GEO_NATION of region: expected empty string, got %s \n " , buffA ) ;
buffA [ 0 ] = 0 ;
ret = pGetGeoInfoA ( 333 , GEO_NATION , buffA , 20 , 0 ) ; /* LOCATION_BOTH internal Wine type */
ok ( ret = = 0 | |
broken ( ret = = 4 ) /* Win7 and older */ ,
" GEO_NATION of LOCATION_BOTH: expected 0, got %d \n " , ret ) ;
ok ( * buffA = = 0 | |
broken ( ! strcmp ( buffA , " 333 " ) ) /* Win7 and older */ ,
" GEO_NATION of LOCATION_BOTH: expected empty string, got %s \n " , buffA ) ;
/* GEO_ID is like GEO_NATION but works for any ID */
buffA [ 0 ] = 0 ;
ret = pGetGeoInfoA ( 203 , GEO_ID , buffA , 20 , 0 ) ; /* GEOCLASS_NATION */
if ( ret = = 0 )
win_skip ( " GEO_ID not supported. \n " ) ;
else
{
ok ( ret = = 4 , " GEO_ID: expected 4, got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " 203 " ) , " GEO_ID: expected 203, got %s \n " , buffA ) ;
ret = pGetGeoInfoA ( 47610 , GEO_ID , buffA , 20 , 0 ) ; /* GEOCLASS_REGION */
ok ( ret = = 6 , " got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " 47610 " ) , " got %s \n " , buffA ) ;
ret = pGetGeoInfoA ( 333 , GEO_ID , buffA , 20 , 0 ) ; /* LOCATION_BOTH internal Wine type */
ok ( ret = = 4 , " got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " 333 " ) , " got %s \n " , buffA ) ;
}
2014-07-11 04:36:18 +02:00
2014-07-15 03:51:32 +02:00
/* GEO_PARENT */
buffA [ 0 ] = 0 ;
ret = pGetGeoInfoA ( 203 , GEO_PARENT , buffA , 20 , 0 ) ;
if ( ret = = 0 )
win_skip ( " GEO_PARENT not supported. \n " ) ;
else
{
ok ( ret = = 6 , " got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " 47609 " ) , " got %s \n " , buffA ) ;
}
2014-07-11 04:36:18 +02:00
buffA [ 0 ] = 0 ;
ret = pGetGeoInfoA ( 203 , GEO_ISO_UN_NUMBER , buffA , 20 , 0 ) ;
if ( ret = = 0 )
win_skip ( " GEO_ISO_UN_NUMBER not supported. \n " ) ;
else
{
ok ( ret = = 4 , " got %d \n " , ret ) ;
ok ( ! strcmp ( buffA , " 643 " ) , " got %s \n " , buffA ) ;
}
/* try invalid type value */
SetLastError ( 0xdeadbeef ) ;
2018-03-29 19:28:50 +02:00
ret = pGetGeoInfoA ( 203 , GEO_ID + 1 , NULL , 0 , 0 ) ;
2014-07-11 04:36:18 +02:00
ok ( ret = = 0 , " got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS , " got %d \n " , GetLastError ( ) ) ;
}
2014-07-15 03:51:32 +02:00
static int geoidenum_count ;
static BOOL CALLBACK test_geoid_enumproc ( GEOID geoid )
{
INT ret = pGetGeoInfoA ( geoid , GEO_ISO2 , NULL , 0 , 0 ) ;
ok ( ret = = 3 , " got %d for %d \n " , ret , geoid ) ;
/* valid geoid starts at 2 */
ok ( geoid > = 2 , " got geoid %d \n " , geoid ) ;
2014-07-15 04:41:02 +02:00
2014-07-15 03:51:32 +02:00
return geoidenum_count + + < 5 ;
}
static BOOL CALLBACK test_geoid_enumproc2 ( GEOID geoid )
{
geoidenum_count + + ;
return TRUE ;
}
static void test_EnumSystemGeoID ( void )
{
BOOL ret ;
if ( ! pEnumSystemGeoID )
{
win_skip ( " EnumSystemGeoID is not available. \n " ) ;
return ;
}
SetLastError ( 0xdeadbeef ) ;
ret = pEnumSystemGeoID ( GEOCLASS_NATION , 0 , NULL ) ;
ok ( ! ret , " got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " got %d \n " , GetLastError ( ) ) ;
2014-07-15 04:41:02 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = pEnumSystemGeoID ( GEOCLASS_NATION + 1 , 0 , test_geoid_enumproc ) ;
ok ( ! ret , " got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS , " got %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pEnumSystemGeoID ( GEOCLASS_NATION + 1 , 0 , NULL ) ;
ok ( ! ret , " got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " got %d \n " , GetLastError ( ) ) ;
2014-07-15 03:51:32 +02:00
ret = pEnumSystemGeoID ( GEOCLASS_NATION , 0 , test_geoid_enumproc ) ;
ok ( ret , " got %d \n " , ret ) ;
2014-10-02 10:30:06 +02:00
/* only the first level is enumerated, not the whole hierarchy */
2014-07-15 04:41:02 +02:00
geoidenum_count = 0 ;
ret = pEnumSystemGeoID ( GEOCLASS_NATION , 39070 , test_geoid_enumproc2 ) ;
if ( ret = = 0 )
win_skip ( " Parent GEOID is not supported in EnumSystemGeoID. \n " ) ;
else
ok ( ret & & geoidenum_count > 0 , " got %d, count %d \n " , ret , geoidenum_count ) ;
2014-07-15 03:51:32 +02:00
geoidenum_count = 0 ;
ret = pEnumSystemGeoID ( GEOCLASS_REGION , 39070 , test_geoid_enumproc2 ) ;
if ( ret = = 0 )
2014-07-18 11:26:29 +02:00
win_skip ( " GEOCLASS_REGION is not supported in EnumSystemGeoID. \n " ) ;
2014-07-15 03:51:32 +02:00
else
{
ok ( ret & & geoidenum_count > 0 , " got %d, count %d \n " , ret , geoidenum_count ) ;
geoidenum_count = 0 ;
ret = pEnumSystemGeoID ( GEOCLASS_REGION , 0 , test_geoid_enumproc2 ) ;
ok ( ret & & geoidenum_count > 0 , " got %d, count %d \n " , ret , geoidenum_count ) ;
}
2019-11-18 03:27:24 +01:00
geoidenum_count = 0 ;
ret = pEnumSystemGeoID ( GEOCLASS_ALL , 39070 , test_geoid_enumproc2 ) ;
if ( ret = = 0 )
win_skip ( " GEOCLASS_ALL is not supported in EnumSystemGeoID. \n " ) ;
else
{
ok ( ret & & geoidenum_count > 0 , " got %d, count %d \n " , ret , geoidenum_count ) ;
geoidenum_count = 0 ;
ret = pEnumSystemGeoID ( GEOCLASS_ALL , 0 , test_geoid_enumproc2 ) ;
ok ( ret & & geoidenum_count > 0 , " got %d, count %d \n " , ret , geoidenum_count ) ;
}
2014-07-15 03:51:32 +02:00
}
2015-08-26 09:06:07 +02:00
struct invariant_entry {
const char * name ;
int id ;
2017-01-17 11:51:45 +01:00
const char * expect , * expect2 ;
2015-08-26 09:06:07 +02:00
} ;
# 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 " } ,
2017-01-17 11:51:45 +01:00
{ X ( LOCALE_SABBREVCTRYNAME ) , " IVC " , " " } ,
2015-08-26 09:06:07 +02:00
{ 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 ) , " \x00a4 " } ,
{ 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 */
2017-01-17 11:51:45 +01:00
ok ( ret = = len | | ( ptr - > expect2 & & ret = = strlen ( ptr - > expect2 ) + 1 ) ,
" For id %d, expected ret == %d, got %d, error %d \n " ,
2015-08-26 09:06:07 +02:00
ptr - > id , len , ret , GetLastError ( ) ) ;
2017-01-17 11:51:45 +01:00
ok ( ! strcmp ( buffer , ptr - > expect ) | | ( ptr - > expect2 & & ! strcmp ( buffer , ptr - > expect2 ) ) ,
" For id %d, Expected %s, got '%s' \n " ,
2015-08-26 09:06:07 +02:00
ptr - > id , ptr - > expect , buffer ) ;
}
ptr + + ;
}
2017-01-17 11:51:46 +01:00
if ( ( LANGIDFROMLCID ( GetSystemDefaultLCID ( ) ) ! = MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) ) | |
( LANGIDFROMLCID ( GetThreadLocale ( ) ) ! = MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) ) )
2015-08-26 09:06:07 +02:00
{
2017-01-17 11:51:46 +01:00
skip ( " Non US-English locale \n " ) ;
2015-08-26 09:06:07 +02:00
}
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 " ;
2019-11-19 09:58:20 +01:00
static const char sortms [ ] = " Maths Alphanumerics " ;
2015-08-26 09:06:07 +02:00
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 ) ) ;
2019-11-19 09:58:20 +01:00
ok ( ret , " Failed err %d \n " , GetLastError ( ) ) ;
ok ( ! strcmp ( buffer , sortm ) | | ! strcmp ( buffer , sortd ) | | ! strcmp ( buffer , sortms ) , " Got '%s' \n " , buffer ) ;
2015-08-26 09:06:07 +02:00
}
}
2016-01-17 10:00:55 +01:00
static void test_GetSystemPreferredUILanguages ( void )
{
BOOL ret ;
2020-05-22 12:42:14 +02:00
NTSTATUS status ;
2021-12-07 12:55:21 +01:00
ULONG i , count , size , size_id , size_name , size_buffer ;
2016-01-17 10:00:55 +01:00
WCHAR * buffer ;
if ( ! pGetSystemPreferredUILanguages )
{
win_skip ( " GetSystemPreferredUILanguages is not available. \n " ) ;
return ;
}
/* (in)valid first parameter */
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( 0 , & count , NULL , & size ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_FULL_LANGUAGE , & count , NULL , & size ) ;
ok ( ! ret , " Expected GetSystemPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected error ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID | MUI_FULL_LANGUAGE , & count , NULL , & size ) ;
ok ( ! ret , " Expected GetSystemPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected error ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID | MUI_LANGUAGE_NAME , & count , NULL , & size ) ;
ok ( ! ret , " Expected GetSystemPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected error ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID | MUI_MACHINE_LANGUAGE_SETTINGS , & count , NULL , & size ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 5 = = 1 , " Expected size (%d) %% 5 == 1 \n " , size ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_NAME | MUI_MACHINE_LANGUAGE_SETTINGS , & count , NULL , & size ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
/* second parameter
* ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , NULL , NULL , & size ) ;
* - > unhandled exception c0000005
*/
/* invalid third parameter */
size = 1 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , & count , NULL , & size ) ;
ok ( ! ret , " Expected GetSystemPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected error ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
/* fourth parameter
* ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , & count , NULL , NULL ) ;
* - > unhandled exception c0000005
*/
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size_id = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , & count , NULL , & size_id ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size_id % 5 = = 1 , " Expected size (%d) %% 5 == 1 \n " , size_id ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size_name = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_NAME , & count , NULL , & size_name ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size_name % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size_name ) ;
size_buffer = max ( size_id , size_name ) ;
if ( ! size_buffer )
{
2016-06-23 13:31:03 +02:00
skip ( " No valid buffer size \n " ) ;
2016-01-17 10:00:55 +01:00
return ;
}
buffer = HeapAlloc ( GetProcessHeap ( ) , 0 , size_buffer * sizeof ( WCHAR ) ) ;
if ( ! buffer )
{
2016-01-20 08:42:45 +01:00
skip ( " Failed to allocate memory for %d chars \n " , size_buffer ) ;
2016-01-17 10:00:55 +01:00
return ;
}
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size = size_buffer ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( 0 , & count , buffer , & size ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
if ( ret & & size % 6 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size = size_buffer ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buffer , & size ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 5 = = 1 , " Expected size (%d) %% 5 == 1 \n " , size ) ;
if ( ret & & size % 5 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
2021-12-07 12:55:21 +01:00
for ( i = 0 ; buffer [ i ] ; i + + )
ok ( ( ' 0 ' < = buffer [ i ] & & buffer [ i ] < = ' 9 ' ) | |
( ' A ' < = buffer [ i ] & & buffer [ i ] < = ' F ' ) ,
" MUI_LANGUAGE_ID [%d] is bad in %s \n " , i , wine_dbgstr_w ( buffer ) ) ;
2016-01-17 10:00:55 +01:00
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size = size_buffer ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_NAME , & count , buffer , & size ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
if ( ret & & size % 5 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-01-17 10:00:55 +01:00
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_MACHINE_LANGUAGE_SETTINGS , & count , NULL , & size ) ;
ok ( ret , " Expected GetSystemPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
if ( ret & & size % 6 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
2020-05-22 12:42:14 +02:00
/* ntdll version is the same, but apparently takes an extra second parameter */
count = 0 ;
size = size_buffer ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
status = pRtlGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , 0 , & count , buffer , & size ) ;
ok ( ! status , " got %x \n " , status ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 5 = = 1 , " Expected size (%d) %% 5 == 1 \n " , size ) ;
if ( ret & & size % 5 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
count = 0 ;
size = size_buffer ;
status = pRtlGetSystemPreferredUILanguages ( MUI_LANGUAGE_NAME , 0 , & count , buffer , & size ) ;
ok ( ! status , " got %x \n " , status ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
if ( ret & & size % 5 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
count = 0 ;
size = 0 ;
status = pRtlGetSystemPreferredUILanguages ( MUI_MACHINE_LANGUAGE_SETTINGS , 0 , & count , NULL , & size ) ;
ok ( ! status , " got %x \n " , status ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
if ( ret & & size % 6 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
2020-03-02 07:30:40 +01:00
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buffer , & size ) ;
ok ( ! ret , " Expected GetSystemPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INSUFFICIENT_BUFFER = = GetLastError ( ) ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( size = = size_id , " expected %u, got %u \n " , size_id , size ) ;
2016-01-17 10:00:55 +01:00
size = 1 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buffer , & size ) ;
ok ( ! ret , " Expected GetSystemPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INSUFFICIENT_BUFFER = = GetLastError ( ) ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
2020-03-02 07:30:40 +01:00
ok ( size = = size_id , " expected %u, got %u \n " , size_id , size ) ;
2016-01-17 10:00:55 +01:00
size = size_id - 1 ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buffer , & size ) ;
ok ( ! ret , " Expected GetSystemPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INSUFFICIENT_BUFFER = = GetLastError ( ) ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
2020-03-02 07:30:40 +01:00
ok ( size = = size_id , " expected %u, got %u \n " , size_id , size ) ;
2016-01-17 10:00:55 +01:00
size = size_id - 2 ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetSystemPreferredUILanguages ( 0 , & count , buffer , & size ) ;
ok ( ! ret , " Expected GetSystemPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INSUFFICIENT_BUFFER = = GetLastError ( ) ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
2020-03-02 07:30:40 +01:00
ok ( size = = size_id + 2 | | size = = size_id + 1 /* before win10 1809 */ , " expected %u, got %u \n " , size_id + 2 , size ) ;
2016-05-29 17:44:12 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , buffer ) ;
2016-01-17 10:00:55 +01:00
}
2016-04-29 10:14:35 +02:00
static void test_GetThreadPreferredUILanguages ( void )
{
BOOL ret ;
2020-05-22 12:42:14 +02:00
NTSTATUS status ;
2020-03-02 07:30:40 +01:00
ULONG count , size , size_id ;
2016-04-29 10:14:35 +02:00
WCHAR * buf ;
if ( ! pGetThreadPreferredUILanguages )
{
win_skip ( " GetThreadPreferredUILanguages is not available. \n " ) ;
return ;
}
size = count = 0 ;
ret = pGetThreadPreferredUILanguages ( MUI_LANGUAGE_ID | MUI_UI_FALLBACK , & count , NULL , & size ) ;
ok ( ret , " got %u \n " , GetLastError ( ) ) ;
ok ( count , " expected count > 0 \n " ) ;
ok ( size , " expected size > 0 \n " ) ;
count = 0 ;
buf = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , size * sizeof ( WCHAR ) ) ;
ret = pGetThreadPreferredUILanguages ( MUI_LANGUAGE_ID | MUI_UI_FALLBACK , & count , buf , & size ) ;
ok ( ret , " got %u \n " , GetLastError ( ) ) ;
ok ( count , " expected count > 0 \n " ) ;
2020-03-02 07:30:40 +01:00
size_id = count = 0 ;
ret = pGetThreadPreferredUILanguages ( MUI_LANGUAGE_ID , & count , NULL , & size_id ) ;
ok ( ret , " got %u \n " , GetLastError ( ) ) ;
ok ( count , " expected count > 0 \n " ) ;
ok ( size_id , " expected size > 0 \n " ) ;
ok ( size_id < = size , " expected size > 0 \n " ) ;
2020-05-22 12:42:14 +02:00
/* ntdll function is the same */
size_id = count = 0 ;
status = pRtlGetThreadPreferredUILanguages ( MUI_LANGUAGE_ID , & count , NULL , & size_id ) ;
ok ( ! status , " got %x \n " , status ) ;
ok ( count , " expected count > 0 \n " ) ;
ok ( size_id , " expected size > 0 \n " ) ;
ok ( size_id < = size , " expected size > 0 \n " ) ;
2020-03-02 07:30:40 +01:00
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetThreadPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buf , & size ) ;
ok ( ! ret , " Expected GetThreadPreferredUILanguages to fail \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( size = = size_id , " expected %u, got %u \n " , size_id , size ) ;
size = 1 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetThreadPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buf , & size ) ;
ok ( ! ret , " Expected GetThreadPreferredUILanguages to fail \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( size = = size_id , " expected %u, got %u \n " , size_id , size ) ;
size = size_id - 1 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetThreadPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buf , & size ) ;
ok ( ! ret , " Expected GetThreadPreferredUILanguages to fail \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( size = = size_id , " expected %u, got %u \n " , size_id , size ) ;
size = size_id - 2 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetThreadPreferredUILanguages ( 0 , & count , buf , & size ) ;
ok ( ! ret , " Expected GetThreadPreferredUILanguages to fail \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
2022-01-27 20:16:01 +01:00
todo_wine
2020-03-02 07:30:40 +01:00
ok ( size = = size_id | | size = = size_id - 1 /* before win10 1809 */ , " expected %u, got %u \n " , size_id , size ) ;
2016-04-29 10:14:35 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , buf ) ;
}
2016-10-18 20:00:12 +02:00
static void test_GetUserPreferredUILanguages ( void )
{
BOOL ret ;
2020-05-22 12:42:14 +02:00
NTSTATUS status ;
2016-10-18 20:00:12 +02:00
ULONG count , size , size_id , size_name , size_buffer ;
WCHAR * buffer ;
if ( ! pGetUserPreferredUILanguages )
{
win_skip ( " GetUserPreferredUILanguages is not available. \n " ) ;
return ;
}
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_FULL_LANGUAGE , & count , NULL , & size ) ;
ok ( ! ret , " Expected GetUserPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected error ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_ID | MUI_FULL_LANGUAGE , & count , NULL , & size ) ;
ok ( ! ret , " Expected GetUserPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected error ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_ID | MUI_MACHINE_LANGUAGE_SETTINGS , & count , NULL , & size ) ;
ok ( ! ret , " Expected GetUserPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected error ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
size = 1 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_ID , & count , NULL , & size ) ;
ok ( ! ret , " Expected GetUserPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected error ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-10-18 20:00:12 +02:00
size_id = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_ID , & count , NULL , & size_id ) ;
ok ( ret , " Expected GetUserPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size_id % 5 = = 1 , " Expected size (%d) %% 5 == 1 \n " , size_id ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-10-18 20:00:12 +02:00
size_name = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_NAME , & count , NULL , & size_name ) ;
ok ( ret , " Expected GetUserPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size_name % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size_name ) ;
size_buffer = max ( size_id , size_name ) ;
if ( ! size_buffer )
{
skip ( " No valid buffer size \n " ) ;
return ;
}
2020-05-22 12:42:14 +02:00
/* ntdll version is the same, but apparently takes an extra second parameter */
count = 0 ;
size_id = 0 ;
SetLastError ( 0xdeadbeef ) ;
status = pRtlGetUserPreferredUILanguages ( MUI_LANGUAGE_ID , 0 , & count , NULL , & size_id ) ;
ok ( ! status , " got %x \n " , status ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size_id % 5 = = 1 , " Expected size (%d) %% 5 == 1 \n " , size_id ) ;
2016-10-18 20:00:12 +02:00
buffer = HeapAlloc ( GetProcessHeap ( ) , 0 , size_buffer * sizeof ( WCHAR ) ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-10-18 20:00:12 +02:00
size = size_buffer ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( 0 , & count , buffer , & size ) ;
ok ( ret , " Expected GetUserPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
if ( ret & & size % 6 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-10-18 20:00:12 +02:00
size = size_buffer ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buffer , & size ) ;
ok ( ret , " Expected GetUserPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 5 = = 1 , " Expected size (%d) %% 5 == 1 \n " , size ) ;
if ( ret & & size % 5 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-10-18 20:00:12 +02:00
size = size_buffer ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_NAME , & count , buffer , & size ) ;
ok ( ret , " Expected GetUserPreferredUILanguages to succeed \n " ) ;
ok ( count , " Expected count > 0 \n " ) ;
ok ( size % 6 = = 1 , " Expected size (%d) %% 6 == 1 \n " , size ) ;
if ( ret & & size % 5 = = 1 )
ok ( ! buffer [ size - 2 ] & & ! buffer [ size - 1 ] ,
" Expected last two WCHARs being empty, got 0x%x 0x%x \n " ,
buffer [ size - 2 ] , buffer [ size - 1 ] ) ;
size = 1 ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buffer , & size ) ;
ok ( ! ret , " Expected GetUserPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INSUFFICIENT_BUFFER = = GetLastError ( ) ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
size = size_id - 1 ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( MUI_LANGUAGE_ID , & count , buffer , & size ) ;
ok ( ! ret , " Expected GetUserPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INSUFFICIENT_BUFFER = = GetLastError ( ) ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
2020-03-02 07:30:37 +01:00
count = 0 ;
2016-10-18 20:00:12 +02:00
size = size_id - 2 ;
memset ( buffer , 0x5a , size_buffer * sizeof ( WCHAR ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserPreferredUILanguages ( 0 , & count , buffer , & size ) ;
ok ( ! ret , " Expected GetUserPreferredUILanguages to fail \n " ) ;
ok ( ERROR_INSUFFICIENT_BUFFER = = GetLastError ( ) ,
" Expected error ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
HeapFree ( GetProcessHeap ( ) , 0 , buffer ) ;
}
2018-03-13 15:09:45 +01:00
static void test_FindNLSStringEx ( void )
{
INT res ;
static WCHAR en_simpsimpW [ ] = { ' S ' , ' i ' , ' m ' , ' p ' , ' l ' , ' e ' , ' S ' , ' i ' , ' m ' , ' p ' , ' l ' , ' e ' , 0 } ;
static WCHAR en_simpW [ ] = { ' S ' , ' i ' , ' m ' , ' p ' , ' l ' , ' e ' , 0 } ;
static WCHAR comb_s_accent1W [ ] = { 0x1e69 , ' o ' , ' u ' , ' r ' , ' c ' , ' e ' , 0 } ;
static WCHAR comb_s_accent2W [ ] = { 0x0073 , 0x323 , 0x307 , ' o ' , ' u ' , ' r ' , ' c ' , ' e ' , 0 } ;
static WCHAR comb_q_accent1W [ ] = { 0x0071 , 0x0307 , 0x323 , ' u ' , ' o ' , ' t ' , ' e ' , 0 } ;
static WCHAR comb_q_accent2W [ ] = { 0x0071 , 0x0323 , 0x307 , ' u ' , ' o ' , ' t ' , ' e ' , 0 } ;
struct test_data {
const WCHAR * locale ;
DWORD flags ;
WCHAR * src ;
INT src_size ;
WCHAR * value ;
INT val_size ;
INT found ;
INT expected_ret ;
INT expected_found ;
int todo ;
BOOL broken_vista_servers ;
} ;
static struct test_data test_arr [ ] =
{
2018-06-22 19:50:38 +02:00
{ localeW , FIND_FROMSTART , en_simpsimpW , ARRAY_SIZE ( en_simpsimpW ) - 1 ,
en_simpW , ARRAY_SIZE ( en_simpW ) - 1 , 0 , 0 , 6 , 0 , FALSE } ,
{ localeW , FIND_FROMEND , en_simpsimpW , ARRAY_SIZE ( en_simpsimpW ) - 1 ,
en_simpW , ARRAY_SIZE ( en_simpW ) - 1 , 0 , 6 , 6 , 0 , FALSE } ,
{ localeW , FIND_STARTSWITH , en_simpsimpW , ARRAY_SIZE ( en_simpsimpW ) - 1 ,
en_simpW , ARRAY_SIZE ( en_simpW ) - 1 , 0 , 0 , 6 , 0 , FALSE } ,
{ localeW , FIND_ENDSWITH , en_simpsimpW , ARRAY_SIZE ( en_simpsimpW ) - 1 ,
en_simpW , ARRAY_SIZE ( en_simpW ) - 1 , 0 , 6 , 6 , 0 , FALSE } ,
{ localeW , FIND_FROMSTART , comb_s_accent1W , ARRAY_SIZE ( comb_s_accent1W ) - 1 ,
comb_s_accent2W , ARRAY_SIZE ( comb_s_accent2W ) - 1 , 0 , 0 , 6 , 1 , TRUE } ,
{ localeW , FIND_FROMSTART , comb_q_accent1W , ARRAY_SIZE ( comb_q_accent1W ) - 1 ,
comb_q_accent2W , ARRAY_SIZE ( comb_q_accent2W ) - 1 , 0 , 0 , 7 , 1 , FALSE } ,
2018-03-13 15:09:45 +01:00
{ 0 }
} ;
struct test_data * ptest ;
if ( ! pFindNLSStringEx )
{
win_skip ( " FindNLSStringEx is not available. \n " ) ;
return ;
}
SetLastError ( 0xdeadbeef ) ;
res = pFindNLSStringEx ( invalidW , FIND_FROMSTART , fooW , 3 , fooW ,
3 , NULL , NULL , NULL , 0 ) ;
ok ( res , " Expected failure of FindNLSStringEx. Return value was %d \n " , res ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected ERROR_INVALID_PARAMETER as last error; got %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
res = pFindNLSStringEx ( localeW , FIND_FROMSTART , NULL , 3 , fooW , 3 ,
NULL , NULL , NULL , 0 ) ;
ok ( res , " Expected failure of FindNLSStringEx. Return value was %d \n " , res ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected ERROR_INVALID_PARAMETER as last error; got %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
res = pFindNLSStringEx ( localeW , FIND_FROMSTART , fooW , - 5 , fooW , 3 ,
NULL , NULL , NULL , 0 ) ;
ok ( res , " Expected failure of FindNLSStringEx. Return value was %d \n " , res ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected ERROR_INVALID_PARAMETER as last error; got %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
res = pFindNLSStringEx ( localeW , FIND_FROMSTART , fooW , 3 , NULL , 3 ,
NULL , NULL , NULL , 0 ) ;
ok ( res , " Expected failure of FindNLSStringEx. Return value was %d \n " , res ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected ERROR_INVALID_PARAMETER as last error; got %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
res = pFindNLSStringEx ( localeW , FIND_FROMSTART , fooW , 3 , fooW , - 5 ,
NULL , NULL , NULL , 0 ) ;
ok ( res , " Expected failure of FindNLSStringEx. Return value was %d \n " , res ) ;
ok ( ERROR_INVALID_PARAMETER = = GetLastError ( ) ,
" Expected ERROR_INVALID_PARAMETER as last error; got %d \n " , GetLastError ( ) ) ;
for ( ptest = test_arr ; ptest - > src ! = NULL ; ptest + + )
{
todo_wine_if ( ptest - > todo )
{
res = pFindNLSStringEx ( ptest - > locale , ptest - > flags , ptest - > src , ptest - > src_size ,
ptest - > value , ptest - > val_size , & ptest - > found , NULL , NULL , 0 ) ;
if ( ptest - > broken_vista_servers )
{
ok ( res = = ptest - > expected_ret | | /* Win 7 onwards */
broken ( res = = - 1 ) , /* Win Vista, Server 2003 and 2008 */
" Expected FindNLSStringEx to return %d. Returned value was %d \n " ,
ptest - > expected_ret , res ) ;
ok ( ptest - > found = = ptest - > expected_found | | /* Win 7 onwards */
broken ( ptest - > found = = 0 ) , /* Win Vista, Server 2003 and 2008 */
" Expected FindNLSStringEx to output %d. Value was %d \n " ,
ptest - > expected_found , ptest - > found ) ;
}
else
{
ok ( res = = ptest - > expected_ret ,
" Expected FindNLSStringEx to return %d. Returned value was %d \n " ,
ptest - > expected_ret , res ) ;
ok ( ptest - > found = = ptest - > expected_found ,
" Expected FindNLSStringEx to output %d. Value was %d \n " ,
ptest - > expected_found , ptest - > found ) ;
}
}
}
}
2018-10-30 07:31:57 +01:00
static void test_FindStringOrdinal ( void )
{
static const WCHAR abc123aBcW [ ] = { ' a ' , ' b ' , ' c ' , ' 1 ' , ' 2 ' , ' 3 ' , ' a ' , ' B ' , ' c ' , 0 } ;
static const WCHAR abcW [ ] = { ' a ' , ' b ' , ' c ' , 0 } ;
static const WCHAR aBcW [ ] = { ' a ' , ' B ' , ' c ' , 0 } ;
static const WCHAR aaaW [ ] = { ' a ' , ' a ' , ' a ' , 0 } ;
static const struct
{
DWORD flag ;
const WCHAR * src ;
INT src_size ;
const WCHAR * val ;
INT val_size ;
BOOL ignore_case ;
INT ret ;
DWORD err ;
}
tests [ ] =
{
/* Invalid */
{ 1 , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , - 1 , ERROR_INVALID_FLAGS } ,
{ FIND_FROMSTART , NULL , ARRAY_SIZE ( abc123aBcW ) - 1 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , - 1 ,
ERROR_INVALID_PARAMETER } ,
{ FIND_FROMSTART , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , NULL , ARRAY_SIZE ( abcW ) - 1 , FALSE , - 1 ,
ERROR_INVALID_PARAMETER } ,
{ FIND_FROMSTART , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , NULL , 0 , FALSE , - 1 , ERROR_INVALID_PARAMETER } ,
{ FIND_FROMSTART , NULL , 0 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , - 1 , ERROR_INVALID_PARAMETER } ,
{ FIND_FROMSTART , NULL , 0 , NULL , 0 , FALSE , - 1 , ERROR_INVALID_PARAMETER } ,
/* Case-insensitive */
{ FIND_FROMSTART , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , 0 , NO_ERROR } ,
{ FIND_FROMEND , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , 0 , NO_ERROR } ,
{ FIND_STARTSWITH , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , 0 , NO_ERROR } ,
{ FIND_ENDSWITH , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , - 1 , NO_ERROR } ,
/* Case-sensitive */
{ FIND_FROMSTART , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , aBcW , ARRAY_SIZE ( aBcW ) - 1 , TRUE , 0 , NO_ERROR } ,
{ FIND_FROMEND , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , aBcW , ARRAY_SIZE ( aBcW ) - 1 , TRUE , 6 , NO_ERROR } ,
{ FIND_STARTSWITH , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , aBcW , ARRAY_SIZE ( aBcW ) - 1 , TRUE , 0 , NO_ERROR } ,
{ FIND_ENDSWITH , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , aBcW , ARRAY_SIZE ( aBcW ) - 1 , TRUE , 6 , NO_ERROR } ,
/* Other */
{ FIND_FROMSTART , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , aaaW , ARRAY_SIZE ( aaaW ) - 1 , FALSE , - 1 , NO_ERROR } ,
{ FIND_FROMSTART , abc123aBcW , - 1 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , 0 , NO_ERROR } ,
{ FIND_FROMSTART , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , abcW , - 1 , FALSE , 0 , NO_ERROR } ,
{ FIND_FROMSTART , abc123aBcW , 0 , abcW , ARRAY_SIZE ( abcW ) - 1 , FALSE , - 1 , NO_ERROR } ,
{ FIND_FROMSTART , abc123aBcW , ARRAY_SIZE ( abc123aBcW ) - 1 , abcW , 0 , FALSE , 0 , NO_ERROR } ,
{ FIND_FROMSTART , abc123aBcW , 0 , abcW , 0 , FALSE , 0 , NO_ERROR } ,
} ;
INT ret ;
DWORD err ;
INT i ;
if ( ! pFindStringOrdinal )
{
win_skip ( " FindStringOrdinal is not available. \n " ) ;
return ;
}
for ( i = 0 ; i < ARRAY_SIZE ( tests ) ; i + + )
{
SetLastError ( 0xdeadbeef ) ;
ret = pFindStringOrdinal ( tests [ i ] . flag , tests [ i ] . src , tests [ i ] . src_size , tests [ i ] . val , tests [ i ] . val_size ,
tests [ i ] . ignore_case ) ;
err = GetLastError ( ) ;
ok ( ret = = tests [ i ] . ret , " Item %d expected %d, got %d \n " , i , tests [ i ] . ret , ret ) ;
ok ( err = = tests [ i ] . err , " Item %d expected %#x, got %#x \n " , i , tests [ i ] . err , err ) ;
}
}
2018-03-31 11:24:53 +02:00
static void test_SetThreadUILanguage ( void )
{
LANGID res ;
if ( ! pGetThreadUILanguage )
{
win_skip ( " GetThreadUILanguage isn't implemented, skipping SetThreadUILanguage tests for version < Vista \n " ) ;
return ; /* BTW SetThreadUILanguage is present on winxp/2003 but doesn`t set the LANGID anyway when tested */
}
res = pSetThreadUILanguage ( 0 ) ;
2018-03-31 11:26:24 +02:00
ok ( res = = pGetThreadUILanguage ( ) , " expected %d got %d \n " , pGetThreadUILanguage ( ) , res ) ;
2018-03-31 11:24:53 +02:00
res = pSetThreadUILanguage ( MAKELANGID ( LANG_DUTCH , SUBLANG_DUTCH_BELGIAN ) ) ;
ok ( res = = MAKELANGID ( LANG_DUTCH , SUBLANG_DUTCH_BELGIAN ) ,
" expected %d got %d \n " , MAKELANGID ( LANG_DUTCH , SUBLANG_DUTCH_BELGIAN ) , res ) ;
res = pSetThreadUILanguage ( 0 ) ;
todo_wine ok ( res = = MAKELANGID ( LANG_DUTCH , SUBLANG_DUTCH_BELGIAN ) ,
" expected %d got %d \n " , MAKELANGID ( LANG_DUTCH , SUBLANG_DUTCH_BELGIAN ) , res ) ;
}
2020-02-04 14:31:45 +01:00
static int put_utf16 ( WCHAR * str , unsigned int c )
{
if ( c < 0x10000 )
{
* str = c ;
return 1 ;
}
c - = 0x10000 ;
str [ 0 ] = 0xd800 | ( c > > 10 ) ;
str [ 1 ] = 0xdc00 | ( c & 0x3ff ) ;
return 2 ;
}
/* read a Unicode string from NormalizationTest.txt format; helper for test_NormalizeString */
static int read_str ( char * str , WCHAR res [ 32 ] )
{
int pos = 0 ;
char * end ;
while ( * str & & pos < 31 )
{
unsigned int c = strtoul ( str , & end , 16 ) ;
pos + = put_utf16 ( res + pos , c ) ;
while ( * end = = ' ' ) end + + ;
str = end ;
}
res [ pos ] = 0 ;
return pos ;
}
2018-04-09 20:38:00 +02:00
static void test_NormalizeString ( void )
{
/* part 0: specific cases */
/* LATIN CAPITAL LETTER D WITH DOT ABOVE */
static const WCHAR part0_str1 [ ] = { 0x1e0a , 0 } ;
static const WCHAR part0_nfd1 [ ] = { 0x0044 , 0x0307 , 0 } ;
/* LATIN CAPITAL LETTER D, COMBINING DOT BELOW, COMBINING DOT ABOVE */
static const WCHAR part0_str2 [ ] = { 0x0044 , 0x0323 , 0x0307 , 0 } ;
static const WCHAR part0_nfc2 [ ] = { 0x1e0c , 0x0307 , 0 } ;
/* LATIN CAPITAL LETTER D, COMBINING HORN, COMBINING DOT BELOW, COMBINING DOT ABOVE */
static const WCHAR part0_str3 [ ] = { 0x0044 , 0x031b , 0x0323 , 0x0307 , 0 } ;
static const WCHAR part0_nfc3 [ ] = { 0x1e0c , 0x031b , 0x0307 , 0 } ;
/* LATIN CAPITAL LETTER D, COMBINING HORN, COMBINING DOT BELOW, COMBINING DOT ABOVE */
static const WCHAR part0_str4 [ ] = { 0x0044 , 0x031b , 0x0323 , 0x0307 , 0 } ;
static const WCHAR part0_nfc4 [ ] = { 0x1e0c , 0x031b , 0x0307 , 0 } ;
/*
* HEBREW ACCENT SEGOL , HEBREW POINT PATAH , HEBREW POINT DAGESH OR MAPIQ ,
* HEBREW ACCENT MERKHA , HEBREW POINT SHEVA , HEBREW PUNCTUATION PASEQ ,
* HEBREW MARK UPPER DOT , HEBREW ACCENT DEHI
*/
static const WCHAR part0_str5 [ ] = { 0x0592 , 0x05B7 , 0x05BC , 0x05A5 , 0x05B0 , 0x05C0 , 0x05C4 , 0x05AD , 0 } ;
static const WCHAR part0_nfc5 [ ] = { 0x05B0 , 0x05B7 , 0x05BC , 0x05A5 , 0x0592 , 0x05C0 , 0x05AD , 0x05C4 , 0 } ;
/*
* HEBREW POINT QAMATS , HEBREW POINT HOLAM , HEBREW POINT HATAF SEGOL ,
* HEBREW ACCENT ETNAHTA , HEBREW PUNCTUATION SOF PASUQ , HEBREW POINT SHEVA ,
* HEBREW ACCENT ILUY , HEBREW ACCENT QARNEY PARA
*/
static const WCHAR part0_str6 [ ] = { 0x05B8 , 0x05B9 , 0x05B1 , 0x0591 , 0x05C3 , 0x05B0 , 0x05AC , 0x059F , 0 } ;
static const WCHAR part0_nfc6 [ ] = { 0x05B1 , 0x05B8 , 0x05B9 , 0x0591 , 0x05C3 , 0x05B0 , 0x05AC , 0x059F , 0 } ;
/* LATIN CAPITAL LETTER D WITH DOT BELOW */
static const WCHAR part0_str8 [ ] = { 0x1E0C , 0 } ;
static const WCHAR part0_nfd8 [ ] = { 0x0044 , 0x0323 , 0 } ;
/* LATIN CAPITAL LETTER D WITH DOT ABOVE, COMBINING DOT BELOW */
static const WCHAR part0_str9 [ ] = { 0x1E0A , 0x0323 , 0 } ;
static const WCHAR part0_nfc9 [ ] = { 0x1E0C , 0x0307 , 0 } ;
static const WCHAR part0_nfd9 [ ] = { 0x0044 , 0x0323 , 0x0307 , 0 } ;
/* LATIN CAPITAL LETTER D WITH DOT BELOW, COMBINING DOT ABOVE */
static const WCHAR part0_str10 [ ] = { 0x1E0C , 0x0307 , 0 } ;
static const WCHAR part0_nfd10 [ ] = { 0x0044 , 0x0323 , 0x0307 , 0 } ;
/* LATIN CAPITAL LETTER E WITH MACRON AND GRAVE, COMBINING MACRON */
static const WCHAR part0_str11 [ ] = { 0x1E14 , 0x0304 , 0 } ;
static const WCHAR part0_nfd11 [ ] = { 0x0045 , 0x0304 , 0x0300 , 0x0304 , 0 } ;
/* LATIN CAPITAL LETTER E WITH MACRON, COMBINING GRAVE ACCENT */
static const WCHAR part0_str12 [ ] = { 0x0112 , 0x0300 , 0 } ;
static const WCHAR part0_nfc12 [ ] = { 0x1E14 , 0 } ;
static const WCHAR part0_nfd12 [ ] = { 0x0045 , 0x0304 , 0x0300 , 0 } ;
/* part 1: character by character */
/* DIAERESIS */
static const WCHAR part1_str1 [ ] = { 0x00a8 , 0 } ;
static const WCHAR part1_nfkc1 [ ] = { 0x0020 , 0x0308 , 0 } ;
/* VULGAR FRACTION ONE QUARTER */
static const WCHAR part1_str2 [ ] = { 0x00bc , 0 } ;
static const WCHAR part1_nfkc2 [ ] = { 0x0031 , 0x2044 , 0x0034 , 0 } ;
/* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
static const WCHAR part1_str3 [ ] = { 0x00ca , 0 } ;
static const WCHAR part1_nfd3 [ ] = { 0x0045 , 0x0302 , 0 } ;
/* MODIFIER LETTER SMALL GAMMA */
static const WCHAR part1_str4 [ ] = { 0x02e0 , 0 } ;
static const WCHAR part1_nfkc4 [ ] = { 0x0263 , 0 } ;
/* CYRILLIC CAPITAL LETTER IE WITH GRAVE */
static const WCHAR part1_str5 [ ] = { 0x0400 , 0 } ;
static const WCHAR part1_nfd5 [ ] = { 0x0415 , 0x0300 , 0 } ;
/* CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT */
static const WCHAR part1_str6 [ ] = { 0x0476 , 0 } ;
static const WCHAR part1_nfd6 [ ] = { 0x0474 , 0x030F , 0 } ;
/* ARABIC LIGATURE HAH WITH JEEM INITIAL FORM */
static const WCHAR part1_str7 [ ] = { 0xFCA9 , 0 } ;
static const WCHAR part1_nfkc7 [ ] = { 0x062D , 0x062C , 0 } ;
/* GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA */
static const WCHAR part1_str8 [ ] = { 0x1F42 , 0 } ;
static const WCHAR part1_nfd8 [ ] = { 0x03BF , 0x0313 , 0x0300 , 0 } ;
/* QUADRUPLE PRIME */
static const WCHAR part1_str9 [ ] = { 0x2057 , 0 } ;
static const WCHAR part1_nfkc9 [ ] = { 0x2032 , 0x2032 , 0x2032 , 0x2032 , 0 } ;
/* KATAKANA-HIRAGANA VOICED SOUND MARK */
static const WCHAR part1_str10 [ ] = { 0x309B , 0 } ;
static const WCHAR part1_nfkc10 [ ] = { 0x20 , 0x3099 , 0 } ;
2019-02-08 11:41:26 +01:00
/* ANGSTROM SIGN */
static const WCHAR part1_str11 [ ] = { 0x212B , 0 } ;
static const WCHAR part1_nfc11 [ ] = { 0xC5 , 0 } ;
static const WCHAR part1_nfd11 [ ] = { ' A ' , 0x030A , 0 } ;
2020-02-03 13:23:38 +01:00
static const WCHAR composite_src [ ] =
{
0x008a , 0x008e , 0x009a , 0x009e , 0x009f , 0x00c0 , 0x00c1 , 0x00c2 ,
0x00c3 , 0x00c4 , 0x00c5 , 0x00c7 , 0x00c8 , 0x00c9 , 0x00ca , 0x00cb ,
0x00cc , 0x00cd , 0x00ce , 0x00cf , 0x00d1 , 0x00d2 , 0x00d3 , 0x00d4 ,
0x00d5 , 0x00d6 , 0x00d8 , 0x00d9 , 0x00da , 0x00db , 0x00dc , 0x00dd ,
0x00e0 , 0x00e1 , 0x00e2 , 0x00e3 , 0x00e4 , 0x00e5 , 0x00e7 , 0x00e8 ,
0x00e9 , 0x00ea , 0x00eb , 0x00ec , 0x00ed , 0x00ee , 0x00ef , 0x00f1 ,
0x00f2 , 0x00f3 , 0x00f4 , 0x00f5 , 0x00f6 , 0x00f8 , 0x00f9 , 0x00fa ,
0x00fb , 0x00fc , 0x00fd , 0x00ff , 0x212b
} ;
2018-04-09 20:38:00 +02:00
struct test_data_normal {
const WCHAR * str ;
const WCHAR * expected [ 4 ] ;
} ;
static const struct test_data_normal test_arr [ ] =
{
2019-02-08 11:41:27 +01:00
{ part0_str1 , { part0_str1 , part0_nfd1 , part0_str1 , part0_nfd1 } } ,
{ part0_str2 , { part0_nfc2 , part0_str2 , part0_nfc2 , part0_str2 } } ,
{ part0_str3 , { part0_nfc3 , part0_str3 , part0_nfc3 , part0_str3 } } ,
{ part0_str4 , { part0_nfc4 , part0_str4 , part0_nfc4 , part0_str4 } } ,
{ part0_str5 , { part0_nfc5 , part0_nfc5 , part0_nfc5 , part0_nfc5 } } ,
{ part0_str6 , { part0_nfc6 , part0_nfc6 , part0_nfc6 , part0_nfc6 } } ,
{ part0_str8 , { part0_str8 , part0_nfd8 , part0_str8 , part0_nfd8 } } ,
{ part0_str9 , { part0_nfc9 , part0_nfd9 , part0_nfc9 , part0_nfd9 } } ,
{ part0_str10 , { part0_str10 , part0_nfd10 , part0_str10 , part0_nfd10 } } ,
{ part0_str11 , { part0_str11 , part0_nfd11 , part0_str11 , part0_nfd11 } } ,
{ part0_str12 , { part0_nfc12 , part0_nfd12 , part0_nfc12 , part0_nfd12 } } ,
{ part1_str1 , { part1_str1 , part1_str1 , part1_nfkc1 , part1_nfkc1 } } ,
{ part1_str2 , { part1_str2 , part1_str2 , part1_nfkc2 , part1_nfkc2 } } ,
{ part1_str3 , { part1_str3 , part1_nfd3 , part1_str3 , part1_nfd3 } } ,
{ part1_str4 , { part1_str4 , part1_str4 , part1_nfkc4 , part1_nfkc4 } } ,
{ part1_str5 , { part1_str5 , part1_nfd5 , part1_str5 , part1_nfd5 } } ,
{ part1_str6 , { part1_str6 , part1_nfd6 , part1_str6 , part1_nfd6 } } ,
{ part1_str7 , { part1_str7 , part1_str7 , part1_nfkc7 , part1_nfkc7 } } ,
{ part1_str8 , { part1_str8 , part1_nfd8 , part1_str8 , part1_nfd8 } } ,
{ part1_str9 , { part1_str9 , part1_str9 , part1_nfkc9 , part1_nfkc9 } } ,
{ part1_str10 , { part1_str10 , part1_str10 , part1_nfkc10 , part1_nfkc10 } } ,
{ part1_str11 , { part1_nfc11 , part1_nfd11 , part1_nfc11 , part1_nfd11 } } ,
2018-04-09 20:38:00 +02:00
{ 0 }
} ;
const struct test_data_normal * ptest = test_arr ;
const int norm_forms [ ] = { NormalizationC , NormalizationD , NormalizationKC , NormalizationKD } ;
2020-02-03 13:23:38 +01:00
WCHAR dst [ 256 ] ;
2020-02-04 14:31:45 +01:00
BOOLEAN ret ;
2019-11-21 10:43:46 +01:00
NTSTATUS status ;
2020-02-03 13:23:38 +01:00
int dstlen , str_cmp , i , j ;
2020-02-04 14:31:45 +01:00
FILE * f ;
2018-04-09 20:38:00 +02:00
if ( ! pNormalizeString )
{
win_skip ( " NormalizeString is not available. \n " ) ;
return ;
}
2019-11-21 10:43:46 +01:00
if ( ! pRtlNormalizeString ) win_skip ( " RtlNormalizeString is not available. \n " ) ;
2018-04-09 20:38:00 +02:00
/*
* For each string , first test passing - 1 as srclen to NormalizeString ,
* thereby assuming a null - terminating string in src , and then test passing
* explicitly the string length .
* Do that for all 4 normalization forms .
*/
while ( ptest - > str )
{
for ( i = 0 ; i < 4 ; i + + )
{
2020-02-03 13:23:38 +01:00
SetLastError ( 0xdeadbeef ) ;
2019-02-08 11:41:22 +01:00
dstlen = pNormalizeString ( norm_forms [ i ] , ptest - > str , - 1 , NULL , 0 ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen > lstrlenW ( ptest - > str ) , " %s:%d: wrong len %d / %d \n " ,
2020-02-03 13:23:38 +01:00
wine_dbgstr_w ( ptest - > str ) , i , dstlen , lstrlenW ( ptest - > str ) ) ;
ok ( GetLastError ( ) = = ERROR_SUCCESS , " %s:%d: got error %u \n " ,
wine_dbgstr_w ( ptest - > str ) , i , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , ptest - > str , - 1 , dst , dstlen ) ;
ok ( GetLastError ( ) = = ERROR_SUCCESS , " %s:%d: got error %u \n " ,
wine_dbgstr_w ( ptest - > str ) , i , GetLastError ( ) ) ;
ok ( dstlen = = lstrlenW ( dst ) + 1 , " %s:%d: Copied length differed: was %d, should be %d \n " ,
wine_dbgstr_w ( ptest - > str ) , i , dstlen , lstrlenW ( dst ) + 1 ) ;
str_cmp = wcsncmp ( ptest - > expected [ i ] , dst , dstlen + 1 ) ;
ok ( str_cmp = = 0 , " %s:%d: string incorrect got %s expect %s \n " , wine_dbgstr_w ( ptest - > str ) , i ,
wine_dbgstr_w ( dst ) , wine_dbgstr_w ( ptest - > expected [ i ] ) ) ;
2019-02-08 11:41:22 +01:00
2019-11-19 15:36:22 +01:00
dstlen = pNormalizeString ( norm_forms [ i ] , ptest - > str , lstrlenW ( ptest - > str ) , NULL , 0 ) ;
2020-02-03 13:23:38 +01:00
memset ( dst , 0xcc , sizeof ( dst ) ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , ptest - > str , lstrlenW ( ptest - > str ) , dst , dstlen ) ;
ok ( dstlen = = lstrlenW ( ptest - > expected [ i ] ) , " %s:%d: Copied length differed: was %d, should be %d \n " ,
wine_dbgstr_w ( ptest - > str ) , i , dstlen , lstrlenW ( dst ) ) ;
str_cmp = wcsncmp ( ptest - > expected [ i ] , dst , dstlen ) ;
ok ( str_cmp = = 0 , " %s:%d: string incorrect got %s expect %s \n " , wine_dbgstr_w ( ptest - > str ) , i ,
wine_dbgstr_w ( dst ) , wine_dbgstr_w ( ptest - > expected [ i ] ) ) ;
2019-11-21 10:43:46 +01:00
if ( pRtlNormalizeString )
{
dstlen = 0 ;
status = pRtlNormalizeString ( norm_forms [ i ] , ptest - > str , lstrlenW ( ptest - > str ) , NULL , & dstlen ) ;
ok ( ! status , " %s:%d: failed %x \n " , wine_dbgstr_w ( ptest - > str ) , i , status ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen > lstrlenW ( ptest - > str ) , " %s:%d: wrong len %d / %d \n " ,
2020-02-03 13:23:38 +01:00
wine_dbgstr_w ( ptest - > str ) , i , dstlen , lstrlenW ( ptest - > str ) ) ;
2019-11-21 10:43:46 +01:00
memset ( dst , 0 , sizeof ( dst ) ) ;
status = pRtlNormalizeString ( norm_forms [ i ] , ptest - > str , lstrlenW ( ptest - > str ) , dst , & dstlen ) ;
ok ( ! status , " %s:%d: failed %x \n " , wine_dbgstr_w ( ptest - > str ) , i , status ) ;
ok ( dstlen = = lstrlenW ( dst ) , " %s:%d: Copied length differed: was %d, should be %d \n " ,
wine_dbgstr_w ( ptest - > str ) , i , dstlen , lstrlenW ( dst ) ) ;
str_cmp = wcsncmp ( ptest - > expected [ i ] , dst , dstlen ) ;
ok ( str_cmp = = 0 , " %s:%d: string incorrect got %s expect %s \n " , wine_dbgstr_w ( ptest - > str ) , i ,
wine_dbgstr_w ( dst ) , wine_dbgstr_w ( ptest - > expected [ i ] ) ) ;
2020-02-04 14:31:45 +01:00
ret = FALSE ;
2020-02-18 19:59:16 +01:00
status = pRtlIsNormalizedString ( norm_forms [ i ] , ptest - > str , - 1 , & ret ) ;
2020-02-20 13:05:55 +01:00
ok ( ! status , " %s:%d: failed %x \n " , wine_dbgstr_w ( ptest - > str ) , i , status ) ;
2020-02-18 19:59:16 +01:00
if ( ! wcscmp ( ptest - > str , dst ) )
ok ( ret , " %s:%d: not normalized \n " , wine_dbgstr_w ( ptest - > str ) , i ) ;
else
ok ( ! ret , " %s:%d: normalized (dst %s) \n " , wine_dbgstr_w ( ptest - > str ) , i , wine_dbgstr_w ( dst ) ) ;
ret = FALSE ;
2019-11-21 10:43:46 +01:00
status = pRtlIsNormalizedString ( norm_forms [ i ] , dst , dstlen , & ret ) ;
2020-02-20 13:05:55 +01:00
ok ( ! status , " %s:%d: failed %x \n " , wine_dbgstr_w ( ptest - > str ) , i , status ) ;
ok ( ret , " %s:%d: not normalized \n " , wine_dbgstr_w ( ptest - > str ) , i ) ;
2019-11-21 10:43:46 +01:00
}
2018-04-09 20:38:00 +02:00
}
ptest + + ;
}
2020-02-03 13:23:38 +01:00
/* buffer overflows */
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( NormalizationD , part0_str1 , - 1 , dst , 1 ) ;
2020-02-03 18:39:15 +01:00
ok ( dstlen < = 0 , " wrong len %d \n " , dstlen ) ;
2020-02-03 13:23:38 +01:00
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " got error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( NormalizationC , part0_str2 , - 1 , dst , 1 ) ;
2020-02-03 18:39:15 +01:00
ok ( dstlen < = 0 , " wrong len %d \n " , dstlen ) ;
2020-02-03 16:30:56 +01:00
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " got error %u \n " , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( NormalizationC , part0_str2 , - 1 , NULL , 0 ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen = = 12 , " wrong len %d \n " , dstlen ) ;
2020-02-03 18:39:15 +01:00
ok ( GetLastError ( ) = = ERROR_SUCCESS , " got error %u \n " , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( NormalizationC , part0_str2 , - 1 , dst , 3 ) ;
ok ( dstlen = = 3 , " wrong len %d \n " , dstlen ) ;
2020-02-03 18:39:15 +01:00
ok ( GetLastError ( ) = = ERROR_SUCCESS , " got error %u \n " , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( NormalizationC , part0_str2 , 0 , NULL , 0 ) ;
ok ( dstlen = = 0 , " wrong len %d \n " , dstlen ) ;
2020-02-03 18:39:15 +01:00
ok ( GetLastError ( ) = = ERROR_SUCCESS , " got error %u \n " , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( NormalizationC , part0_str2 , 0 , dst , 3 ) ;
ok ( dstlen = = 0 , " wrong len %d \n " , dstlen ) ;
2020-02-03 18:39:15 +01:00
ok ( GetLastError ( ) = = ERROR_SUCCESS , " got error %u \n " , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
/* size estimations */
memset ( dst , ' A ' , sizeof ( dst ) ) ;
for ( j = 1 ; j < ARRAY_SIZE ( dst ) ; j + + )
{
for ( i = 0 ; i < 4 ; i + + )
{
int expect = ( i < 2 ) ? j * 3 : j * 18 ;
if ( expect > 64 ) expect = max ( 64 , j + j / 8 ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , dst , j , NULL , 0 ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen = = expect , " %d: %d -> wrong len %d \n " , i , j , dstlen ) ;
2020-02-03 13:23:38 +01:00
if ( pRtlNormalizeString )
{
dstlen = 0 ;
status = pRtlNormalizeString ( norm_forms [ i ] , dst , j , NULL , & dstlen ) ;
ok ( ! status , " %d: failed %x \n " , i , status ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen = = expect , " %d: %d -> wrong len %d \n " , i , j , dstlen ) ;
2020-02-03 13:23:38 +01:00
}
}
}
for ( i = 0 ; i < 4 ; i + + )
{
int srclen = ARRAY_SIZE ( composite_src ) ;
int expect = max ( 64 , srclen + srclen / 8 ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , composite_src , srclen , NULL , 0 ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen = = expect , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 13:23:38 +01:00
dstlen = pNormalizeString ( norm_forms [ i ] , composite_src , srclen , dst , dstlen ) ;
if ( i = = 0 | | i = = 2 )
{
ok ( dstlen = = srclen , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 18:39:15 +01:00
ok ( GetLastError ( ) = = ERROR_SUCCESS , " got error %u \n " , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
}
else
{
2020-02-03 18:39:15 +01:00
ok ( dstlen < - expect , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 16:30:56 +01:00
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " got error %u \n " , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
}
if ( pRtlNormalizeString )
{
dstlen = 0 ;
status = pRtlNormalizeString ( norm_forms [ i ] , composite_src , srclen , NULL , & dstlen ) ;
ok ( ! status , " %d: failed %x \n " , i , status ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen = = expect , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 13:23:38 +01:00
status = pRtlNormalizeString ( norm_forms [ i ] , composite_src , srclen , dst , & dstlen ) ;
if ( i = = 0 | | i = = 2 )
{
ok ( ! status , " %d: failed %x \n " , i , status ) ;
ok ( dstlen = = srclen , " %d: wrong len %d \n " , i , dstlen ) ;
}
else
{
2020-02-03 16:30:56 +01:00
ok ( status = = STATUS_BUFFER_TOO_SMALL , " %d: failed %x \n " , i , status ) ;
2020-02-03 13:23:38 +01:00
ok ( dstlen > expect , " %d: wrong len %d \n " , i , dstlen ) ;
}
}
}
/* invalid parameters */
for ( i = 0 ; i < 32 ; i + + )
{
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( i , L " ABC " , - 1 , NULL , 0 ) ;
switch ( i )
{
case NormalizationC :
case NormalizationD :
case NormalizationKC :
case NormalizationKD :
case 13 : /* Idn */
ok ( dstlen > 0 , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 18:39:15 +01:00
ok ( GetLastError ( ) = = ERROR_SUCCESS , " %d: got error %u \n " , i , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
break ;
default :
2020-02-03 13:29:55 +01:00
ok ( dstlen < = 0 , " %d: wrong len %d \n " , i , dstlen ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " %d: got error %u \n " , i , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
break ;
}
if ( pRtlNormalizeString )
{
dstlen = 0 ;
status = pRtlNormalizeString ( i , L " ABC " , - 1 , NULL , & dstlen ) ;
switch ( i )
{
case 0 :
2020-02-03 13:29:55 +01:00
ok ( status = = STATUS_INVALID_PARAMETER , " %d: failed %x \n " , i , status ) ;
2020-02-03 13:23:38 +01:00
break ;
case NormalizationC :
case NormalizationD :
case NormalizationKC :
case NormalizationKD :
case 13 : /* Idn */
ok ( status = = STATUS_SUCCESS , " %d: failed %x \n " , i , status ) ;
break ;
default :
2020-02-03 13:29:55 +01:00
ok ( status = = STATUS_OBJECT_NAME_NOT_FOUND , " %d: failed %x \n " , i , status ) ;
2020-02-03 13:23:38 +01:00
break ;
}
}
}
/* invalid sequences */
for ( i = 0 ; i < 4 ; i + + )
{
dstlen = pNormalizeString ( norm_forms [ i ] , L " AB \xd800 Z " , - 1 , NULL , 0 ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen = = ( i < 2 ? 15 : 64 ) , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 13:23:38 +01:00
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , L " AB \xd800 Z " , - 1 , dst , ARRAY_SIZE ( dst ) ) ;
2020-02-17 10:44:04 +01:00
ok ( dstlen = = - 3 , " %d: wrong len %d \n " , i , dstlen ) ;
ok ( GetLastError ( ) = = ERROR_NO_UNICODE_TRANSLATION , " %d: wrong error %d \n " , i , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
dstlen = pNormalizeString ( norm_forms [ i ] , L " ABCD \xdc12 Z " , - 1 , NULL , 0 ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen = = ( i < 2 ? 21 : 64 ) , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 13:23:38 +01:00
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , L " ABCD \xdc12 Z " , - 1 , dst , ARRAY_SIZE ( dst ) ) ;
2020-02-17 10:44:04 +01:00
ok ( dstlen = = - 4 , " %d: wrong len %d \n " , i , dstlen ) ;
ok ( GetLastError ( ) = = ERROR_NO_UNICODE_TRANSLATION , " %d: wrong error %d \n " , i , GetLastError ( ) ) ;
2020-02-03 13:23:38 +01:00
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , L " ABCD \xdc12 Z " , - 1 , dst , 2 ) ;
2020-02-17 10:44:04 +01:00
todo_wine
ok ( dstlen = = ( i < 2 ? - 18 : - 74 ) , " %d: wrong len %d \n " , i , dstlen ) ;
todo_wine_if ( i = = 0 | | i = = 2 )
2020-02-03 13:23:38 +01:00
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " %d: wrong error %d \n " , i , GetLastError ( ) ) ;
if ( pRtlNormalizeString )
{
dstlen = 0 ;
status = pRtlNormalizeString ( norm_forms [ i ] , L " AB \xd800 Z " , - 1 , NULL , & dstlen ) ;
ok ( ! status , " %d: failed %x \n " , i , status ) ;
2020-02-03 16:30:56 +01:00
ok ( dstlen = = ( i < 2 ? 15 : 64 ) , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 13:23:38 +01:00
dstlen = ARRAY_SIZE ( dst ) ;
status = pRtlNormalizeString ( norm_forms [ i ] , L " AB \xd800 Z " , - 1 , dst , & dstlen ) ;
2020-02-17 10:44:04 +01:00
ok ( status = = STATUS_NO_UNICODE_TRANSLATION , " %d: failed %x \n " , i , status ) ;
ok ( dstlen = = 3 , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 13:23:38 +01:00
dstlen = 1 ;
status = pRtlNormalizeString ( norm_forms [ i ] , L " AB \xd800 Z " , - 1 , dst , & dstlen ) ;
2020-02-17 10:44:04 +01:00
todo_wine_if ( i = = 0 | | i = = 2 )
2020-02-03 13:23:38 +01:00
ok ( status = = STATUS_BUFFER_TOO_SMALL , " %d: failed %x \n " , i , status ) ;
2020-02-17 10:44:04 +01:00
todo_wine_if ( i ! = 3 )
2020-02-03 16:30:56 +01:00
ok ( dstlen = = ( i < 2 ? 14 : 73 ) , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 13:23:38 +01:00
dstlen = 2 ;
status = pRtlNormalizeString ( norm_forms [ i ] , L " AB \xd800 Z " , - 1 , dst , & dstlen ) ;
2020-02-17 10:44:04 +01:00
ok ( status = = STATUS_NO_UNICODE_TRANSLATION , " %d: failed %x \n " , i , status ) ;
ok ( dstlen = = 3 , " %d: wrong len %d \n " , i , dstlen ) ;
2020-02-03 13:23:38 +01:00
}
}
2020-02-04 14:31:45 +01:00
/* optionally run the full test file from Unicode.org
* available at http : //www.unicode.org/Public/UCD/latest/ucd/NormalizationTest.txt
*/
if ( ( f = fopen ( " NormalizationTest.txt " , " r " ) ) )
{
char * p , buffer [ 1024 ] ;
WCHAR str [ 3 ] , srcW [ 32 ] , dstW [ 32 ] , resW [ 4 ] [ 32 ] ;
2020-02-18 19:59:16 +01:00
int line = 0 , part = 0 , ch ;
2020-02-04 14:31:45 +01:00
char tested [ 0x110000 / 8 ] ;
while ( fgets ( buffer , sizeof ( buffer ) , f ) )
{
line + + ;
if ( ( p = strchr ( buffer , ' # ' ) ) ) * p = 0 ;
if ( ! strncmp ( buffer , " @Part " , 5 ) )
{
part = atoi ( buffer + 5 ) ;
continue ;
}
if ( ! ( p = strtok ( buffer , " ; " ) ) ) continue ;
read_str ( p , srcW ) ;
for ( i = 0 ; i < 4 ; i + + )
{
p = strtok ( NULL , " ; " ) ;
read_str ( p , & resW [ i ] [ 0 ] ) ;
}
if ( part = = 1 )
{
ch = srcW [ 0 ] ;
if ( ch > = 0xd800 & & ch < = 0xdbff )
ch = 0x10000 + ( ( srcW [ 0 ] & 0x3ff ) < < 10 ) + ( srcW [ 1 ] & 0x3ff ) ;
tested [ ch / 8 ] | = 1 < < ( ch % 8 ) ;
}
for ( i = 0 ; i < 4 ; i + + )
{
memset ( dstW , 0xcc , sizeof ( dstW ) ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , srcW , - 1 , dstW , ARRAY_SIZE ( dstW ) ) ;
ok ( ! wcscmp ( dstW , resW [ i ] ) ,
" line %u form %u: wrong result %s for %s expected %s \n " , line , i ,
wine_dbgstr_w ( dstW ) , wine_dbgstr_w ( srcW ) , wine_dbgstr_w ( resW [ i ] ) ) ;
2020-02-18 19:59:16 +01:00
ret = FALSE ;
status = pRtlIsNormalizedString ( norm_forms [ i ] , srcW , - 1 , & ret ) ;
ok ( ! status , " line %u form %u: RtlIsNormalizedString failed %x \n " , line , i , status ) ;
if ( ! wcscmp ( srcW , dstW ) )
ok ( ret , " line %u form %u: source not normalized %s \n " , line , i , wine_dbgstr_w ( srcW ) ) ;
else
ok ( ! ret , " line %u form %u: source normalized %s \n " , line , i , wine_dbgstr_w ( srcW ) ) ;
ret = FALSE ;
status = pRtlIsNormalizedString ( norm_forms [ i ] , dstW , - 1 , & ret ) ;
ok ( ! status , " line %u form %u: RtlIsNormalizedString failed %x \n " , line , i , status ) ;
ok ( ret , " line %u form %u: dest not normalized %s \n " , line , i , wine_dbgstr_w ( dstW ) ) ;
for ( j = 0 ; j < 4 ; j + + )
{
int expect = i | ( j & 2 ) ;
memset ( dstW , 0xcc , sizeof ( dstW ) ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , resW [ j ] , - 1 , dstW , ARRAY_SIZE ( dstW ) ) ;
ok ( ! wcscmp ( dstW , resW [ expect ] ) ,
" line %u form %u res %u: wrong result %s for %s expected %s \n " , line , i , j ,
wine_dbgstr_w ( dstW ) , wine_dbgstr_w ( resW [ j ] ) , wine_dbgstr_w ( resW [ expect ] ) ) ;
}
2020-02-04 14:31:45 +01:00
}
}
fclose ( f ) ;
/* test chars that are not in the @Part1 list */
for ( ch = 0 ; ch < 0x110000 ; ch + + )
{
if ( tested [ ch / 8 ] & ( 1 < < ( ch % 8 ) ) ) continue ;
str [ put_utf16 ( str , ch ) ] = 0 ;
for ( i = 0 ; i < 4 ; i + + )
{
memset ( dstW , 0xcc , sizeof ( dstW ) ) ;
SetLastError ( 0xdeadbeef ) ;
dstlen = pNormalizeString ( norm_forms [ i ] , str , - 1 , dstW , ARRAY_SIZE ( dstW ) ) ;
if ( ( ch > = 0xd800 & & ch < = 0xdfff ) | |
( ch > = 0xfdd0 & & ch < = 0xfdef ) | |
( ( ch & 0xffff ) > = 0xfffe ) )
{
ok ( dstlen < = 0 , " char %04x form %u: wrong result %d %s expected error \n " ,
ch , i , dstlen , wine_dbgstr_w ( dstW ) ) ;
ok ( GetLastError ( ) = = ERROR_NO_UNICODE_TRANSLATION ,
" char %04x form %u: error %u \n " , str [ 0 ] , i , GetLastError ( ) ) ;
status = pRtlIsNormalizedString ( norm_forms [ i ] , str , - 1 , & ret ) ;
ok ( status = = STATUS_NO_UNICODE_TRANSLATION ,
" char %04x form %u: failed %x \n " , ch , i , status ) ;
}
else
{
ok ( ! wcscmp ( dstW , str ) ,
" char %04x form %u: wrong result %s expected unchanged \n " ,
ch , i , wine_dbgstr_w ( dstW ) ) ;
ret = FALSE ;
status = pRtlIsNormalizedString ( norm_forms [ i ] , str , - 1 , & ret ) ;
ok ( ! status , " char %04x form %u: failed %x \n " , ch , i , status ) ;
ok ( ret , " char %04x form %u: not normalized \n " , ch , i ) ;
}
}
}
}
2018-04-09 20:38:00 +02:00
}
2019-02-14 03:39:48 +01:00
static void test_SpecialCasing ( void )
{
int ret , i ;
WCHAR exp , buffer [ 8 ] ;
static const WCHAR azCyrlazW [ ] = { ' a ' , ' z ' , ' - ' , ' C ' , ' y ' , ' r ' , ' l ' , ' - ' , ' a ' , ' z ' , 0 } ;
static const WCHAR azLatnazW [ ] = { ' a ' , ' z ' , ' - ' , ' L ' , ' a ' , ' t ' , ' n ' , ' - ' , ' a ' , ' z ' , 0 } ;
static const WCHAR deDEW [ ] = { ' d ' , ' e ' , ' - ' , ' D ' , ' E ' , 0 } ;
static const WCHAR elGRW [ ] = { ' e ' , ' l ' , ' - ' , ' G ' , ' R ' , 0 } ;
static const WCHAR enUSW [ ] = { ' e ' , ' n ' , ' - ' , ' U ' , ' S ' , 0 } ;
static const WCHAR hyAMW [ ] = { ' h ' , ' y ' , ' - ' , ' A ' , ' M ' , 0 } ;
static const WCHAR ltLTW [ ] = { ' l ' , ' t ' , ' - ' , ' L ' , ' T ' , 0 } ;
static const WCHAR trTRW [ ] = { ' t ' , ' r ' , ' - ' , ' T ' , ' R ' , 0 } ;
static const WCHAR TRTRW [ ] = { ' T ' , ' R ' , ' - ' , ' T ' , ' R ' , 0 } ;
static const struct test {
const WCHAR * lang ;
DWORD flags ;
WCHAR ch ;
WCHAR exp ; /* 0 if self */
WCHAR exp_ling ; /* 0 if exp */
} tests [ ] = {
{ deDEW , LCMAP_UPPERCASE , 0x00DF } , /* LATIN SMALL LETTER SHARP S */
{ enUSW , LCMAP_UPPERCASE , 0xFB00 } , /* LATIN SMALL LIGATURE FF */
{ enUSW , LCMAP_UPPERCASE , 0xFB01 } , /* LATIN SMALL LIGATURE FI */
{ enUSW , LCMAP_UPPERCASE , 0xFB02 } , /* LATIN SMALL LIGATURE FL */
{ enUSW , LCMAP_UPPERCASE , 0xFB03 } , /* LATIN SMALL LIGATURE FFI */
{ enUSW , LCMAP_UPPERCASE , 0xFB04 } , /* LATIN SMALL LIGATURE FFL */
{ enUSW , LCMAP_UPPERCASE , 0xFB05 } , /* LATIN SMALL LIGATURE LONG S T */
{ enUSW , LCMAP_UPPERCASE , 0xFB06 } , /* LATIN SMALL LIGATURE ST */
{ hyAMW , LCMAP_UPPERCASE , 0x0587 } , /* ARMENIAN SMALL LIGATURE ECH YIWN */
{ hyAMW , LCMAP_UPPERCASE , 0xFB13 } , /* ARMENIAN SMALL LIGATURE MEN NOW */
{ hyAMW , LCMAP_UPPERCASE , 0xFB14 } , /* ARMENIAN SMALL LIGATURE MEN ECH */
{ hyAMW , LCMAP_UPPERCASE , 0xFB15 } , /* ARMENIAN SMALL LIGATURE MEN INI */
{ hyAMW , LCMAP_UPPERCASE , 0xFB16 } , /* ARMENIAN SMALL LIGATURE VEW NOW */
{ hyAMW , LCMAP_UPPERCASE , 0xFB17 } , /* ARMENIAN SMALL LIGATURE MEN XEH */
{ enUSW , LCMAP_UPPERCASE , 0x0149 } , /* LATIN SMALL LETTER N PRECEDED BY APOSTROPHE */
{ elGRW , LCMAP_UPPERCASE , 0x0390 } , /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
{ elGRW , LCMAP_UPPERCASE , 0x03B0 } , /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
{ enUSW , LCMAP_UPPERCASE , 0x01F0 } , /* LATIN SMALL LETTER J WITH CARON */
{ enUSW , LCMAP_UPPERCASE , 0x1E96 } , /* LATIN SMALL LETTER H WITH LINE BELOW */
{ enUSW , LCMAP_UPPERCASE , 0x1E97 } , /* LATIN SMALL LETTER T WITH DIAERESIS */
{ enUSW , LCMAP_UPPERCASE , 0x1E98 } , /* LATIN SMALL LETTER W WITH RING ABOVE */
{ enUSW , LCMAP_UPPERCASE , 0x1E99 } , /* LATIN SMALL LETTER Y WITH RING ABOVE */
{ enUSW , LCMAP_UPPERCASE , 0x1E9A } , /* LATIN SMALL LETTER A WITH RIGHT HALF RING */
{ elGRW , LCMAP_UPPERCASE , 0x1F50 } , /* GREEK SMALL LETTER UPSILON WITH PSILI */
{ elGRW , LCMAP_UPPERCASE , 0x1F52 } , /* GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA */
{ elGRW , LCMAP_UPPERCASE , 0x1F54 } , /* GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA */
{ elGRW , LCMAP_UPPERCASE , 0x1F56 } , /* GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FB6 } , /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FC6 } , /* GREEK SMALL LETTER ETA WITH PERISPOMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FD2 } , /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA */
{ elGRW , LCMAP_UPPERCASE , 0x1FD3 } , /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA */
{ elGRW , LCMAP_UPPERCASE , 0x1FD6 } , /* GREEK SMALL LETTER IOTA WITH PERISPOMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FD7 } , /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FE2 } , /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA */
{ elGRW , LCMAP_UPPERCASE , 0x1FE3 } , /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA */
{ elGRW , LCMAP_UPPERCASE , 0x1FE4 } , /* GREEK SMALL LETTER RHO WITH PSILI */
{ elGRW , LCMAP_UPPERCASE , 0x1FE6 } , /* GREEK SMALL LETTER UPSILON WITH PERISPOMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FE7 } , /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FF6 } , /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F80 , 0x1F88 } , /* GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F81 , 0x1F89 } , /* GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F82 , 0x1F8A } , /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F83 , 0x1F8B } , /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F84 , 0x1F8C } , /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F85 , 0x1F8D } , /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F86 , 0x1F8E } , /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F87 , 0x1F8F } , /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1F88 , 0x1F80 } , /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1F89 , 0x1F81 } , /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1F8A , 0x1F82 } , /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1F8B , 0x1F83 } , /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1F8C , 0x1F84 } , /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1F8D , 0x1F85 } , /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1F8E , 0x1F86 } , /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1F8F , 0x1F87 } , /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F90 , 0x1F98 } , /* GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F91 , 0x1F99 } , /* GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F92 , 0x1F9A } , /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F93 , 0x1F9B } , /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F94 , 0x1F9C } , /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F95 , 0x1F9D } , /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F96 , 0x1F9E } , /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1F97 , 0x1F9F } , /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FA8 , 0x1FA0 } , /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FA9 , 0x1FA1 } , /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FAA , 0x1FA2 } , /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FAB , 0x1FA3 } , /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FAC , 0x1FA4 } , /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FAD , 0x1FA5 } , /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FAE , 0x1FA6 } , /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FAF , 0x1FA7 } , /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FB3 , 0x1FBC } , /* GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FBC , 0x1FB3 } , /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FC3 , 0x1FCC } , /* GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FCC , 0x1FC3 } , /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FF3 , 0x1FFC } , /* GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x1FFC , 0x1FF3 } , /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FB2 } , /* GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FB4 } , /* GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FC2 } , /* GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FC4 } , /* GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FF2 } , /* GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FF4 } , /* GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FB7 } , /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FC7 } , /* GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_UPPERCASE , 0x1FF7 } , /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI */
{ elGRW , LCMAP_LOWERCASE , 0x03A3 , 0x03C3 } , /* GREEK CAPITAL LETTER SIGMA */
{ ltLTW , LCMAP_LOWERCASE , ' J ' , ' j ' } , /* LATIN CAPITAL LETTER J */
{ ltLTW , LCMAP_LOWERCASE , 0x012E , 0x012F } , /* LATIN CAPITAL LETTER I WITH OGONEK */
{ ltLTW , LCMAP_LOWERCASE , 0x00CC , 0x00EC } , /* LATIN CAPITAL LETTER I WITH GRAVE */
{ ltLTW , LCMAP_LOWERCASE , 0x00CD , 0x00ED } , /* LATIN CAPITAL LETTER I WITH ACUTE */
{ ltLTW , LCMAP_LOWERCASE , 0x0128 , 0x0129 } , /* LATIN CAPITAL LETTER I WITH TILDE */
{ enUSW , LCMAP_UPPERCASE , ' i ' , ' I ' } , /* LATIN SMALL LETTER I */
{ ltLTW , LCMAP_UPPERCASE , ' i ' , ' I ' } , /* LATIN SMALL LETTER I */
2020-03-18 12:00:02 +01:00
{ trTRW , LCMAP_UPPERCASE , ' i ' , ' I ' , 0x0130 } , /* LATIN SMALL LETTER I */
{ TRTRW , LCMAP_UPPERCASE , ' i ' , ' I ' , 0x0130 } , /* LATIN SMALL LETTER I */
{ azCyrlazW , LCMAP_UPPERCASE , ' i ' , ' I ' , 0x0130 } , /* LATIN SMALL LETTER I */
{ azLatnazW , LCMAP_UPPERCASE , ' i ' , ' I ' , 0x0130 } , /* LATIN SMALL LETTER I */
2019-02-14 03:39:48 +01:00
{ enUSW , LCMAP_LOWERCASE , ' I ' , ' i ' } , /* LATIN CAPITAL LETTER I */
{ ltLTW , LCMAP_LOWERCASE , ' I ' , ' i ' } , /* LATIN CAPITAL LETTER I */
2020-03-18 12:00:02 +01:00
{ trTRW , LCMAP_LOWERCASE , ' I ' , ' i ' , 0x0131 } , /* LATIN CAPITAL LETTER I */
{ TRTRW , LCMAP_LOWERCASE , ' I ' , ' i ' , 0x0131 } , /* LATIN CAPITAL LETTER I */
{ azCyrlazW , LCMAP_LOWERCASE , ' I ' , ' i ' , 0x0131 } , /* LATIN CAPITAL LETTER I */
{ azLatnazW , LCMAP_LOWERCASE , ' I ' , ' i ' , 0x0131 } , /* LATIN CAPITAL LETTER I */
{ enUSW , LCMAP_LOWERCASE , 0x0130 , 0 , ' i ' } , /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{ trTRW , LCMAP_LOWERCASE , 0x0130 , 0 , ' i ' } , /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{ TRTRW , LCMAP_LOWERCASE , 0x0130 , 0 , ' i ' } , /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{ azCyrlazW , LCMAP_LOWERCASE , 0x0130 , 0 , ' i ' } , /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{ azLatnazW , LCMAP_LOWERCASE , 0x0130 , 0 , ' i ' } , /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{ enUSW , LCMAP_UPPERCASE , 0x0131 , 0 , ' I ' } , /* LATIN SMALL LETTER DOTLESS I */
{ trTRW , LCMAP_UPPERCASE , 0x0131 , 0 , ' I ' } , /* LATIN SMALL LETTER DOTLESS I */
{ TRTRW , LCMAP_UPPERCASE , 0x0131 , 0 , ' I ' } , /* LATIN SMALL LETTER DOTLESS I */
{ azCyrlazW , LCMAP_UPPERCASE , 0x0131 , 0 , ' I ' } , /* LATIN SMALL LETTER DOTLESS I */
{ azLatnazW , LCMAP_UPPERCASE , 0x0131 , 0 , ' I ' } , /* LATIN SMALL LETTER DOTLESS I */
2019-02-14 03:39:48 +01:00
} ;
if ( ! pLCMapStringEx )
{
win_skip ( " LCMapStringEx not available \n " ) ;
return ;
}
for ( i = 0 ; i < ARRAY_SIZE ( tests ) ; i + + ) {
memset ( buffer , 0 , sizeof ( buffer ) ) ;
ret = pLCMapStringEx ( tests [ i ] . lang , tests [ i ] . flags ,
& tests [ i ] . ch , 1 , buffer , ARRAY_SIZE ( buffer ) , NULL , NULL , 0 ) ;
ok ( ret = = 1 , " expected 1, got %d for %04x for %s \n " , ret , tests [ i ] . ch ,
wine_dbgstr_w ( tests [ i ] . lang ) ) ;
exp = tests [ i ] . exp ? tests [ i ] . exp : tests [ i ] . ch ;
ok ( buffer [ 0 ] = = exp | | broken ( buffer [ 0 ] ! = exp ) ,
" expected %04x, got %04x for %04x for %s \n " ,
exp , buffer [ 0 ] , tests [ i ] . ch , wine_dbgstr_w ( tests [ i ] . lang ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
ret = pLCMapStringEx ( tests [ i ] . lang , tests [ i ] . flags | LCMAP_LINGUISTIC_CASING ,
& tests [ i ] . ch , 1 , buffer , ARRAY_SIZE ( buffer ) , NULL , NULL , 0 ) ;
ok ( ret = = 1 , " expected 1, got %d for %04x for %s \n " , ret , tests [ i ] . ch ,
wine_dbgstr_w ( tests [ i ] . lang ) ) ;
exp = tests [ i ] . exp_ling ? tests [ i ] . exp_ling : exp ;
ok ( buffer [ 0 ] = = exp | | broken ( buffer [ 0 ] ! = exp ) ,
" expected %04x, got %04x for %04x for %s \n " ,
exp , buffer [ 0 ] , tests [ i ] . ch , wine_dbgstr_w ( tests [ i ] . lang ) ) ;
}
}
2020-03-20 12:54:36 +01:00
static void test_NLSVersion ( void )
{
static const GUID guid_null = { 0 } ;
static const GUID guid_def = { 0x000000001 , 0x57ee , 0x1e5c , { 0x00 , 0xb4 , 0xd0 , 0x00 , 0x0b , 0xb1 , 0xe1 , 0x1e } } ;
static const GUID guid_fr = { 0x000000003 , 0x57ee , 0x1e5c , { 0x00 , 0xb4 , 0xd0 , 0x00 , 0x0b , 0xb1 , 0xe1 , 0x1e } } ;
static const GUID guid_ja = { 0x000000046 , 0x57ee , 0x1e5c , { 0x00 , 0xb4 , 0xd0 , 0x00 , 0x0b , 0xb1 , 0xe1 , 0x1e } } ;
BOOL ret ;
NLSVERSIONINFOEX info ;
if ( ! pGetNLSVersion )
{
win_skip ( " GetNLSVersion not available \n " ) ;
return ;
}
2020-05-05 01:29:41 +02:00
2020-03-20 12:54:36 +01:00
SetLastError ( 0xdeadbeef ) ;
memset ( & info , 0xcc , sizeof ( info ) ) ;
2020-05-05 01:29:41 +02:00
info . dwNLSVersionInfoSize = offsetof ( NLSVERSIONINFO , dwEffectiveId ) ;
2020-03-20 12:54:36 +01:00
ret = pGetNLSVersion ( COMPARE_STRING , MAKELANGID ( LANG_FRENCH , SUBLANG_FRENCH_CANADIAN ) ,
( NLSVERSIONINFO * ) & info ) ;
ok ( ret , " GetNLSVersion failed err %u \n " , GetLastError ( ) ) ;
2020-05-05 01:29:41 +02:00
SetLastError ( 0xdeadbeef ) ;
memset ( & info , 0xcc , sizeof ( info ) ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersion ( COMPARE_STRING , MAKELANGID ( LANG_FRENCH , SUBLANG_FRENCH_CANADIAN ) ,
( NLSVERSIONINFO * ) & info ) ;
ok ( ret | | GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER /* < Vista */ ,
" GetNLSVersion failed err %u \n " , GetLastError ( ) ) ;
if ( ret )
{
ok ( info . dwEffectiveId = = MAKELANGID ( LANG_FRENCH , SUBLANG_FRENCH_CANADIAN ) ,
" wrong id %x \n " , info . dwEffectiveId ) ;
ok ( IsEqualIID ( & info . guidCustomVersion , & guid_fr ) | |
broken ( IsEqualIID ( & info . guidCustomVersion , & guid_null ) ) , /* <= win7 */
" wrong guid %s \n " , debugstr_guid ( & info . guidCustomVersion ) ) ;
}
2020-03-20 12:54:36 +01:00
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = 8 ;
ret = pGetNLSVersion ( COMPARE_STRING , LOCALE_USER_DEFAULT , ( NLSVERSIONINFO * ) & info ) ;
ok ( ! ret , " GetNLSVersion succeeded \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersion ( 2 , LOCALE_USER_DEFAULT , ( NLSVERSIONINFO * ) & info ) ;
ok ( ! ret , " GetNLSVersion succeeded \n " ) ;
2020-06-04 07:04:28 +02:00
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS | |
broken ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) , /* win2003 */
" wrong error %u \n " , GetLastError ( ) ) ;
2020-03-20 12:54:36 +01:00
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersion ( COMPARE_STRING , 0xdeadbeef , ( NLSVERSIONINFO * ) & info ) ;
ok ( ! ret , " GetNLSVersion succeeded \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " wrong error %u \n " , GetLastError ( ) ) ;
if ( pGetNLSVersionEx )
{
SetLastError ( 0xdeadbeef ) ;
memset ( & info , 0xcc , sizeof ( info ) ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersionEx ( COMPARE_STRING , L " ja-JP " , & info ) ;
ok ( ret , " GetNLSVersionEx failed err %u \n " , GetLastError ( ) ) ;
ok ( info . dwEffectiveId = = MAKELANGID ( LANG_JAPANESE , SUBLANG_JAPANESE_JAPAN ) ,
" wrong id %x \n " , info . dwEffectiveId ) ;
ok ( IsEqualIID ( & info . guidCustomVersion , & guid_ja ) | |
broken ( IsEqualIID ( & info . guidCustomVersion , & guid_null ) ) , /* <= win7 */
" wrong guid %s \n " , debugstr_guid ( & info . guidCustomVersion ) ) ;
trace ( " version %08x %08x %08x %s \n " , info . dwNLSVersion , info . dwDefinedVersion , info . dwEffectiveId ,
debugstr_guid ( & info . guidCustomVersion ) ) ;
SetLastError ( 0xdeadbeef ) ;
memset ( & info , 0xcc , sizeof ( info ) ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersionEx ( COMPARE_STRING , L " fr " , & info ) ;
ok ( ! ret = = ! pIsValidLocaleName ( L " fr " ) , " GetNLSVersionEx doesn't match IsValidLocaleName \n " ) ;
if ( ret )
{
ok ( info . dwEffectiveId = = MAKELANGID ( LANG_FRENCH , SUBLANG_DEFAULT ) ,
" wrong id %x \n " , info . dwEffectiveId ) ;
ok ( IsEqualIID ( & info . guidCustomVersion , & guid_fr ) | |
broken ( IsEqualIID ( & info . guidCustomVersion , & guid_null ) ) , /* <= win7 */
" wrong guid %s \n " , debugstr_guid ( & info . guidCustomVersion ) ) ;
}
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) - 1 ;
ret = pGetNLSVersionEx ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ! ret , " GetNLSVersionEx succeeded \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
memset ( & info , 0xcc , sizeof ( info ) ) ;
info . dwNLSVersionInfoSize = offsetof ( NLSVERSIONINFO , dwEffectiveId ) ;
ret = pGetNLSVersionEx ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ret , " GetNLSVersionEx failed err %u \n " , GetLastError ( ) ) ;
ok ( info . dwEffectiveId = = 0xcccccccc , " wrong id %x \n " , info . dwEffectiveId ) ;
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersionEx ( 2 , L " en-US " , & info ) ;
ok ( ! ret , " GetNLSVersionEx succeeded \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_FLAGS , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersionEx ( COMPARE_STRING , L " foobar " , & info ) ;
ok ( ! ret , " GetNLSVersionEx succeeded \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
memset ( & info , 0xcc , sizeof ( info ) ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersionEx ( COMPARE_STRING , L " zz-XX " , & info ) ;
if ( ! ret ) ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " wrong error %u \n " , GetLastError ( ) ) ;
ok ( ! ret = = ! pIsValidLocaleName ( L " zz-XX " ) , " GetNLSVersionEx doesn't match IsValidLocaleName \n " ) ;
if ( ret )
{
ok ( info . dwEffectiveId = = LOCALE_CUSTOM_UNSPECIFIED , " wrong id %x \n " , info . dwEffectiveId ) ;
ok ( IsEqualIID ( & info . guidCustomVersion , & guid_def ) ,
" wrong guid %s \n " , debugstr_guid ( & info . guidCustomVersion ) ) ;
}
SetLastError ( 0xdeadbeef ) ;
memset ( & info , 0xcc , sizeof ( info ) ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pGetNLSVersionEx ( COMPARE_STRING , LOCALE_NAME_INVARIANT , & info ) ;
ok ( ret , " GetNLSVersionEx failed err %u \n " , GetLastError ( ) ) ;
if ( ret )
{
ok ( info . dwEffectiveId = = LOCALE_INVARIANT , " wrong id %x \n " , info . dwEffectiveId ) ;
ok ( IsEqualIID ( & info . guidCustomVersion , & guid_def ) | |
broken ( IsEqualIID ( & info . guidCustomVersion , & guid_null ) ) , /* <= win7 */
" wrong guid %s \n " , debugstr_guid ( & info . guidCustomVersion ) ) ;
}
else ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " wrong error %u \n " , GetLastError ( ) ) ;
}
else win_skip ( " GetNLSVersionEx not available \n " ) ;
2020-03-20 14:43:45 +01:00
if ( pIsValidNLSVersion )
{
info . dwNLSVersionInfoSize = sizeof ( info ) ;
pGetNLSVersion ( COMPARE_STRING , LOCALE_USER_DEFAULT , ( NLSVERSIONINFO * ) & info ) ;
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " ja-JP " , & info ) ;
ok ( ret , " IsValidNLSVersion failed err %u \n " , GetLastError ( ) ) ;
ok ( GetLastError ( ) = = 0xdeadbeef , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = offsetof ( NLSVERSIONINFO , dwEffectiveId ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ret , " IsValidNLSVersion failed err %u \n " , GetLastError ( ) ) ;
ok ( GetLastError ( ) = = 0xdeadbeef , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pIsValidNLSVersion ( 2 , L " en-US " , & info ) ;
ok ( ! ret , " IsValidNLSVersion succeeded \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " foobar " , & info ) ;
ok ( ! ret , " IsValidNLSVersion succeeded \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " wrong error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
memset ( & info , 0xcc , sizeof ( info ) ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ! ret , " IsValidNLSVersion succeeded \n " ) ;
ok ( GetLastError ( ) = = ERROR_SUCCESS , " wrong error %u \n " , GetLastError ( ) ) ;
info . dwNLSVersionInfoSize = sizeof ( info ) ;
pGetNLSVersion ( COMPARE_STRING , LOCALE_USER_DEFAULT , ( NLSVERSIONINFO * ) & info ) ;
info . dwNLSVersion + + ;
SetLastError ( 0xdeadbeef ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ret , " IsValidNLSVersion failed err %u \n " , GetLastError ( ) ) ;
ok ( GetLastError ( ) = = 0xdeadbeef , " wrong error %u \n " , GetLastError ( ) ) ;
info . dwNLSVersion + = 0x100 ;
SetLastError ( 0xdeadbeef ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ! ret , " IsValidNLSVersion succeeded \n " ) ;
ok ( GetLastError ( ) = = 0 , " wrong error %u \n " , GetLastError ( ) ) ;
2021-12-16 17:04:46 +01:00
info . dwNLSVersion - = 0x800 ;
2020-03-20 14:43:45 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ! ret , " IsValidNLSVersion succeeded \n " ) ;
ok ( GetLastError ( ) = = 0 , " wrong error %u \n " , GetLastError ( ) ) ;
2021-12-16 17:04:46 +01:00
info . dwNLSVersion + = 0x700 ;
2020-03-20 14:43:45 +01:00
info . dwDefinedVersion + = 0x100 ;
SetLastError ( 0xdeadbeef ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ret , " IsValidNLSVersion failed err %u \n " , GetLastError ( ) ) ;
ok ( GetLastError ( ) = = 0xdeadbeef , " wrong error %u \n " , GetLastError ( ) ) ;
info . dwDefinedVersion - = 0x100 ;
info . guidCustomVersion . Data1 = 0x123 ;
SetLastError ( 0xdeadbeef ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ! ret , " IsValidNLSVersion succeeded \n " ) ;
ok ( GetLastError ( ) = = 0 , " wrong error %u \n " , GetLastError ( ) ) ;
info . guidCustomVersion = guid_null ;
SetLastError ( 0xdeadbeef ) ;
ret = pIsValidNLSVersion ( COMPARE_STRING , L " en-US " , & info ) ;
ok ( ret , " IsValidNLSVersion failed err %u \n " , GetLastError ( ) ) ;
ok ( GetLastError ( ) = = 0xdeadbeef , " wrong error %u \n " , GetLastError ( ) ) ;
}
else win_skip ( " IsValidNLSVersion not available \n " ) ;
2020-03-20 12:54:36 +01:00
}
2021-03-08 17:34:40 +01:00
static void test_geo_name ( void )
{
WCHAR reg_name [ 32 ] , buf [ 32 ] , set_name [ 32 ] , nation [ 32 ] , region [ 32 ] ;
BOOL have_name = FALSE , have_region = FALSE , have_nation = FALSE ;
DWORD size , type , name_size ;
LSTATUS status ;
GEOID geoid ;
BOOL bret ;
HKEY key ;
int ret ;
if ( ! pSetUserGeoName | | ! pGetUserDefaultGeoName )
{
win_skip ( " GetUserDefaultGeoName / SetUserGeoName is not available, skipping test. \n " ) ;
return ;
}
status = RegOpenKeyExA ( HKEY_CURRENT_USER , " Control Panel \\ International \\ Geo " , 0 , KEY_READ | KEY_WRITE , & key ) ;
ok ( status = = ERROR_SUCCESS , " Got unexpected status %#x. \n " , status ) ;
size = sizeof ( reg_name ) ;
if ( ! RegQueryValueExW ( key , L " Name " , NULL , & type , ( BYTE * ) reg_name , & size ) )
have_name = TRUE ;
lstrcpyW ( buf , L " QQ " ) ;
RegSetValueExW ( key , L " Name " , 0 , REG_SZ , ( BYTE * ) buf , ( lstrlenW ( buf ) + 1 ) * sizeof ( WCHAR ) ) ;
size = sizeof ( reg_name ) ;
if ( ( ret = pGetUserDefaultGeoName ( NULL , 0 ) ) = = 1 )
{
if ( have_name )
{
status = RegSetValueExW ( key , L " Name " , 0 , REG_SZ , ( BYTE * ) reg_name , ( lstrlenW ( reg_name ) + 1 ) * sizeof ( * reg_name ) ) ;
ok ( status = = ERROR_SUCCESS , " Got unexpected status %#x. \n " , status ) ;
}
else
{
RegDeleteValueW ( key , L " Name " ) ;
}
win_skip ( " Geo names are not available, skipping test. \n " ) ;
return ;
}
size = sizeof ( nation ) ;
if ( ! RegQueryValueExW ( key , L " Nation " , NULL , & type , ( BYTE * ) nation , & size ) )
have_nation = TRUE ;
size = sizeof ( region ) ;
if ( ! RegQueryValueExW ( key , L " Region " , NULL , & type , ( BYTE * ) region , & size ) )
have_region = TRUE ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( NULL , 0 ) ;
ok ( ( ret = = 3 | | ret = = 4 ) & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
name_size = ret ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , 0 ) ;
ok ( ret > = 3 & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , 2 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( NULL , 1 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( NULL , name_size ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , name_size ) ;
ok ( ret = = name_size & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " QQ " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
SetLastError ( 0xdeadbeef ) ;
bret = pSetUserGeoName ( NULL ) ;
ok ( ! bret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
lstrcpyW ( set_name , L " QQ " ) ;
SetLastError ( 0xdeadbeef ) ;
bret = pSetUserGeoName ( set_name ) ;
ok ( ! bret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
lstrcpyW ( set_name , L " Xx " ) ;
SetLastError ( 0xdeadbeef ) ;
bret = pSetUserGeoName ( set_name ) ;
ok ( ( bret & & GetLastError ( ) = = 0xdeadbeef ) | | broken ( bret & & GetLastError ( ) = = 0 ) ,
" Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ret = = 4 & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " 001 " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
geoid = GetUserGeoID ( GEOCLASS_REGION ) ;
ok ( geoid = = 39070 , " Got unexpected geoid %u. \n " , geoid ) ;
size = sizeof ( buf ) ;
status = RegQueryValueExW ( key , L " Name " , NULL , & type , ( BYTE * ) buf , & size ) ;
ok ( status = = ERROR_SUCCESS , " Got unexpected status %#x. \n " , status ) ;
ok ( type = = REG_SZ , " Got unexpected type %#x. \n " , type ) ;
ok ( ! lstrcmpW ( buf , L " 001 " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
lstrcpyW ( set_name , L " ar " ) ;
SetLastError ( 0xdeadbeef ) ;
bret = pSetUserGeoName ( set_name ) ;
ok ( ( bret & & GetLastError ( ) = = 0xdeadbeef ) | | broken ( bret & & GetLastError ( ) = = 0 ) ,
" Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ( ret = = 3 & & GetLastError ( ) = = 0xdeadbeef ) | | broken ( ret = = 3 & & GetLastError ( ) = = 0 ) ,
" Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " AR " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
geoid = GetUserGeoID ( GEOCLASS_NATION ) ;
ok ( geoid = = 11 , " Got unexpected geoid %u. \n " , geoid ) ;
lstrcpyW ( set_name , L " 150 " ) ;
SetLastError ( 0xdeadbeef ) ;
bret = pSetUserGeoName ( set_name ) ;
ok ( ( bret & & GetLastError ( ) = = 0xdeadbeef ) | | broken ( bret & & GetLastError ( ) = = 0 ) ,
" Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ( ret = = 4 & & GetLastError ( ) = = 0xdeadbeef ) | | broken ( ret = = 4 & & GetLastError ( ) = = 0 ) ,
" Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " 150 " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
geoid = GetUserGeoID ( GEOCLASS_NATION ) ;
ok ( geoid = = 11 , " Got unexpected geoid %u. \n " , geoid ) ;
lstrcpyW ( set_name , L " 150a " ) ;
SetLastError ( 0xdeadbeef ) ;
bret = pSetUserGeoName ( set_name ) ;
ok ( ! bret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
bret = SetUserGeoID ( 21242 ) ;
ok ( bret , " Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ret = = 3 & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " XX " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
bret = SetUserGeoID ( 42483 ) ;
ok ( bret , " Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ret = = 4 & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " 011 " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
bret = SetUserGeoID ( 333 ) ;
ok ( bret , " Got unexpected bret %#x, GetLastError() %u. \n " , bret , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ret = = 3 & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " AN " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
RegDeleteValueW ( key , L " Name " ) ;
RegDeleteValueW ( key , L " Region " ) ;
lstrcpyW ( buf , L " 124 " ) ;
status = RegSetValueExW ( key , L " Nation " , 0 , REG_SZ , ( BYTE * ) buf , ( lstrlenW ( buf ) + 1 ) * sizeof ( * buf ) ) ;
ok ( status = = ERROR_SUCCESS , " Got unexpected status %#x. \n " , status ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ret = = 3 & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " JM " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
lstrcpyW ( buf , L " 333 " ) ;
status = RegSetValueExW ( key , L " Region " , 0 , REG_SZ , ( BYTE * ) buf , ( lstrlenW ( buf ) + 1 ) * sizeof ( * buf ) ) ;
ok ( status = = ERROR_SUCCESS , " Got unexpected status %#x. \n " , status ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ret = = 3 & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " JM " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
RegDeleteValueW ( key , L " Nation " ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pGetUserDefaultGeoName ( buf , ARRAY_SIZE ( buf ) ) ;
ok ( ret = = 4 & & GetLastError ( ) = = 0xdeadbeef , " Got unexpected ret %u, GetLastError() %u. \n " , ret , GetLastError ( ) ) ;
ok ( ! lstrcmpW ( buf , L " 001 " ) , " Got unexpected name %s. \n " , wine_dbgstr_w ( buf ) ) ;
/* Restore user geo data. */
if ( have_name )
{
status = RegSetValueExW ( key , L " Name " , 0 , REG_SZ , ( BYTE * ) reg_name , ( lstrlenW ( reg_name ) + 1 ) * sizeof ( * reg_name ) ) ;
ok ( status = = ERROR_SUCCESS , " Got unexpected status %#x. \n " , status ) ;
}
else
{
RegDeleteValueW ( key , L " Name " ) ;
}
if ( have_nation )
{
status = RegSetValueExW ( key , L " Nation " , 0 , REG_SZ , ( BYTE * ) nation , ( lstrlenW ( nation ) + 1 ) * sizeof ( * nation ) ) ;
ok ( status = = ERROR_SUCCESS , " Got unexpected status %#x. \n " , status ) ;
}
else
{
RegDeleteValueW ( key , L " Nation " ) ;
}
if ( have_region )
{
status = RegSetValueExW ( key , L " Region " , 0 , REG_SZ , ( BYTE * ) region , ( lstrlenW ( region ) + 1 ) * sizeof ( * region ) ) ;
ok ( status = = ERROR_SUCCESS , " Got unexpected status %#x. \n " , status ) ;
}
else
{
RegDeleteValueW ( key , L " Region " ) ;
}
RegCloseKey ( key ) ;
}
2021-11-30 03:35:45 +01:00
static const LCID locales_with_optional_calendars [ ] = {
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_SAUDI_ARABIA ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_LEBANON ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_EGYPT ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_ALGERIA ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_BAHRAIN ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_IRAQ ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_JORDAN ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_KUWAIT ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_LIBYA ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_MOROCCO ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_OMAN ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_QATAR ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_SYRIA ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_TUNISIA ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_UAE ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_ARABIC , SUBLANG_ARABIC_YEMEN ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_CHINESE , SUBLANG_CHINESE_TRADITIONAL ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_DIVEHI , SUBLANG_DEFAULT ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_PERSIAN , SUBLANG_DEFAULT ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_HEBREW , SUBLANG_DEFAULT ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_JAPANESE , SUBLANG_DEFAULT ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_KOREAN , SUBLANG_KOREAN ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_THAI , SUBLANG_DEFAULT ) , SORT_DEFAULT ) ,
MAKELCID ( MAKELANGID ( LANG_URDU , SUBLANG_URDU_PAKISTAN ) , SORT_DEFAULT )
} ;
static BOOL CALLBACK calinfo_procA ( LPSTR calinfo )
{
( void ) calinfo ;
return TRUE ;
}
static void test_EnumCalendarInfoA ( void )
{
2021-12-28 20:09:48 +01:00
BOOL ret ;
2021-11-30 03:35:45 +01:00
INT i ;
2021-12-28 20:09:48 +01:00
ret = EnumCalendarInfoA ( calinfo_procA , LOCALE_USER_DEFAULT , ENUM_ALL_CALENDARS ,
CAL_RETURN_NUMBER | CAL_ICALINTVALUE ) ;
ok ( ret , " EnumCalendarInfoA for user default locale failed: %u \n " , GetLastError ( ) ) ;
2021-11-30 03:35:45 +01:00
for ( i = 0 ; i < ARRAY_SIZE ( locales_with_optional_calendars ) ; i + + )
{
LCID lcid = locales_with_optional_calendars [ i ] ;
2021-12-28 20:09:48 +01:00
ret = EnumCalendarInfoA ( calinfo_procA , lcid , ENUM_ALL_CALENDARS ,
CAL_RETURN_NUMBER | CAL_ICALINTVALUE ) ;
ok ( ret | | broken ( GetLastError ( ) = = ERROR_INVALID_FLAGS ) /* no locale */ ,
2021-11-30 03:35:45 +01:00
" EnumCalendarInfoA for LCID %#06x failed: %u \n " , lcid , GetLastError ( ) ) ;
}
}
static BOOL CALLBACK calinfo_procW ( LPWSTR calinfo )
{
( void ) calinfo ;
return TRUE ;
}
static void test_EnumCalendarInfoW ( void )
{
2021-12-28 20:09:48 +01:00
BOOL ret ;
2021-11-30 03:35:45 +01:00
INT i ;
2021-12-28 20:09:48 +01:00
ret = EnumCalendarInfoW ( calinfo_procW , LOCALE_USER_DEFAULT , ENUM_ALL_CALENDARS ,
CAL_RETURN_NUMBER | CAL_ICALINTVALUE ) ;
ok ( ret , " EnumCalendarInfoW for user default locale failed: %u \n " , GetLastError ( ) ) ;
2021-11-30 03:35:45 +01:00
for ( i = 0 ; i < ARRAY_SIZE ( locales_with_optional_calendars ) ; i + + )
{
LCID lcid = locales_with_optional_calendars [ i ] ;
2021-12-28 20:09:48 +01:00
ret = EnumCalendarInfoW ( calinfo_procW , lcid , ENUM_ALL_CALENDARS ,
CAL_RETURN_NUMBER | CAL_ICALINTVALUE ) ;
ok ( ret | | broken ( GetLastError ( ) = = ERROR_INVALID_FLAGS ) /* no locale */ ,
2021-11-30 03:35:45 +01:00
" EnumCalendarInfoW for LCID %#06x failed: %u \n " , lcid , GetLastError ( ) ) ;
}
}
static BOOL CALLBACK calinfoex_procA ( LPSTR calinfo , LCID calid )
{
( void ) calinfo ;
( void ) calid ;
return TRUE ;
}
static void test_EnumCalendarInfoExA ( void )
{
2021-12-28 20:09:48 +01:00
BOOL ret ;
2021-11-30 03:35:45 +01:00
INT i ;
2021-12-28 20:09:48 +01:00
ret = EnumCalendarInfoExA ( calinfoex_procA , LOCALE_USER_DEFAULT , ENUM_ALL_CALENDARS ,
CAL_RETURN_NUMBER | CAL_ICALINTVALUE ) ;
ok ( ret , " EnumCalendarInfoExA for user default locale failed: %u \n " , GetLastError ( ) ) ;
2021-11-30 03:35:45 +01:00
for ( i = 0 ; i < ARRAY_SIZE ( locales_with_optional_calendars ) ; i + + )
{
LCID lcid = locales_with_optional_calendars [ i ] ;
2021-12-28 20:09:48 +01:00
ret = EnumCalendarInfoExA ( calinfoex_procA , lcid , ENUM_ALL_CALENDARS ,
CAL_RETURN_NUMBER | CAL_ICALINTVALUE ) ;
ok ( ret | | broken ( GetLastError ( ) = = ERROR_INVALID_FLAGS ) /* no locale */ ,
2021-11-30 03:35:45 +01:00
" EnumCalendarInfoExA for LCID %#06x failed: %u \n " , lcid , GetLastError ( ) ) ;
}
}
static BOOL CALLBACK calinfoex_procW ( LPWSTR calinfo , LCID calid )
{
( void ) calinfo ;
( void ) calid ;
return TRUE ;
}
static void test_EnumCalendarInfoExW ( void )
{
2021-12-28 20:09:48 +01:00
BOOL ret ;
2021-11-30 03:35:45 +01:00
INT i ;
2021-12-28 20:09:48 +01:00
ret = EnumCalendarInfoExW ( calinfoex_procW , LOCALE_USER_DEFAULT , ENUM_ALL_CALENDARS ,
CAL_RETURN_NUMBER | CAL_ICALINTVALUE ) ;
ok ( ret , " EnumCalendarInfoExW for user default locale failed: %u \n " , GetLastError ( ) ) ;
2021-11-30 03:35:45 +01:00
for ( i = 0 ; i < ARRAY_SIZE ( locales_with_optional_calendars ) ; i + + )
{
LCID lcid = locales_with_optional_calendars [ i ] ;
2021-12-28 20:09:48 +01:00
ret = EnumCalendarInfoExW ( calinfoex_procW , lcid , ENUM_ALL_CALENDARS ,
CAL_RETURN_NUMBER | CAL_ICALINTVALUE ) ;
ok ( ret | | broken ( GetLastError ( ) = = ERROR_INVALID_FLAGS ) /* no locale */ ,
2021-11-30 03:35:45 +01:00
" EnumCalendarInfoExW for LCID %#06x failed: %u \n " , lcid , GetLastError ( ) ) ;
}
}
2002-05-29 02:30:32 +02:00
START_TEST ( locale )
{
2003-09-24 20:52:39 +02:00
InitFunctionPointers ( ) ;
2005-07-28 12:16:02 +02:00
test_EnumTimeFormatsA ( ) ;
2015-11-10 15:40:07 +01:00
test_EnumTimeFormatsW ( ) ;
2005-07-27 17:15:02 +02:00
test_EnumDateFormatsA ( ) ;
2003-09-18 00:40:07 +02:00
test_GetLocaleInfoA ( ) ;
2009-10-20 21:46:34 +02:00
test_GetLocaleInfoW ( ) ;
2012-07-26 09:20:46 +02:00
test_GetLocaleInfoEx ( ) ;
2003-09-18 00:40:07 +02:00
test_GetTimeFormatA ( ) ;
2014-12-24 17:52:04 +01:00
test_GetTimeFormatEx ( ) ;
2003-09-18 00:40:07 +02:00
test_GetDateFormatA ( ) ;
2014-12-24 17:52:04 +01:00
test_GetDateFormatEx ( ) ;
2003-09-18 00:40:07 +02:00
test_GetDateFormatW ( ) ;
test_GetCurrencyFormatA ( ) ; /* Also tests the W version */
test_GetNumberFormatA ( ) ; /* Also tests the W version */
2016-08-15 19:54:20 +02:00
test_GetNumberFormatEx ( ) ;
2003-09-18 00:40:07 +02:00
test_CompareStringA ( ) ;
2016-02-13 22:24:06 +01:00
test_CompareStringW ( ) ;
2014-04-16 21:54:58 +02:00
test_CompareStringEx ( ) ;
2003-09-18 00:40:07 +02:00
test_LCMapStringA ( ) ;
test_LCMapStringW ( ) ;
2012-06-04 22:53:55 +02:00
test_LCMapStringEx ( ) ;
2012-07-26 09:20:46 +02:00
test_LocaleNameToLCID ( ) ;
2003-10-24 02:26:18 +02:00
test_FoldStringA ( ) ;
test_FoldStringW ( ) ;
2003-09-24 20:52:39 +02:00
test_ConvertDefaultLocale ( ) ;
test_EnumSystemLanguageGroupsA ( ) ;
2010-09-27 14:03:12 +02:00
test_EnumSystemLocalesEx ( ) ;
2003-09-24 20:52:39 +02:00
test_EnumLanguageGroupLocalesA ( ) ;
test_SetLocaleInfoA ( ) ;
2004-11-01 22:06:28 +01:00
test_EnumUILanguageA ( ) ;
2007-04-01 13:16:42 +02:00
test_GetCPInfo ( ) ;
2010-07-19 20:52:57 +02:00
test_GetStringTypeW ( ) ;
2020-02-28 15:25:22 +01:00
test_Idn ( ) ;
2012-07-27 05:00:24 +02:00
test_IsValidLocaleName ( ) ;
2012-10-31 09:56:39 +01:00
test_CompareStringOrdinal ( ) ;
2014-07-11 04:36:18 +02:00
test_GetGeoInfo ( ) ;
2014-07-15 03:51:32 +02:00
test_EnumSystemGeoID ( ) ;
2015-08-26 09:06:07 +02:00
test_invariant ( ) ;
2016-01-17 10:00:55 +01:00
test_GetSystemPreferredUILanguages ( ) ;
2016-04-29 10:14:35 +02:00
test_GetThreadPreferredUILanguages ( ) ;
2016-10-18 20:00:12 +02:00
test_GetUserPreferredUILanguages ( ) ;
2018-03-13 15:09:45 +01:00
test_FindNLSStringEx ( ) ;
2018-10-30 07:31:57 +01:00
test_FindStringOrdinal ( ) ;
2018-03-31 11:24:53 +02:00
test_SetThreadUILanguage ( ) ;
2018-04-09 20:38:00 +02:00
test_NormalizeString ( ) ;
2019-02-14 03:39:48 +01:00
test_SpecialCasing ( ) ;
2020-03-20 12:54:36 +01:00
test_NLSVersion ( ) ;
2021-03-08 17:34:40 +01:00
test_geo_name ( ) ;
2021-08-17 17:32:50 +02:00
test_sorting ( ) ;
2021-11-30 03:35:45 +01:00
test_EnumCalendarInfoA ( ) ;
test_EnumCalendarInfoW ( ) ;
test_EnumCalendarInfoExA ( ) ;
test_EnumCalendarInfoExW ( ) ;
2002-05-29 02:30:32 +02:00
}