Commit 85d42816 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Implement LCMapString using unicode collation tables.

Move CompareString and LCMapString to dlls/kernel/locale.c.
parent 4cb21206
...@@ -16344,8 +16344,6 @@ esac ...@@ -16344,8 +16344,6 @@ esac
ac_config_commands="$ac_config_commands objects" ac_config_commands="$ac_config_commands objects"
ac_config_commands="$ac_config_commands ole"
ac_config_commands="$ac_config_commands programs/regapi/tests" ac_config_commands="$ac_config_commands programs/regapi/tests"
ac_config_commands="$ac_config_commands programs/regedit/tests" ac_config_commands="$ac_config_commands programs/regedit/tests"
...@@ -17118,7 +17116,6 @@ do ...@@ -17118,7 +17116,6 @@ do
"misc" ) CONFIG_COMMANDS="$CONFIG_COMMANDS misc" ;; "misc" ) CONFIG_COMMANDS="$CONFIG_COMMANDS misc" ;;
"msdos" ) CONFIG_COMMANDS="$CONFIG_COMMANDS msdos" ;; "msdos" ) CONFIG_COMMANDS="$CONFIG_COMMANDS msdos" ;;
"objects" ) CONFIG_COMMANDS="$CONFIG_COMMANDS objects" ;; "objects" ) CONFIG_COMMANDS="$CONFIG_COMMANDS objects" ;;
"ole" ) CONFIG_COMMANDS="$CONFIG_COMMANDS ole" ;;
"programs/regapi/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS programs/regapi/tests" ;; "programs/regapi/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS programs/regapi/tests" ;;
"programs/regedit/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS programs/regedit/tests" ;; "programs/regedit/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS programs/regedit/tests" ;;
"relay32" ) CONFIG_COMMANDS="$CONFIG_COMMANDS relay32" ;; "relay32" ) CONFIG_COMMANDS="$CONFIG_COMMANDS relay32" ;;
...@@ -17857,8 +17854,6 @@ echo "$as_me: creating misc" >&6;} && mkdir "misc") ;; ...@@ -17857,8 +17854,6 @@ echo "$as_me: creating misc" >&6;} && mkdir "misc") ;;
echo "$as_me: creating msdos" >&6;} && mkdir "msdos") ;; echo "$as_me: creating msdos" >&6;} && mkdir "msdos") ;;
objects ) test -d "objects" || ({ echo "$as_me:$LINENO: creating objects" >&5 objects ) test -d "objects" || ({ echo "$as_me:$LINENO: creating objects" >&5
echo "$as_me: creating objects" >&6;} && mkdir "objects") ;; echo "$as_me: creating objects" >&6;} && mkdir "objects") ;;
ole ) test -d "ole" || ({ echo "$as_me:$LINENO: creating ole" >&5
echo "$as_me: creating ole" >&6;} && mkdir "ole") ;;
programs/regapi/tests ) test -d "programs/regapi/tests" || ({ echo "$as_me:$LINENO: creating programs/regapi/tests" >&5 programs/regapi/tests ) test -d "programs/regapi/tests" || ({ echo "$as_me:$LINENO: creating programs/regapi/tests" >&5
echo "$as_me: creating programs/regapi/tests" >&6;} && mkdir "programs/regapi/tests") ;; echo "$as_me: creating programs/regapi/tests" >&6;} && mkdir "programs/regapi/tests") ;;
programs/regedit/tests ) test -d "programs/regedit/tests" || ({ echo "$as_me:$LINENO: creating programs/regedit/tests" >&5 programs/regedit/tests ) test -d "programs/regedit/tests" || ({ echo "$as_me:$LINENO: creating programs/regedit/tests" >&5
......
...@@ -1351,7 +1351,6 @@ WINE_CONFIG_EXTRA_DIR(memory) ...@@ -1351,7 +1351,6 @@ WINE_CONFIG_EXTRA_DIR(memory)
WINE_CONFIG_EXTRA_DIR(misc) WINE_CONFIG_EXTRA_DIR(misc)
WINE_CONFIG_EXTRA_DIR(msdos) WINE_CONFIG_EXTRA_DIR(msdos)
WINE_CONFIG_EXTRA_DIR(objects) WINE_CONFIG_EXTRA_DIR(objects)
WINE_CONFIG_EXTRA_DIR(ole)
WINE_CONFIG_EXTRA_DIR(programs/regapi/tests) WINE_CONFIG_EXTRA_DIR(programs/regapi/tests)
WINE_CONFIG_EXTRA_DIR(programs/regedit/tests) WINE_CONFIG_EXTRA_DIR(programs/regedit/tests)
WINE_CONFIG_EXTRA_DIR(relay32) WINE_CONFIG_EXTRA_DIR(relay32)
......
...@@ -20,7 +20,6 @@ SPEC_SRCS16 = \ ...@@ -20,7 +20,6 @@ SPEC_SRCS16 = \
windebug.spec windebug.spec
C_SRCS = \ C_SRCS = \
$(TOPOBJDIR)/ole/ole2nls.c \
atom.c \ atom.c \
change.c \ change.c \
comm.c \ comm.c \
...@@ -65,7 +64,7 @@ MC_SRCS = \ ...@@ -65,7 +64,7 @@ MC_SRCS = \
messages/winerr_enu.mc messages/winerr_enu.mc
SUBDIRS = tests SUBDIRS = tests
EXTRASUBDIRS = messages nls $(TOPOBJDIR)/ole EXTRASUBDIRS = messages nls
@MAKE_DLL_RULES@ @MAKE_DLL_RULES@
......
...@@ -100,6 +100,7 @@ static inline void release( void *ptr ) ...@@ -100,6 +100,7 @@ static inline void release( void *ptr )
/* put an ASCII string into the debug buffer */ /* put an ASCII string into the debug buffer */
inline static char *put_string_a( const char *src, int n ) inline static char *put_string_a( const char *src, int n )
{ {
static const char hex[16] = "0123456789abcdef";
char *dst, *res; char *dst, *res;
if (n == -1) n = strlen(src); if (n == -1) n = strlen(src);
...@@ -123,9 +124,9 @@ inline static char *put_string_a( const char *src, int n ) ...@@ -123,9 +124,9 @@ inline static char *put_string_a( const char *src, int n )
else else
{ {
*dst++ = '\\'; *dst++ = '\\';
*dst++ = '0' + ((c >> 6) & 7); *dst++ = 'x';
*dst++ = '0' + ((c >> 3) & 7); *dst++ = hex[(c >> 4) & 0x0f];
*dst++ = '0' + ((c >> 0) & 7); *dst++ = hex[c & 0x0f];
} }
} }
} }
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#ifndef __WINE_UNICODE_H #ifndef __WINE_UNICODE_H
#define __WINE_UNICODE_H #define __WINE_UNICODE_H
#include <stdarg.h>
#include "windef.h" #include "windef.h"
#include "winnls.h" #include "winnls.h"
...@@ -71,6 +73,8 @@ extern int wine_cp_wcstombs( const union cptable *table, int flags, ...@@ -71,6 +73,8 @@ extern int wine_cp_wcstombs( const union cptable *table, int flags,
extern int wine_utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen ); extern int wine_utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
extern int wine_utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen ); extern int wine_utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen );
extern int wine_get_sortkey( int flags, const WCHAR *src, int srclen, char *dst, int dstlen );
extern int strcmpiW( const WCHAR *str1, const WCHAR *str2 ); extern int strcmpiW( const WCHAR *str1, const WCHAR *str2 );
extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n ); extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n );
extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub ); extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
......
...@@ -196,6 +196,10 @@ extern "C" { ...@@ -196,6 +196,10 @@ extern "C" {
#define LCMAP_HALFWIDTH 0x00400000 /* map double byte to single byte */ #define LCMAP_HALFWIDTH 0x00400000 /* map double byte to single byte */
#define LCMAP_FULLWIDTH 0x00800000 /* map single byte to double byte */ #define LCMAP_FULLWIDTH 0x00800000 /* map single byte to double byte */
#define LCMAP_LINGUISTIC_CASING 0x01000000 /* use linguistic rules for casing */
#define LCMAP_SIMPLIFIED_CHINESE 0x02000000 /* map traditional chinese to simplified chinese */
#define LCMAP_TRADITIONAL_CHINESE 0x04000000 /* map simplified chinese to traditional chinese */
/* Date Flags for GetDateFormat. */ /* Date Flags for GetDateFormat. */
#define DATE_SHORTDATE 0x00000001 /* use short date picture */ #define DATE_SHORTDATE 0x00000001 /* use short date picture */
......
...@@ -70,9 +70,11 @@ CODEPAGES = \ ...@@ -70,9 +70,11 @@ CODEPAGES = \
C_SRCS = \ C_SRCS = \
casemap.c \ casemap.c \
collation.c \
compose.c \ compose.c \
cptable.c \ cptable.c \
mbtowc.c \ mbtowc.c \
sortkey.c \
string.c \ string.c \
utf8.c \ utf8.c \
wctomb.c \ wctomb.c \
......
...@@ -20,11 +20,10 @@ ...@@ -20,11 +20,10 @@
#include <string.h> #include <string.h>
#include "winnls.h"
#include "wine/unicode.h" #include "wine/unicode.h"
/* get the decomposition of a Unicode char */ /* get the decomposition of a Unicode char */
static int get_decomposition( WCHAR src, WCHAR *dst, unsigned int dstlen ) int get_decomposition( WCHAR src, WCHAR *dst, unsigned int dstlen )
{ {
extern const WCHAR unicode_decompose_table[]; extern const WCHAR unicode_decompose_table[];
const WCHAR *ptr = unicode_decompose_table; const WCHAR *ptr = unicode_decompose_table;
......
/*
* Unicode sort key generation
*
* Copyright 2003 Dmitry Timoshkov
*
* 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
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "wine/unicode.h"
extern int get_decomposition(WCHAR src, WCHAR *dst, unsigned int dstlen);
/*
* flags - normalization NORM_* flags
*
* FIXME: 'variable' flag not handled
*/
int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dstlen)
{
extern const unsigned int collation_table[];
WCHAR dummy[4]; /* no decomposition is larger than 4 chars */
int key_len[4];
char *key_ptr[4];
const WCHAR *src_save = src;
int srclen_save = srclen;
key_len[0] = key_len[1] = key_len[2] = key_len[3] = 0;
for (; srclen; srclen--, src++)
{
int decomposed_len = get_decomposition(*src, dummy, 4);
if (decomposed_len)
{
int i;
for (i = 0; i < decomposed_len; i++)
{
WCHAR wch = dummy[i];
unsigned int ce;
/* tests show that win2k just ignores NORM_IGNORENONSPACE,
* and skips white space and punctuation characters for
* NORM_IGNORESYMBOLS.
*/
if ((flags & NORM_IGNORESYMBOLS) && (get_char_typeW(wch) & (C1_PUNCT | C1_SPACE)))
continue;
if (flags & NORM_IGNORECASE) wch = tolowerW(wch);
ce = collation_table[collation_table[wch >> 8] + (wch & 0xff)];
if (ce != (unsigned int)-1)
{
if (ce >> 16) key_len[0] += 2;
if ((ce >> 8) & 0xff) key_len[1]++;
if ((ce >> 4) & 0x0f) key_len[2]++;
/*if (ce & 1)
{
if (wch >> 8) key_len[3]++;
key_len[3]++;
}*/
}
/*else
{
key_len[0] += 2;
if (wch >> 8) key_len[0]++;
if (wch & 0xff) key_len[0]++;
}*/
}
}
}
if (!dstlen) /* compute length */
/* 4 * '\1' + 1 * '\0' + key length */
return key_len[0] + key_len[1] + key_len[2] + key_len[3] + 4 + 1;
if (dstlen < key_len[0] + key_len[1] + key_len[2] + key_len[3] + 4 + 1)
return 0; /* overflow */
src = src_save;
srclen = srclen_save;
key_ptr[0] = dst;
key_ptr[1] = key_ptr[0] + key_len[0] + 1;
key_ptr[2] = key_ptr[1] + key_len[1] + 1;
key_ptr[3] = key_ptr[2] + key_len[2] + 1;
for (; srclen; srclen--, src++)
{
int decomposed_len = get_decomposition(*src, dummy, 4);
if (decomposed_len)
{
int i;
for (i = 0; i < decomposed_len; i++)
{
WCHAR wch = dummy[i];
unsigned int ce;
/* tests show that win2k just ignores NORM_IGNORENONSPACE,
* and skips white space and punctuation characters for
* NORM_IGNORESYMBOLS.
*/
if ((flags & NORM_IGNORESYMBOLS) && (get_char_typeW(wch) & (C1_PUNCT | C1_SPACE)))
continue;
if (flags & NORM_IGNORECASE) wch = tolowerW(wch);
ce = collation_table[collation_table[wch >> 8] + (wch & 0xff)];
if (ce != (unsigned int)-1)
{
WCHAR key;
if ((key = ce >> 16))
{
*key_ptr[0]++ = key >> 8;
*key_ptr[0]++ = key & 0xff;
}
/* make key 1 start from 2 */
if ((key = (ce >> 8) & 0xff)) *key_ptr[1]++ = key + 1;
/* make key 2 start from 2 */
if ((key = (ce >> 4) & 0x0f)) *key_ptr[2]++ = key + 1;
/* key 3 is always a character code */
/*if (ce & 1)
{
if (wch >> 8) *key_ptr[3]++ = wch >> 8;
if (wch & 0xff) *key_ptr[3]++ = wch & 0xff;
}*/
}
/*else
{
*key_ptr[0]++ = 0xff;
*key_ptr[0]++ = 0xfe;
if (wch >> 8) *key_ptr[0]++ = wch >> 8;
if (wch & 0xff) *key_ptr[0]++ = wch & 0xff;
}*/
}
}
}
*key_ptr[0] = '\1';
*key_ptr[1] = '\1';
*key_ptr[2] = '\1';
*key_ptr[3]++ = '\1';
*key_ptr[3] = 0;
return key_ptr[3] - dst;
}
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <string.h> #include <string.h>
#include "winnls.h"
#include "wine/unicode.h" #include "wine/unicode.h"
/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */ /* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <string.h> #include <string.h>
#include "winnls.h"
#include "wine/unicode.h" #include "wine/unicode.h"
/* search for a character in the unicode_compose_table; helper for compose() */ /* search for a character in the unicode_compose_table; helper for compose() */
......
...@@ -16,6 +16,7 @@ EXPORTS ...@@ -16,6 +16,7 @@ EXPORTS
wine_cp_get_table wine_cp_get_table
wine_cp_mbstowcs wine_cp_mbstowcs
wine_cp_wcstombs wine_cp_wcstombs
wine_get_sortkey
wine_utf8_mbstowcs wine_utf8_mbstowcs
wine_utf8_wcstombs wine_utf8_wcstombs
wine_wctype_table wine_wctype_table
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