diff --git a/dlls/kernelbase/decompose.c b/dlls/kernelbase/decompose.c index 262dd67a0fc..a6558917505 100644 --- a/dlls/kernelbase/decompose.c +++ b/dlls/kernelbase/decompose.c @@ -4,7 +4,7 @@ #include "windef.h" -static const WCHAR table[6061] = +const WCHAR DECLSPEC_HIDDEN nfd_table[6061] = { /* index */ 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0100, 0x0160, 0x0100, @@ -957,17 +957,3 @@ static const WCHAR table[6061] = 0x05e9, 0x05bc, 0x05ea, 0x05bc, 0x05d5, 0x05b9, 0x05d1, 0x05bf, 0x05db, 0x05bf, 0x05e4, 0x05bf }; - -unsigned int DECLSPEC_HIDDEN wine_decompose( int flags, WCHAR ch, WCHAR *dst, unsigned int dstlen ) -{ - unsigned short offset = table[table[ch >> 8] + ((ch >> 4) & 0xf)] + (ch & 0xf); - unsigned short start = table[offset]; - unsigned short end = table[offset + 1]; - unsigned int len = end - start; - - *dst = ch; - if (!len) return 1; - if (dstlen < len) return 0; - memcpy( dst, table + start, len * sizeof(WCHAR) ); - return len; -} diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c index a2d4735c300..29cc18f9cd7 100644 --- a/dlls/kernelbase/locale.c +++ b/dlls/kernelbase/locale.c @@ -42,11 +42,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(nls); #define CALINFO_MAX_YEAR 2029 extern UINT CDECL __wine_get_unix_codepage(void); -extern unsigned int wine_decompose( int flags, WCHAR ch, WCHAR *dst, unsigned int dstlen ) DECLSPEC_HIDDEN; extern WCHAR wine_compose( const WCHAR *str ) DECLSPEC_HIDDEN; extern const unsigned short wctype_table[] DECLSPEC_HIDDEN; extern const unsigned int collation_table[] DECLSPEC_HIDDEN; +extern const unsigned short nfd_table[] DECLSPEC_HIDDEN; static HANDLE kernel32_handle; @@ -675,6 +675,18 @@ static inline WCHAR casemap( const USHORT *table, WCHAR ch ) } +static const WCHAR *get_decomposition( WCHAR ch, unsigned int *len ) +{ + unsigned short offset = nfd_table[nfd_table[ch >> 8] + ((ch >> 4) & 0xf)] + (ch & 0xf); + unsigned short start = nfd_table[offset]; + unsigned short end = nfd_table[offset + 1]; + + if ((*len = end - start)) return nfd_table + start; + *len = 1; + return NULL; +} + + static UINT get_lcid_codepage( LCID lcid, ULONG flags ) { UINT ret = GetACP(); @@ -1138,15 +1150,17 @@ static int check_invalid_chars( const CPTABLEINFO *info, const unsigned char *sr static int mbstowcs_decompose( const CPTABLEINFO *info, const unsigned char *src, int srclen, WCHAR *dst, int dstlen ) { - WCHAR ch, dummy[4]; /* no decomposition is larger than 4 chars */ + WCHAR ch; USHORT off; - int len, res; + int len; + const WCHAR *decomp; + unsigned int decomp_len; if (info->DBCSOffsets) { if (!dstlen) /* compute length */ { - for (len = 0; srclen; srclen--, src++) + for (len = 0; srclen; srclen--, src++, len += decomp_len) { if ((off = info->DBCSOffsets[*src])) { @@ -1159,12 +1173,12 @@ static int mbstowcs_decompose( const CPTABLEINFO *info, const unsigned char *src else ch = info->UniDefaultChar; } else ch = info->MultiByteTable[*src]; - len += wine_decompose( 0, ch, dummy, 4 ); + get_decomposition( ch, &decomp_len ); } return len; } - for (len = dstlen; srclen && len; srclen--, src++) + for (len = dstlen; srclen && len; srclen--, src++, dst += decomp_len, len -= decomp_len) { if ((off = info->DBCSOffsets[*src])) { @@ -1177,25 +1191,33 @@ static int mbstowcs_decompose( const CPTABLEINFO *info, const unsigned char *src else ch = info->UniDefaultChar; } else ch = info->MultiByteTable[*src]; - if (!(res = wine_decompose( 0, ch, dst, len ))) break; - dst += res; - len -= res; + + if ((decomp = get_decomposition( ch, &decomp_len ))) + { + if (len < decomp_len) break; + memcpy( dst, decomp, decomp_len * sizeof(WCHAR) ); + } + else *dst = ch; } } else { if (!dstlen) /* compute length */ { - for (len = 0; srclen; srclen--, src++) - len += wine_decompose( 0, info->MultiByteTable[*src], dummy, 4 ); + for (len = 0; srclen; srclen--, src++, len += decomp_len) + get_decomposition( info->MultiByteTable[*src], &decomp_len ); return len; } - for (len = dstlen; srclen && len; srclen--, src++) + for (len = dstlen; srclen && len; srclen--, src++, dst += decomp_len, len -= decomp_len) { - if (!(res = wine_decompose( 0, info->MultiByteTable[*src], dst, len ))) break; - len -= res; - dst += res; + ch = info->MultiByteTable[*src]; + if ((decomp = get_decomposition( ch, &decomp_len ))) + { + if (len < decomp_len) break; + memcpy( dst, decomp, decomp_len * sizeof(WCHAR) ); + } + else *dst = ch; } } @@ -2227,7 +2249,7 @@ static unsigned int get_weight( WCHAR ch, enum weight type ) } -static void inc_str_pos( const WCHAR **str, int *len, int *dpos, int *dlen ) +static void inc_str_pos( const WCHAR **str, int *len, unsigned int *dpos, unsigned int *dlen ) { (*dpos)++; if (*dpos == *dlen) @@ -2242,14 +2264,13 @@ static void inc_str_pos( const WCHAR **str, int *len, int *dpos, int *dlen ) static int compare_weights(int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2, enum weight type ) { - int dpos1 = 0, dpos2 = 0, dlen1 = 0, dlen2 = 0; - WCHAR dstr1[4], dstr2[4]; - unsigned int ce1, ce2; + unsigned int ce1, ce2, dpos1 = 0, dpos2 = 0, dlen1 = 0, dlen2 = 0; + const WCHAR *dstr1 = NULL, *dstr2 = NULL; while (len1 > 0 && len2 > 0) { - if (!dlen1) dlen1 = wine_decompose( 0, *str1, dstr1, 4 ); - if (!dlen2) dlen2 = wine_decompose( 0, *str2, dstr2, 4 ); + if (!dlen1 && !(dstr1 = get_decomposition( *str1, &dlen1 ))) dstr1 = str1; + if (!dlen2 && !(dstr2 = get_decomposition( *str2, &dlen2 ))) dstr2 = str2; if (flags & NORM_IGNORESYMBOLS) { @@ -2308,14 +2329,14 @@ static int compare_weights(int flags, const WCHAR *str1, int len1, } while (len1) { - if (!dlen1) dlen1 = wine_decompose( 0, *str1, dstr1, 4 ); + if (!dlen1 && !(dstr1 = get_decomposition( *str1, &dlen1 ))) dstr1 = str1; ce1 = get_weight( dstr1[dpos1], type ); if (ce1) break; inc_str_pos( &str1, &len1, &dpos1, &dlen1 ); } while (len2) { - if (!dlen2) dlen2 = wine_decompose( 0, *str2, dstr2, 4 ); + if (!dlen2 && !(dstr2 = get_decomposition( *str2, &dlen2 ))) dstr2 = str2; ce2 = get_weight( dstr2[dpos2], type ); if (ce2) break; inc_str_pos( &str2, &len2, &dpos2, &dlen2 ); diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c index 8d266e00943..784203378ab 100644 --- a/dlls/ntdll/locale.c +++ b/dlls/ntdll/locale.c @@ -83,8 +83,9 @@ static HMODULE kernel32_handle; static const union cptable *unix_table; /* NULL if UTF8 */ extern WCHAR wine_compose( const WCHAR *str ) DECLSPEC_HIDDEN; -extern unsigned int wine_decompose( int flags, WCHAR ch, WCHAR *dst, unsigned int dstlen ) DECLSPEC_HIDDEN; extern const unsigned short combining_class_table[] DECLSPEC_HIDDEN; +extern const unsigned short nfd_table[] DECLSPEC_HIDDEN; +extern const unsigned short nfkd_table[] DECLSPEC_HIDDEN; static NTSTATUS load_string( ULONG id, LANGID lang, WCHAR *buffer, ULONG len ) { @@ -153,6 +154,18 @@ static WCHAR casemap_ascii( WCHAR ch ) } +static const WCHAR *get_decomposition( const unsigned short *table, WCHAR ch, unsigned int *len ) +{ + unsigned short offset = table[table[ch >> 8] + ((ch >> 4) & 0xf)] + (ch & 0xf); + unsigned short start = table[offset]; + unsigned short end = table[offset + 1]; + + if ((*len = end - start)) return table + start; + *len = 1; + return NULL; +} + + static BYTE get_combining_class( WCHAR c ) { return combining_class_table[combining_class_table[combining_class_table[c >> 8] + ((c >> 4) & 0xf)] + (c & 0xf)]; @@ -223,20 +236,27 @@ static void canonical_order_string( WCHAR *str, unsigned int len ) } -static NTSTATUS decompose_string( int flags, const WCHAR *src, int src_len, WCHAR *dst, int *dst_len ) +static NTSTATUS decompose_string( int compat, const WCHAR *src, int src_len, WCHAR *dst, int *dst_len ) { - int src_pos, dst_pos = 0, decomp_len; + const unsigned short *table = compat ? nfkd_table : nfd_table; + int src_pos, dst_pos = 0; + unsigned int decomp_len; + const WCHAR *decomp; for (src_pos = 0; src_pos < src_len; src_pos++) { if (dst_pos == *dst_len) break; - decomp_len = wine_decompose( flags, src[src_pos], dst + dst_pos, *dst_len - dst_pos ); - if (decomp_len == 0) break; + if ((decomp = get_decomposition( table, src[src_pos], &decomp_len ))) + { + if (dst_pos + decomp_len > *dst_len) break; + memcpy( dst + dst_pos, decomp, decomp_len * sizeof(WCHAR) ); + } + else dst[dst_pos] = src[src_pos]; dst_pos += decomp_len; } if (src_pos < src_len) { - *dst_len += (src_len - src_pos) * (flags & WINE_DECOMPOSE_COMPAT ? 18 : 3); + *dst_len += (src_len - src_pos) * (compat ? 18 : 3); return STATUS_BUFFER_TOO_SMALL; } canonical_order_string( dst, dst_pos ); @@ -1691,7 +1711,7 @@ NTSTATUS WINAPI RtlIsNormalizedString( ULONG form, const WCHAR *str, INT len, BO */ NTSTATUS WINAPI RtlNormalizeString( ULONG form, const WCHAR *src, INT src_len, WCHAR *dst, INT *dst_len ) { - int flags = 0, compose, compat, buf_len; + int compose, compat, buf_len; WCHAR *buf = NULL; NTSTATUS status = STATUS_SUCCESS; @@ -1721,16 +1741,14 @@ NTSTATUS WINAPI RtlNormalizeString( ULONG form, const WCHAR *src, INT src_len, W return STATUS_SUCCESS; } - if (compat) flags |= WINE_DECOMPOSE_COMPAT; - - if (!compose) return decompose_string( flags, src, src_len, dst, dst_len ); + if (!compose) return decompose_string( compat, src, src_len, dst, dst_len ); buf_len = src_len * 4; for (;;) { buf = RtlAllocateHeap( GetProcessHeap(), 0, buf_len * sizeof(WCHAR) ); if (!buf) return STATUS_NO_MEMORY; - status = decompose_string( flags, src, src_len, buf, &buf_len ); + status = decompose_string( compat, src, src_len, buf, &buf_len ); if (status != STATUS_BUFFER_TOO_SMALL) break; RtlFreeHeap( GetProcessHeap(), 0, buf ); } diff --git a/include/wine/unicode.h b/include/wine/unicode.h index c9393062b73..5210b72498a 100644 --- a/include/wine/unicode.h +++ b/include/wine/unicode.h @@ -97,9 +97,6 @@ extern int wine_compare_string( int flags, const WCHAR *str1, int len1, const WC extern int wine_get_sortkey( int flags, const WCHAR *src, int srclen, char *dst, int dstlen ); extern int wine_fold_string( int flags, const WCHAR *src, int srclen , WCHAR *dst, int dstlen ); -#define WINE_DECOMPOSE_COMPAT 1 -#define WINE_DECOMPOSE_REORDER 2 - extern int strcmpiW( const WCHAR *str1, const WCHAR *str2 ); extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n ); extern int memicmpW( const WCHAR *str1, const WCHAR *str2, int n ); diff --git a/libs/port/decompose.c b/libs/port/decompose.c index 092d3cfe293..394328fb5e7 100644 --- a/libs/port/decompose.c +++ b/libs/port/decompose.c @@ -4,7 +4,7 @@ #include "windef.h" -static const WCHAR decomp_table[6061] = +const WCHAR DECLSPEC_HIDDEN nfd_table[6061] = { /* index */ 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0100, 0x0160, 0x0100, @@ -958,7 +958,7 @@ static const WCHAR decomp_table[6061] = 0x05db, 0x05bf, 0x05e4, 0x05bf }; -static const WCHAR compatmap_table[13479] = +const WCHAR DECLSPEC_HIDDEN nfkd_table[13479] = { /* index */ 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0100, @@ -3039,20 +3039,3 @@ static const WCHAR compatmap_table[13479] = 0x00a3, 0x00ac, 0x0020, 0x0304, 0x00a6, 0x00a5, 0x20a9, 0x2502, 0x2190, 0x2191, 0x2192, 0x2193, 0x25a0, 0x25cb }; - -#include "wine/unicode.h" - -unsigned int DECLSPEC_HIDDEN wine_decompose( int flags, WCHAR ch, WCHAR *dst, unsigned int dstlen ) -{ - const WCHAR *table = (flags & WINE_DECOMPOSE_COMPAT) ? compatmap_table : decomp_table; - unsigned short offset = table[table[ch >> 8] + ((ch >> 4) & 0xf)] + (ch & 0xf); - unsigned short start = table[offset]; - unsigned short end = table[offset + 1]; - unsigned int len = end - start; - - *dst = ch; - if (!len) return 1; - if (dstlen < len) return 0; - memcpy( dst, table + start, len * sizeof(WCHAR) ); - return len; -} diff --git a/libs/port/mbtowc.c b/libs/port/mbtowc.c index 471b87be6c0..b6823d0ee85 100644 --- a/libs/port/mbtowc.c +++ b/libs/port/mbtowc.c @@ -22,7 +22,18 @@ #include "wine/unicode.h" -extern unsigned int wine_decompose( int flags, WCHAR ch, WCHAR *dst, unsigned int dstlen ) DECLSPEC_HIDDEN; +extern const unsigned short nfd_table[] DECLSPEC_HIDDEN; + +static const WCHAR *get_decomposition( WCHAR ch, unsigned int *len ) +{ + unsigned short offset = nfd_table[nfd_table[ch >> 8] + ((ch >> 4) & 0xf)] + (ch & 0xf); + unsigned short start = nfd_table[offset]; + unsigned short end = nfd_table[offset + 1]; + + if ((*len = end - start)) return nfd_table + start; + *len = 1; + return NULL; +} /* check the code whether it is in Unicode Private Use Area (PUA). */ /* MB_ERR_INVALID_CHARS raises an error converting from 1-byte character to PUA. */ @@ -119,22 +130,24 @@ static int mbstowcs_sbcs_decompose( const struct sbcs_table *table, int flags, WCHAR *dst, unsigned int dstlen ) { const WCHAR * const cp2uni = (flags & MB_USEGLYPHCHARS) ? table->cp2uni_glyphs : table->cp2uni; - unsigned int len; + const WCHAR *decomp; + unsigned int len, decomp_len; if (!dstlen) /* compute length */ { - WCHAR dummy[4]; /* no decomposition is larger than 4 chars */ - for (len = 0; srclen; srclen--, src++) - len += wine_decompose( 0, cp2uni[*src], dummy, 4 ); + for (len = 0; srclen; srclen--, src++, len += decomp_len) + get_decomposition( cp2uni[*src], &decomp_len ); return len; } - for (len = dstlen; srclen && len; srclen--, src++) + for (len = dstlen; srclen && len; srclen--, src++, dst += decomp_len, len -= decomp_len) { - unsigned int res = wine_decompose( 0, cp2uni[*src], dst, len ); - if (!res) break; - len -= res; - dst += res; + if ((decomp = get_decomposition( cp2uni[*src], &decomp_len ))) + { + if (len < decomp_len) break; + memcpy( dst, decomp, decomp_len * sizeof(WCHAR) ); + } + else *dst = cp2uni[*src]; } if (srclen) return -1; /* overflow */ return dstlen - len; @@ -221,13 +234,13 @@ static int mbstowcs_dbcs_decompose( const struct dbcs_table *table, { const WCHAR * const cp2uni = table->cp2uni; const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes; - unsigned int len, res; + const WCHAR *decomp; + unsigned int len, decomp_len; WCHAR ch; if (!dstlen) /* compute length */ { - WCHAR dummy[4]; /* no decomposition is larger than 4 chars */ - for (len = 0; srclen; srclen--, src++) + for (len = 0; srclen; srclen--, src++, len += decomp_len) { unsigned char off = cp2uni_lb[*src]; if (off && srclen > 1 && src[1]) @@ -237,12 +250,12 @@ static int mbstowcs_dbcs_decompose( const struct dbcs_table *table, ch = cp2uni[(off << 8) + *src]; } else ch = cp2uni[*src]; - len += wine_decompose( 0, ch, dummy, 4 ); + get_decomposition( ch, &decomp_len ); } return len; } - for (len = dstlen; srclen && len; srclen--, src++) + for (len = dstlen; srclen && len; srclen--, src++, dst += decomp_len, len -= decomp_len) { unsigned char off = cp2uni_lb[*src]; if (off && srclen > 1 && src[1]) @@ -252,9 +265,13 @@ static int mbstowcs_dbcs_decompose( const struct dbcs_table *table, ch = cp2uni[(off << 8) + *src]; } else ch = cp2uni[*src]; - if (!(res = wine_decompose( 0, ch, dst, len ))) break; - dst += res; - len -= res; + + if ((decomp = get_decomposition( ch, &decomp_len ))) + { + if (len < decomp_len) break; + memcpy( dst, decomp, decomp_len * sizeof(WCHAR) ); + } + else *dst = ch; } if (srclen) return -1; /* overflow */ return dstlen - len; diff --git a/libs/port/sortkey.c b/libs/port/sortkey.c index 1037133b9ce..090aaf0b19a 100644 --- a/libs/port/sortkey.c +++ b/libs/port/sortkey.c @@ -19,8 +19,19 @@ */ #include "wine/unicode.h" -extern unsigned int wine_decompose( int flags, WCHAR ch, WCHAR *dst, unsigned int dstlen ); extern const unsigned int collation_table[]; +extern const unsigned short nfd_table[] DECLSPEC_HIDDEN; + +static const WCHAR *get_decomposition( WCHAR ch, unsigned int *len ) +{ + unsigned short offset = nfd_table[nfd_table[ch >> 8] + ((ch >> 4) & 0xf)] + (ch & 0xf); + unsigned short start = nfd_table[offset]; + unsigned short end = nfd_table[offset + 1]; + + if ((*len = end - start)) return nfd_table + start; + *len = 1; + return NULL; +} /* * flags - normalization NORM_* flags @@ -180,7 +191,7 @@ static unsigned int get_weight(WCHAR ch, enum weight type) } } -static void inc_str_pos(const WCHAR **str, int *len, int *dpos, int *dlen) +static void inc_str_pos(const WCHAR **str, int *len, unsigned int *dpos, unsigned int *dlen) { (*dpos)++; if (*dpos == *dlen) @@ -194,9 +205,8 @@ static void inc_str_pos(const WCHAR **str, int *len, int *dpos, int *dlen) static inline int compare_weights(int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2, enum weight type) { - int dpos1 = 0, dpos2 = 0, dlen1 = 0, dlen2 = 0; - WCHAR dstr1[4], dstr2[4]; - unsigned int ce1, ce2; + unsigned int ce1, ce2, dpos1 = 0, dpos2 = 0, dlen1 = 0, dlen2 = 0; + const WCHAR *dstr1 = NULL, *dstr2 = NULL; /* 32-bit collation element table format: * unicode weight - high 16 bit, diacritic weight - high 8 bit of low 16 bit, @@ -204,8 +214,8 @@ static inline int compare_weights(int flags, const WCHAR *str1, int len1, */ while (len1 > 0 && len2 > 0) { - if (!dlen1) dlen1 = wine_decompose(0, *str1, dstr1, 4); - if (!dlen2) dlen2 = wine_decompose(0, *str2, dstr2, 4); + if (!dlen1 && !(dstr1 = get_decomposition( *str1, &dlen1 ))) dstr1 = str1; + if (!dlen2 && !(dstr2 = get_decomposition( *str2, &dlen2 ))) dstr2 = str2; if (flags & NORM_IGNORESYMBOLS) { @@ -264,16 +274,14 @@ static inline int compare_weights(int flags, const WCHAR *str1, int len1, } while (len1) { - if (!dlen1) dlen1 = wine_decompose(0, *str1, dstr1, 4); - + if (!dlen1 && !(dstr1 = get_decomposition( *str1, &dlen1 ))) dstr1 = str1; ce1 = get_weight(dstr1[dpos1], type); if (ce1) break; inc_str_pos(&str1, &len1, &dpos1, &dlen1); } while (len2) { - if (!dlen2) dlen2 = wine_decompose(0, *str2, dstr2, 4); - + if (!dlen2 && !(dstr2 = get_decomposition( *str2, &dlen2 ))) dstr2 = str2; ce2 = get_weight(dstr2[dpos2], type); if (ce2) break; inc_str_pos(&str2, &len2, &dpos2, &dlen2); diff --git a/tools/make_unicode b/tools/make_unicode index 8243e42942a..76526ac6966 100755 --- a/tools/make_unicode +++ b/tools/make_unicode @@ -2380,8 +2380,6 @@ sub dump_decompositions($@) { my ($name, @decomp) = @_; - @decomp = build_decompositions( @decomp ); - # first determine all the 16-char subsets that contain something my @filled = (0) x 4096; @@ -2423,7 +2421,7 @@ sub dump_decompositions($@) # dump the main index - printf OUTPUT "static const WCHAR %s[%d] =\n", $name, $total + $data_total; + printf OUTPUT "\nconst WCHAR DECLSPEC_HIDDEN %s[%d] =\n", $name, $total + $data_total; printf OUTPUT "{\n /* index */\n"; printf OUTPUT "%s", dump_array( 16, 0, @filled_idx ); printf OUTPUT ",\n /* null sub-index */\n%s", dump_array( 16, 0, ($null_offset) x 16 ); @@ -2471,7 +2469,7 @@ sub dump_decompositions($@) printf OUTPUT ",\n /* data */\n"; printf OUTPUT "%s", dump_array( 16, 0, @data ); - printf OUTPUT "\n};\n\n"; + printf OUTPUT "\n};\n"; } ################################################################ @@ -2485,50 +2483,11 @@ sub dump_decompose_table($$) print OUTPUT "/* Unicode char composition */\n"; print OUTPUT "/* generated from $UNIDATA/UnicodeData.txt */\n"; print OUTPUT "/* DO NOT EDIT!! */\n\n"; - print OUTPUT "#include \"windef.h\"\n\n"; + print OUTPUT "#include \"windef.h\"\n"; - dump_decompositions( $compat ? "decomp_table" : "table", @decomp_table ); + dump_decompositions( "nfd_table", build_decompositions( @decomp_table )); + dump_decompositions( "nfkd_table", build_decompositions( @decomp_compat_table )) if $compat; - if ($compat) - { - dump_decompositions( "compatmap_table", @decomp_compat_table ); - print OUTPUT <<"EOF"; -#include "wine/unicode.h" - -unsigned int DECLSPEC_HIDDEN wine_decompose( int flags, WCHAR ch, WCHAR *dst, unsigned int dstlen ) -{ - const WCHAR *table = (flags & WINE_DECOMPOSE_COMPAT) ? compatmap_table : decomp_table; - unsigned short offset = table[table[ch >> 8] + ((ch >> 4) & 0xf)] + (ch & 0xf); - unsigned short start = table[offset]; - unsigned short end = table[offset + 1]; - unsigned int len = end - start; - - *dst = ch; - if (!len) return 1; - if (dstlen < len) return 0; - memcpy( dst, table + start, len * sizeof(WCHAR) ); - return len; -} -EOF - } - else - { - print OUTPUT <<"EOF"; -unsigned int DECLSPEC_HIDDEN wine_decompose( int flags, WCHAR ch, WCHAR *dst, unsigned int dstlen ) -{ - unsigned short offset = table[table[ch >> 8] + ((ch >> 4) & 0xf)] + (ch & 0xf); - unsigned short start = table[offset]; - unsigned short end = table[offset + 1]; - unsigned int len = end - start; - - *dst = ch; - if (!len) return 1; - if (dstlen < len) return 0; - memcpy( dst, table + start, len * sizeof(WCHAR) ); - return len; -} -EOF - } close OUTPUT; save_file($filename); }