Commit 7bb286ad authored by Alexandre Julliard's avatar Alexandre Julliard

kernel32: Move FoldStringW() function to kernelbase.

parent e89bbd52
...@@ -521,7 +521,7 @@ ...@@ -521,7 +521,7 @@
@ stdcall FlushProcessWriteBuffers() @ stdcall FlushProcessWriteBuffers()
@ stdcall -import FlushViewOfFile(ptr long) @ stdcall -import FlushViewOfFile(ptr long)
@ stdcall FoldStringA(long str long ptr long) @ stdcall FoldStringA(long str long ptr long)
@ stdcall FoldStringW(long wstr long ptr long) @ stdcall -import FoldStringW(long wstr long ptr long)
@ stdcall FormatMessageA(long ptr long long ptr long ptr) @ stdcall FormatMessageA(long ptr long long ptr long ptr)
@ stdcall FormatMessageW(long ptr long long ptr long ptr) @ stdcall FormatMessageW(long ptr long long ptr long ptr)
@ stdcall FreeConsole() @ stdcall FreeConsole()
......
...@@ -2162,171 +2162,6 @@ FoldStringA_exit: ...@@ -2162,171 +2162,6 @@ FoldStringA_exit:
return ret; return ret;
} }
/* Unicode expanded ligatures */
static const WCHAR ligatures[][5] =
{
{ 0x00c6, 'A','E',0 },
{ 0x00de, 'T','H',0 },
{ 0x00df, 's','s',0 },
{ 0x00e6, 'a','e',0 },
{ 0x00fe, 't','h',0 },
{ 0x0132, 'I','J',0 },
{ 0x0133, 'i','j',0 },
{ 0x0152, 'O','E',0 },
{ 0x0153, 'o','e',0 },
{ 0x01c4, 'D',0x017d,0 },
{ 0x01c5, 'D',0x017e,0 },
{ 0x01c6, 'd',0x017e,0 },
{ 0x01c7, 'L','J',0 },
{ 0x01c8, 'L','j',0 },
{ 0x01c9, 'l','j',0 },
{ 0x01ca, 'N','J',0 },
{ 0x01cb, 'N','j',0 },
{ 0x01cc, 'n','j',0 },
{ 0x01e2, 0x0100,0x0112,0 },
{ 0x01e3, 0x0101,0x0113,0 },
{ 0x01f1, 'D','Z',0 },
{ 0x01f2, 'D','z',0 },
{ 0x01f3, 'd','z',0 },
{ 0x01fc, 0x00c1,0x00c9,0 },
{ 0x01fd, 0x00e1,0x00e9,0 },
{ 0x05f0, 0x05d5,0x05d5,0 },
{ 0x05f1, 0x05d5,0x05d9,0 },
{ 0x05f2, 0x05d9,0x05d9,0 },
{ 0xfb00, 'f','f',0 },
{ 0xfb01, 'f','i',0 },
{ 0xfb02, 'f','l',0 },
{ 0xfb03, 'f','f','i',0 },
{ 0xfb04, 'f','f','l',0 },
{ 0xfb05, 0x017f,'t',0 },
{ 0xfb06, 's','t',0 },
};
static const WCHAR *get_ligature( WCHAR wc )
{
int low = 0, high = ARRAY_SIZE( ligatures ) -1;
while (low <= high)
{
int pos = (low + high) / 2;
if (ligatures[pos][0] < wc) low = pos + 1;
else if (ligatures[pos][0] > wc) high = pos - 1;
else return ligatures[pos] + 1;
}
return NULL;
}
static int expand_ligatures( const WCHAR *src, int srclen, WCHAR *dst, int dstlen )
{
int i, len, pos = 0;
const WCHAR *expand;
for (i = 0; i < srclen; i++)
{
if (!(expand = get_ligature( src[i] )))
{
expand = src + i;
len = 1;
}
else len = lstrlenW( expand );
if (dstlen)
{
if (pos + len > dstlen) break;
memcpy( dst + pos, expand, len * sizeof(WCHAR) );
}
pos += len;
}
return pos;
}
static int fold_digits( const WCHAR *src, int srclen, WCHAR *dst, int dstlen )
{
extern const WCHAR wine_digitmap[] DECLSPEC_HIDDEN;
int i;
if (!dstlen) return srclen;
if (srclen > dstlen) return 0;
for (i = 0; i < srclen; i++)
dst[i] = src[i] + wine_digitmap[wine_digitmap[src[i] >> 8] + (src[i] & 0xff)];
return srclen;
}
/*************************************************************************
* FoldStringW (KERNEL32.@)
*
* See FoldStringA.
*/
INT WINAPI FoldStringW(DWORD dwFlags, LPCWSTR src, INT srclen,
LPWSTR dst, INT dstlen)
{
WCHAR *tmp;
int ret;
if (!src || !srclen || dstlen < 0 || (dstlen && !dst) || src == dst)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (srclen == -1) srclen = lstrlenW(src) + 1;
switch (dwFlags)
{
case MAP_PRECOMPOSED:
return NormalizeString( NormalizationC, src, srclen, dst, dstlen );
case MAP_FOLDCZONE:
case MAP_PRECOMPOSED | MAP_FOLDCZONE:
return NormalizeString( NormalizationKC, src, srclen, dst, dstlen );
case MAP_COMPOSITE:
return NormalizeString( NormalizationD, src, srclen, dst, dstlen );
case MAP_COMPOSITE | MAP_FOLDCZONE:
return NormalizeString( NormalizationKD, src, srclen, dst, dstlen );
case MAP_FOLDDIGITS:
return fold_digits( src, srclen, dst, dstlen );
case MAP_EXPAND_LIGATURES:
case MAP_EXPAND_LIGATURES | MAP_FOLDCZONE:
return expand_ligatures( src, srclen, dst, dstlen );
case MAP_FOLDDIGITS | MAP_PRECOMPOSED:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = NormalizeString( NormalizationC, tmp, srclen, dst, dstlen );
break;
case MAP_FOLDDIGITS | MAP_FOLDCZONE:
case MAP_FOLDDIGITS | MAP_PRECOMPOSED | MAP_FOLDCZONE:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = NormalizeString( NormalizationKC, tmp, srclen, dst, dstlen );
break;
case MAP_FOLDDIGITS | MAP_COMPOSITE:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = NormalizeString( NormalizationD, tmp, srclen, dst, dstlen );
break;
case MAP_FOLDDIGITS | MAP_COMPOSITE | MAP_FOLDCZONE:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = NormalizeString( NormalizationKD, tmp, srclen, dst, dstlen );
break;
case MAP_EXPAND_LIGATURES | MAP_FOLDDIGITS:
case MAP_EXPAND_LIGATURES | MAP_FOLDDIGITS | MAP_FOLDCZONE:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = expand_ligatures( tmp, srclen, dst, dstlen );
break;
default:
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
if (!tmp)
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
RtlFreeHeap( GetProcessHeap(), 0, tmp );
return ret;
}
/****************************************************************************** /******************************************************************************
* CompareStringW (KERNEL32.@) * CompareStringW (KERNEL32.@)
* *
......
...@@ -6,6 +6,7 @@ EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -mno-cygwin ...@@ -6,6 +6,7 @@ EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -mno-cygwin
C_SRCS = \ C_SRCS = \
console.c \ console.c \
debug.c \ debug.c \
digitmap.c \
file.c \ file.c \
loader.c \ loader.c \
locale.c \ locale.c \
......
...@@ -384,7 +384,7 @@ ...@@ -384,7 +384,7 @@
@ stdcall FlushInstructionCache(long long long) @ stdcall FlushInstructionCache(long long long)
@ stdcall FlushProcessWriteBuffers() kernel32.FlushProcessWriteBuffers @ stdcall FlushProcessWriteBuffers() kernel32.FlushProcessWriteBuffers
@ stdcall FlushViewOfFile(ptr long) @ stdcall FlushViewOfFile(ptr long)
@ stdcall FoldStringW(long wstr long ptr long) kernel32.FoldStringW @ stdcall FoldStringW(long wstr long ptr long)
# @ stub ForceSyncFgPolicyInternal # @ stub ForceSyncFgPolicyInternal
# @ stub FormatApplicationUserModelId # @ stub FormatApplicationUserModelId
@ stdcall FormatMessageA(long ptr long long ptr long ptr) kernel32.FormatMessageA @ stdcall FormatMessageA(long ptr long long ptr long ptr) kernel32.FormatMessageA
......
...@@ -173,6 +173,46 @@ static const struct { UINT cp; const WCHAR *name; } codepage_names[] = ...@@ -173,6 +173,46 @@ static const struct { UINT cp; const WCHAR *name; } codepage_names[] =
{ 65001, L"Unicode (UTF-8)" } { 65001, L"Unicode (UTF-8)" }
}; };
/* Unicode expanded ligatures */
static const WCHAR ligatures[][5] =
{
{ 0x00c6, 'A','E',0 },
{ 0x00de, 'T','H',0 },
{ 0x00df, 's','s',0 },
{ 0x00e6, 'a','e',0 },
{ 0x00fe, 't','h',0 },
{ 0x0132, 'I','J',0 },
{ 0x0133, 'i','j',0 },
{ 0x0152, 'O','E',0 },
{ 0x0153, 'o','e',0 },
{ 0x01c4, 'D',0x017d,0 },
{ 0x01c5, 'D',0x017e,0 },
{ 0x01c6, 'd',0x017e,0 },
{ 0x01c7, 'L','J',0 },
{ 0x01c8, 'L','j',0 },
{ 0x01c9, 'l','j',0 },
{ 0x01ca, 'N','J',0 },
{ 0x01cb, 'N','j',0 },
{ 0x01cc, 'n','j',0 },
{ 0x01e2, 0x0100,0x0112,0 },
{ 0x01e3, 0x0101,0x0113,0 },
{ 0x01f1, 'D','Z',0 },
{ 0x01f2, 'D','z',0 },
{ 0x01f3, 'd','z',0 },
{ 0x01fc, 0x00c1,0x00c9,0 },
{ 0x01fd, 0x00e1,0x00e9,0 },
{ 0x05f0, 0x05d5,0x05d5,0 },
{ 0x05f1, 0x05d5,0x05d9,0 },
{ 0x05f2, 0x05d9,0x05d9,0 },
{ 0xfb00, 'f','f',0 },
{ 0xfb01, 'f','i',0 },
{ 0xfb02, 'f','l',0 },
{ 0xfb03, 'f','f','i',0 },
{ 0xfb04, 'f','f','l',0 },
{ 0xfb05, 0x017f,'t',0 },
{ 0xfb06, 's','t',0 },
};
static NLSTABLEINFO nls_info; static NLSTABLEINFO nls_info;
static UINT mac_cp = 10000; static UINT mac_cp = 10000;
static HKEY intl_key; static HKEY intl_key;
...@@ -325,6 +365,58 @@ done: ...@@ -325,6 +365,58 @@ done:
} }
static const WCHAR *get_ligature( WCHAR wc )
{
int low = 0, high = ARRAY_SIZE( ligatures ) -1;
while (low <= high)
{
int pos = (low + high) / 2;
if (ligatures[pos][0] < wc) low = pos + 1;
else if (ligatures[pos][0] > wc) high = pos - 1;
else return ligatures[pos] + 1;
}
return NULL;
}
static int expand_ligatures( const WCHAR *src, int srclen, WCHAR *dst, int dstlen )
{
int i, len, pos = 0;
const WCHAR *expand;
for (i = 0; i < srclen; i++)
{
if (!(expand = get_ligature( src[i] )))
{
expand = src + i;
len = 1;
}
else len = lstrlenW( expand );
if (dstlen)
{
if (pos + len > dstlen) break;
memcpy( dst + pos, expand, len * sizeof(WCHAR) );
}
pos += len;
}
return pos;
}
static int fold_digits( const WCHAR *src, int srclen, WCHAR *dst, int dstlen )
{
extern const WCHAR wine_digitmap[] DECLSPEC_HIDDEN;
int i;
if (!dstlen) return srclen;
if (srclen > dstlen) return 0;
for (i = 0; i < srclen; i++)
dst[i] = src[i] + wine_digitmap[wine_digitmap[src[i] >> 8] + (src[i] & 0xff)];
return srclen;
}
/* Note: the Internal_ functions are not documented. The number of parameters /* Note: the Internal_ functions are not documented. The number of parameters
* should be correct, but their exact meaning may not. * should be correct, but their exact meaning may not.
*/ */
...@@ -986,6 +1078,78 @@ INT WINAPI DECLSPEC_HOTPATCH FindStringOrdinal( DWORD flag, const WCHAR *src, IN ...@@ -986,6 +1078,78 @@ INT WINAPI DECLSPEC_HOTPATCH FindStringOrdinal( DWORD flag, const WCHAR *src, IN
/****************************************************************************** /******************************************************************************
* FoldStringW (kernelbase.@)
*/
INT WINAPI DECLSPEC_HOTPATCH FoldStringW( DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen )
{
WCHAR *tmp;
int ret;
if (!src || !srclen || dstlen < 0 || (dstlen && !dst) || src == dst)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (srclen == -1) srclen = lstrlenW(src) + 1;
switch (flags)
{
case MAP_PRECOMPOSED:
return NormalizeString( NormalizationC, src, srclen, dst, dstlen );
case MAP_FOLDCZONE:
case MAP_PRECOMPOSED | MAP_FOLDCZONE:
return NormalizeString( NormalizationKC, src, srclen, dst, dstlen );
case MAP_COMPOSITE:
return NormalizeString( NormalizationD, src, srclen, dst, dstlen );
case MAP_COMPOSITE | MAP_FOLDCZONE:
return NormalizeString( NormalizationKD, src, srclen, dst, dstlen );
case MAP_FOLDDIGITS:
return fold_digits( src, srclen, dst, dstlen );
case MAP_EXPAND_LIGATURES:
case MAP_EXPAND_LIGATURES | MAP_FOLDCZONE:
return expand_ligatures( src, srclen, dst, dstlen );
case MAP_FOLDDIGITS | MAP_PRECOMPOSED:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = NormalizeString( NormalizationC, tmp, srclen, dst, dstlen );
break;
case MAP_FOLDDIGITS | MAP_FOLDCZONE:
case MAP_FOLDDIGITS | MAP_PRECOMPOSED | MAP_FOLDCZONE:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = NormalizeString( NormalizationKC, tmp, srclen, dst, dstlen );
break;
case MAP_FOLDDIGITS | MAP_COMPOSITE:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = NormalizeString( NormalizationD, tmp, srclen, dst, dstlen );
break;
case MAP_FOLDDIGITS | MAP_COMPOSITE | MAP_FOLDCZONE:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = NormalizeString( NormalizationKD, tmp, srclen, dst, dstlen );
break;
case MAP_EXPAND_LIGATURES | MAP_FOLDDIGITS:
case MAP_EXPAND_LIGATURES | MAP_FOLDDIGITS | MAP_FOLDCZONE:
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
ret = expand_ligatures( tmp, srclen, dst, dstlen );
break;
default:
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
if (!tmp)
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
RtlFreeHeap( GetProcessHeap(), 0, tmp );
return ret;
}
/******************************************************************************
* GetACP (kernelbase.@) * GetACP (kernelbase.@)
*/ */
UINT WINAPI GetACP(void) UINT WINAPI GetACP(void)
......
...@@ -1808,9 +1808,9 @@ sub dump_vertical($) ...@@ -1808,9 +1808,9 @@ sub dump_vertical($)
################################################################ ################################################################
# dump the digit folding tables # dump the digit folding tables
sub dump_digit_folding($) sub dump_digit_folding($$)
{ {
my $filename = shift; my ($filename, $compat) = @_;
open OUTPUT,">$filename.new" or die "Cannot create $filename"; open OUTPUT,">$filename.new" or die "Cannot create $filename";
print "Building $filename\n"; print "Building $filename\n";
print OUTPUT "/* Unicode digit folding mappings */\n"; print OUTPUT "/* Unicode digit folding mappings */\n";
...@@ -1819,8 +1819,11 @@ sub dump_digit_folding($) ...@@ -1819,8 +1819,11 @@ sub dump_digit_folding($)
print OUTPUT "#include \"windef.h\"\n\n"; print OUTPUT "#include \"windef.h\"\n\n";
dump_case_table( "DECLSPEC_HIDDEN wine_digitmap", @digitmap_table ); dump_case_table( "DECLSPEC_HIDDEN wine_digitmap", @digitmap_table );
print OUTPUT "\n"; if ($compat)
dump_case_table( "DECLSPEC_HIDDEN wine_compatmap", @compatmap_table ); {
print OUTPUT "\n";
dump_case_table( "DECLSPEC_HIDDEN wine_compatmap", @compatmap_table );
}
close OUTPUT; close OUTPUT;
save_file($filename); save_file($filename);
} }
...@@ -2891,7 +2894,8 @@ dump_bidi_dir_table( "dlls/gdi32/direction.c" ); ...@@ -2891,7 +2894,8 @@ dump_bidi_dir_table( "dlls/gdi32/direction.c" );
dump_bidi_dir_table( "dlls/usp10/direction.c" ); dump_bidi_dir_table( "dlls/usp10/direction.c" );
dump_bidi_dir_table( "dlls/dwrite/direction.c" ); dump_bidi_dir_table( "dlls/dwrite/direction.c" );
dump_string_type_table( "dlls/kernel32/wctype.c" ); dump_string_type_table( "dlls/kernel32/wctype.c" );
dump_digit_folding( "libs/port/digitmap.c" ); dump_digit_folding( "libs/port/digitmap.c", 1 );
dump_digit_folding( "dlls/kernelbase/digitmap.c", 0 );
dump_combining_class( "libs/port/combclass.c" ); dump_combining_class( "libs/port/combclass.c" );
dump_mirroring( "dlls/usp10/mirror.c" ); dump_mirroring( "dlls/usp10/mirror.c" );
dump_mirroring( "dlls/dwrite/mirror.c" ); dump_mirroring( "dlls/dwrite/mirror.c" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment