Commit c97bb4c5 authored by Alexandre Julliard's avatar Alexandre Julliard

Added Unicode ctype support.

parent e5fe735d
......@@ -761,8 +761,7 @@ AC_CHECK_HEADERS(\
sys/vfs.h \
sys/vm86.h \
syscall.h \
ucontext.h \
wctype.h \
ucontext.h
)
AC_HEADER_STAT()
......
......@@ -4,17 +4,8 @@
* Copyright 1999 Alexandre Julliard
*/
#include "config.h"
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_WCTYPE_H
#include <wctype.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "crtdll.h"
......@@ -23,9 +14,8 @@
*/
LPSTR __cdecl CRTDLL__mbsinc( LPCSTR str )
{
int len = mblen( str, MB_LEN_MAX );
if (len < 1) len = 1;
return (LPSTR)(str + len);
if (IsDBCSLeadByte( *str )) str++;
return (LPSTR)(str + 1);
}
......@@ -34,13 +24,9 @@ LPSTR __cdecl CRTDLL__mbsinc( LPCSTR str )
*/
INT __cdecl CRTDLL__mbslen( LPCSTR str )
{
INT len, total = 0;
while ((len = mblen( str, MB_LEN_MAX )) > 0)
{
str += len;
total++;
}
return total;
INT len;
for (len = 0; *str; len++, str++) if (IsDBCSLeadByte(str[0]) && str[1]) str++;
return len;
}
......@@ -49,8 +35,11 @@ INT __cdecl CRTDLL__mbslen( LPCSTR str )
*/
INT __cdecl CRTDLL_mbtowc( WCHAR *dst, LPCSTR str, INT n )
{
wchar_t res;
int ret = mbtowc( &res, str, n );
if (dst) *dst = (WCHAR)res;
return ret;
if (n <= 0) return 0;
if (!str) return 0;
if (!MultiByteToWideChar( CP_ACP, 0, str, n, dst, 1 )) return 0;
/* return the number of bytes from src that have been used */
if (!*str) return 0;
if (n >= 2 && IsDBCSLeadByte(*str) && str[1]) return 2;
return 1;
}
......@@ -11,6 +11,7 @@
#include <string.h>
#include "windef.h"
#include "winnls.h"
#include "wine/unicode.h"
#include "crtdll.h"
#include "debugtools.h"
......@@ -113,17 +114,15 @@ LPWSTR __cdecl CRTDLL_wcspbrk( LPCWSTR str, LPCWSTR accept )
*/
INT __cdecl CRTDLL_wctomb( LPSTR dst, WCHAR ch )
{
return wctomb( dst, (wchar_t)ch );
return WideCharToMultiByte( CP_ACP, 0, ch, 1, dst, 6, NULL, NULL );
}
extern INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct ); /* FIXME */
/*********************************************************************
* CRTDLL_iswalnum (CRTDLL.405)
*/
INT __cdecl CRTDLL_iswalnum( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0107 );
return get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT|C1_LOWER|C1_UPPER);
}
/*********************************************************************
......@@ -131,7 +130,7 @@ INT __cdecl CRTDLL_iswalnum( WCHAR wc )
*/
INT __cdecl CRTDLL_iswalpha( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0103 );
return get_char_typeW(wc) & (C1_ALPHA|C1_LOWER|C1_UPPER);
}
/*********************************************************************
......@@ -139,7 +138,7 @@ INT __cdecl CRTDLL_iswalpha( WCHAR wc )
*/
INT __cdecl CRTDLL_iswcntrl( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0020 );
return get_char_typeW(wc) & C1_CNTRL;
}
/*********************************************************************
......@@ -147,7 +146,7 @@ INT __cdecl CRTDLL_iswcntrl( WCHAR wc )
*/
INT __cdecl CRTDLL_iswdigit( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0004 );
return get_char_typeW(wc) & C1_DIGIT;
}
/*********************************************************************
......@@ -155,7 +154,7 @@ INT __cdecl CRTDLL_iswdigit( WCHAR wc )
*/
INT __cdecl CRTDLL_iswgraph( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0117 );
return get_char_typeW(wc) & (C1_ALPHA|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
}
/*********************************************************************
......@@ -163,7 +162,7 @@ INT __cdecl CRTDLL_iswgraph( WCHAR wc )
*/
INT __cdecl CRTDLL_iswlower( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0002 );
return get_char_typeW(wc) & C1_LOWER;
}
/*********************************************************************
......@@ -171,7 +170,7 @@ INT __cdecl CRTDLL_iswlower( WCHAR wc )
*/
INT __cdecl CRTDLL_iswprint( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0157 );
return get_char_typeW(wc) & (C1_ALPHA|C1_BLANK|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
}
/*********************************************************************
......@@ -179,7 +178,7 @@ INT __cdecl CRTDLL_iswprint( WCHAR wc )
*/
INT __cdecl CRTDLL_iswpunct( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0010 );
return get_char_typeW(wc) & C1_PUNCT;
}
/*********************************************************************
......@@ -187,7 +186,7 @@ INT __cdecl CRTDLL_iswpunct( WCHAR wc )
*/
INT __cdecl CRTDLL_iswspace( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0008 );
return get_char_typeW(wc) & C1_SPACE;
}
/*********************************************************************
......@@ -195,7 +194,7 @@ INT __cdecl CRTDLL_iswspace( WCHAR wc )
*/
INT __cdecl CRTDLL_iswupper( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0001 );
return get_char_typeW(wc) & C1_UPPER;
}
/*********************************************************************
......@@ -203,5 +202,5 @@ INT __cdecl CRTDLL_iswupper( WCHAR wc )
*/
INT __cdecl CRTDLL_iswxdigit( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0080 );
return get_char_typeW(wc) & C1_XDIGIT;
}
......@@ -9,9 +9,6 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_WCTYPE_H
#include <wctype.h>
#endif
#include "windef.h"
#include "winbase.h"
......@@ -296,40 +293,7 @@ INT __cdecl NTDLL_wcstol(LPWSTR s,LPWSTR *end,INT base)
*/
INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct )
{
INT res = 0;
#ifdef HAVE_WCTYPE_H
#undef iswupper
#undef iswlower
#undef iswdigit
#undef iswspace
#undef iswpunct
#undef iswcntrl
#undef iswxdigit
#undef iswalpha
if (wct & 0x0001) res |= iswupper(wc);
if (wct & 0x0002) res |= iswlower(wc);
if (wct & 0x0004) res |= iswdigit(wc);
if (wct & 0x0008) res |= iswspace(wc);
if (wct & 0x0010) res |= iswpunct(wc);
if (wct & 0x0020) res |= iswcntrl(wc);
if (wct & 0x0080) res |= iswxdigit(wc);
if (wct & 0x0100) res |= iswalpha(wc);
#else
if (wct & 0x0001) res |= isupper(LOBYTE(wc));
if (wct & 0x0002) res |= islower(LOBYTE(wc));
if (wct & 0x0004) res |= isdigit(LOBYTE(wc));
if (wct & 0x0008) res |= isspace(LOBYTE(wc));
if (wct & 0x0010) res |= ispunct(LOBYTE(wc));
if (wct & 0x0020) res |= iscntrl(LOBYTE(wc));
if (wct & 0x0080) res |= isxdigit(LOBYTE(wc));
if (wct & 0x0100) res |= isalpha(LOBYTE(wc));
#endif
if (wct & 0x0040)
FIXME(": iswctype(%04hx,_BLANK|...) requested\n",wc);
if (wct & 0x8000)
FIXME(": iswctype(%04hx,_LEADBYTE|...) requested\n",wc);
return res;
return (get_char_typeW(wc) & 0xfff) & wct;
}
......@@ -338,5 +302,5 @@ INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct )
*/
INT __cdecl NTDLL_iswalpha( WCHAR wc )
{
return NTDLL_iswctype( wc, 0x0100 );
return get_char_typeW(wc) & C1_ALPHA;
}
......@@ -320,6 +320,62 @@ BOOL WINAPI OemToCharW( LPCSTR s, LPWSTR d )
/***********************************************************************
* IsCharLowerA (USER.436) (USER32.@)
* FIXME: handle current locale
*/
BOOL WINAPI IsCharLowerA(CHAR x)
{
return islower(x);
}
/***********************************************************************
* IsCharLowerW (USER32.@)
*/
BOOL WINAPI IsCharLowerW(WCHAR x)
{
return get_char_typeW(x) & C1_LOWER;
}
/***********************************************************************
* IsCharUpperA (USER.435) (USER32.337)
* FIXME: handle current locale
*/
BOOL WINAPI IsCharUpperA(CHAR x)
{
return isupper(x);
}
/***********************************************************************
* IsCharUpperW (USER32.@)
*/
BOOL WINAPI IsCharUpperW(WCHAR x)
{
return get_char_typeW(x) & C1_UPPER;
}
/***********************************************************************
* IsCharAlphaNumericW (USER32.@)
*/
BOOL WINAPI IsCharAlphaNumericW(WCHAR x)
{
return get_char_typeW(x) & (C1_ALPHA|C1_DIGIT|C1_LOWER|C1_UPPER);
}
/***********************************************************************
* IsCharAlphaW (USER32.@)
*/
BOOL WINAPI IsCharAlphaW(WCHAR x)
{
return get_char_typeW(x) & (C1_ALPHA|C1_LOWER|C1_UPPER);
}
/***********************************************************************
* FormatMessage16 (USER.606)
*/
DWORD WINAPI FormatMessage16(
......
......@@ -428,9 +428,6 @@
/* Define if you have the <ucontext.h> header file. */
#undef HAVE_UCONTEXT_H
/* Define if you have the <wctype.h> header file. */
#undef HAVE_WCTYPE_H
/* Define if you have the curses library (-lcurses). */
#undef HAVE_LIBCURSES
......
......@@ -1767,11 +1767,10 @@ INT WINAPI GetProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT);
VOID WINAPI GetStartupInfoA(LPSTARTUPINFOA);
VOID WINAPI GetStartupInfoW(LPSTARTUPINFOW);
#define GetStartupInfo WINELIB_NAME_AW(GetStartupInfo)
BOOL WINAPI GetStringTypeA(LCID,DWORD,LPCSTR,INT,LPWORD);
BOOL WINAPI GetStringTypeW(DWORD,LPCWSTR,INT,LPWORD);
#define GetStringType WINELIB_NAME_AW(GetStringType)
UINT WINAPI GetSystemDirectoryA(LPSTR,UINT);
UINT WINAPI GetSystemDirectoryW(LPWSTR,UINT);
BOOL WINAPI GetStringTypeA(LCID,DWORD,LPCSTR,INT,LPWORD);
BOOL WINAPI GetStringTypeW(DWORD,LPCWSTR,INT,LPWORD);
UINT WINAPI GetSystemDirectoryA(LPSTR,UINT);
UINT WINAPI GetSystemDirectoryW(LPWSTR,UINT);
#define GetSystemDirectory WINELIB_NAME_AW(GetSystemDirectory)
DWORD WINAPI GetTickCount(void);
UINT WINAPI GetTempFileNameA(LPCSTR,LPCSTR,UINT,LPSTR);
......
......@@ -73,6 +73,14 @@ static inline WCHAR toupperW( WCHAR ch )
return ch + casemap_upper[casemap_upper[ch >> 8] + (ch & 0xff)];
}
/* the character type contains the C1_* flags in the low 12 bits */
/* and the C2_* type in the high 4 bits */
static inline unsigned short get_char_typeW( WCHAR ch )
{
extern unsigned short wctype_table[];
return wctype_table[wctype_table[ch >> 8] + (ch & 0xff)];
}
/* some useful string manipulation routines */
static inline unsigned int strlenW( const WCHAR *str )
......
......@@ -360,3 +360,38 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
}
return ret;
}
/******************************************************************************
* GetStringTypeW (KERNEL32)
*
*/
BOOL WINAPI GetStringTypeW( DWORD type, LPCWSTR src, INT count, LPWORD chartype )
{
if (count == -1) count = strlenW(src) + 1;
switch(type)
{
case CT_CTYPE1:
while (count--) *chartype++ = get_char_typeW( *src++ ) & 0xfff;
break;
case CT_CTYPE2:
while (count--) *chartype++ = get_char_typeW( *src++ ) >> 12;
break;
case CT_CTYPE3:
FIXME("CT_CTYPE3 not supported.\n");
default:
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
return TRUE;
}
/******************************************************************************
* GetStringTypeExW (KERNEL32)
*/
BOOL WINAPI GetStringTypeExW( LCID locale, DWORD type, LPCWSTR src, INT count, LPWORD chartype )
{
/* locale is ignored for Unicode */
return GetStringTypeW( type, src, count, chartype );
}
......@@ -13,15 +13,6 @@
#include <string.h>
#include <ctype.h>
#ifdef HAVE_WCTYPE_H
# include <wctype.h>
#else
# define iswalnum(c) isalnum(c)
# define iswalpha(c) isalpha(c)
# define iswupper(c) isupper(c)
# define iswlower(c) islower(c)
#endif /* HAVE_WCTYPE_H */
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
......@@ -192,57 +183,3 @@ BOOL WINAPI IsCharAlphaNumericA(CHAR x)
{
return IsCharAlphaA(x) || isdigit(x) ;
}
/***********************************************************************
* IsCharAlphaNumericW (USER32.333)
* FIXME: handle current locale
*/
BOOL WINAPI IsCharAlphaNumericW(WCHAR x)
{
return iswalnum(x);
}
/***********************************************************************
* IsCharAlphaW (USER32.334)
* FIXME: handle current locale
*/
BOOL WINAPI IsCharAlphaW(WCHAR x)
{
return iswalpha(x);
}
/***********************************************************************
* IsCharLowerA (USER.436) (USER32.335)
* FIXME: handle current locale
*/
BOOL WINAPI IsCharLowerA(CHAR x)
{
return islower(x);
}
/***********************************************************************
* IsCharLowerW (USER32.336)
* FIXME: handle current locale
*/
BOOL WINAPI IsCharLowerW(WCHAR x)
{
return iswlower(x);
}
/***********************************************************************
* IsCharUpperA (USER.435) (USER32.337)
* FIXME: handle current locale
*/
BOOL WINAPI IsCharUpperA(CHAR x)
{
return isupper(x);
}
/***********************************************************************
* IsCharUpperW (USER32.338)
* FIXME: handle current locale
*/
BOOL WINAPI IsCharUpperW(WCHAR x)
{
return iswupper(x);
}
......@@ -1223,60 +1223,6 @@ BOOL WINAPI GetStringTypeExA(LCID locale,DWORD dwInfoType,LPCSTR src,
}
}
/******************************************************************************
* GetStringTypeW [KERNEL32.399]
*
* NOTES
* Yes, this is missing LCID locale. MS fault.
*/
BOOL WINAPI GetStringTypeW(DWORD dwInfoType,LPCWSTR src,INT cchSrc,
LPWORD chartype)
{
return GetStringTypeExW(0/*defaultlocale*/,dwInfoType,src,cchSrc,chartype);
}
/******************************************************************************
* GetStringTypeExW [KERNEL32.398]
*
* FIXME: unicode chars are assumed chars
*/
BOOL WINAPI GetStringTypeExW(LCID locale,DWORD dwInfoType,LPCWSTR src,
INT cchSrc,LPWORD chartype)
{
int i;
UINT ch;
if (cchSrc==-1)
cchSrc=lstrlenW(src)+1;
switch (dwInfoType) {
case CT_CTYPE2:
FIXME("CT_CTYPE2 not supported.\n");
return FALSE;
case CT_CTYPE3:
FIXME("CT_CTYPE3 not supported.\n");
return FALSE;
default:break;
}
for (i=0;i<cchSrc;i++) {
chartype[i] = 0;
ch = src[i];
if ( ch >= (UINT)0x100 ) continue;
if (isdigit(ch)) chartype[i]|=C1_DIGIT;
if (isalpha(ch)) chartype[i]|=C1_ALPHA;
if (islower(ch)) chartype[i]|=C1_LOWER;
if (isupper(ch)) chartype[i]|=C1_UPPER;
if (isspace(ch)) chartype[i]|=C1_SPACE;
if (ispunct(ch)) chartype[i]|=C1_PUNCT;
if (iscntrl(ch)) chartype[i]|=C1_CNTRL;
/* FIXME: isblank() is a GNU extension */
/* if (isblank(ch)) chartype[i]|=C1_BLANK; */
if ((ch == ' ') || (ch == '\t')) chartype[i]|=C1_BLANK;
/* C1_XDIGIT */
}
return TRUE;
}
/***********************************************************************
* VerLanguageNameA [KERNEL32.709][VERSION.9]
*/
......
......@@ -72,6 +72,7 @@ C_SRCS = \
string.c \
utf8.c \
wctomb.c \
wctype.c \
$(CODEPAGES:%=c_%.c)
all: libwine_unicode.$(LIBEXT)
......
......@@ -76,11 +76,93 @@ $DEF_CHAR = ord '?';
[ 28599, "ISO8859/8859-9.TXT", "ISO 8859-9 Latin 5" ]
);
%ctype =
(
"upper" => 0x0001,
"lower" => 0x0002,
"digit" => 0x0004,
"space" => 0x0008,
"punct" => 0x0010,
"cntrl" => 0x0020,
"blank" => 0x0040,
"xdigit" => 0x0080,
"alpha" => 0x0100
);
%categories =
(
"Lu" => $ctype{"alpha"}|$ctype{"upper"}, # Letter, Uppercase
"Ll" => $ctype{"alpha"}|$ctype{"lower"}, # Letter, Lowercase
"Lt" => $ctype{"alpha"}, # Letter, Titlecase
"Mn" => $ctype{"punct"}, # Mark, Non-Spacing
"Mc" => $ctype{"punct"}, # Mark, Spacing Combining
"Me" => $ctype{"punct"}, # Mark, Enclosing
"Nd" => $ctype{"digit"}, # Number, Decimal Digit
"Nl" => $ctype{"punct"}, # Number, Letter
"No" => $ctype{"punct"}, # Number, Other
"Zs" => $ctype{"space"}, # Separator, Space
"Zl" => 0, # Separator, Line
"Zp" => 0, # Separator, Paragraph
"Cc" => $ctype{"cntrl"}, # Other, Control
"Cf" => 0, # Other, Format
"Cs" => 0, # Other, Surrogate
"Co" => 0, # Other, Private Use
"Cn" => 0, # Other, Not Assigned
"Lm" => $ctype{"punct"}, # Letter, Modifier
"Lo" => $ctype{"alpha"}, # Letter, Other
"Pc" => $ctype{"punct"}, # Punctuation, Connector
"Pd" => $ctype{"punct"}, # Punctuation, Dash
"Ps" => $ctype{"punct"}, # Punctuation, Open
"Pe" => $ctype{"punct"}, # Punctuation, Close
"Pi" => $ctype{"punct"}, # Punctuation, Initial quote
"Pf" => $ctype{"punct"}, # Punctuation, Final quote
"Po" => $ctype{"punct"}, # Punctuation, Other
"Sm" => $ctype{"punct"}, # Symbol, Math
"Sc" => $ctype{"punct"}, # Symbol, Currency
"Sk" => $ctype{"punct"}, # Symbol, Modifier
"So" => $ctype{"punct"} # Symbol, Other
);
# a few characters need additional categories that cannot be determined automatically
%special_categories =
(
"xdigit" => [ ord('0')..ord('9'),ord('A')..ord('F'),ord('a')..ord('f'),
0xff10..0xff19, 0xff21..0xff26, 0xff41..0xff46 ],
"space" => [ 0x09..0x0d, 0xfeff ],
"blank" => [ 0x09, 0x20, 0xa0, 0xfeff ]
);
%directions =
(
"L" => 1, # Left-to-Right
"LRE" => 11, # Left-to-Right Embedding
"LRO" => 11, # Left-to-Right Override
"R" => 2, # Right-to-Left
"AL" => 2, # Right-to-Left Arabic
"RLE" => 11, # Right-to-Left Embedding
"RLO" => 11, # Right-to-Left Override
"PDF" => 11, # Pop Directional Format
"EN" => 3, # European Number
"ES" => 4, # European Number Separator
"ET" => 5, # European Number Terminator
"AN" => 6, # Arabic Number
"CS" => 7, # Common Number Separator
"NSM" => 0, # Non-Spacing Mark
"BN" => 0, # Boundary Neutral
"B" => 8, # Paragraph Separator
"S" => 9, # Segment Separator
"WS" => 10, # Whitespace
"ON" => 11 # Other Neutrals
);
################################################################
# main routine
READ_DEFAULTS();
DUMP_CASE_MAPPINGS();
DUMP_CTYPE_TABLES();
foreach $file (@allfiles) { HANDLE_FILE( @$file ); }
......@@ -97,6 +179,8 @@ sub READ_DEFAULTS
@unicode_aliases = ();
@tolower_table = ();
@toupper_table = ();
@category_table = ();
@direction_table = ();
# first setup a few default mappings
......@@ -135,12 +219,43 @@ sub READ_DEFAULTS
$decomp, $dec, $dig, $num, $mirror,
$oldname, $comment, $upper, $lower, $title) = split /;/;
if ($lower ne "") { $tolower_table[hex $code] = hex $lower; }
if ($upper ne "") { $toupper_table[hex $code] = hex $upper; }
my $src = hex $code;
next if $decomp eq ""; # no decomposition, skip it
die "unknown category $cat" unless defined $categories{$cat};
die "unknown directionality $bidi" unless defined $directions{$bidi};
$uniname[$src] = $name;
$category_table[$src] = $categories{$cat};
$direction_table[$src] = $directions{$bidi};
if ($lower ne "")
{
$tolower_table[$src] = hex $lower;
$category_table[$src] |= $ctype{"upper"}|$ctype{"alpha"};
}
if ($upper ne "")
{
$toupper_table[$src] = hex $upper;
$category_table[$src] |= $ctype{"lower"}|$ctype{"alpha"};
}
if ($dec ne "")
{
$category_table[$src] |= $ctype{"digit"};
}
$src = hex $code;
# copy the category and direction for everything between First/Last pairs
if ($name =~ /, First>/) { $start = $src; }
if ($name =~ /, Last>/)
{
while ($start < $src)
{
$category_table[$start] = $category_table[$src];
$direction_table[$start] = $direction_table[$src];
$start++;
}
}
next if $decomp eq ""; # no decomposition, skip it
if ($decomp =~ /^<([a-zA-Z]+)>\s+([0-9a-fA-F]+)$/)
{
......@@ -165,6 +280,7 @@ sub READ_DEFAULTS
{
# decomposition contains only char values without prefix -> use first char
$dst = hex $1;
$category_table[$src] |= $category_table[$dst];
}
else
{
......@@ -181,6 +297,14 @@ sub READ_DEFAULTS
}
$unicode_defaults[$src] = $dst;
}
# patch the category of some special characters
foreach $cat (keys %special_categories)
{
my $flag = $ctype{$cat};
foreach $i (@{$special_categories{$cat}}) { $category_table[$i] |= $flag; }
}
}
......@@ -567,6 +691,49 @@ sub DUMP_CASE_TABLE
################################################################
# dump the ctype tables
sub DUMP_CTYPE_TABLES
{
open OUTPUT,">wctype.c" or die "Cannot create casemap.c";
printf "Building wctype.c\n";
printf OUTPUT "/* Unicode ctype tables */\n";
printf OUTPUT "/* Automatically generated; DO NOT EDIT!! */\n\n";
printf OUTPUT "#include \"wine/unicode.h\"\n\n";
my $i;
my @array = (0) x 256;
# add the direction in the high 4 bits of the category
for ($i = 0; $i < 65536; $i++)
{
$category_table[$i] |= $direction_table[$i] << 12;
}
# try to merge table rows
for ($row = 0; $row < 256; $row++)
{
my $rowtxt = sprintf "%04x" x 256, @category_table[($row<<8)..($row<<8)+255];
if (defined($sequences{$rowtxt}))
{
# reuse an existing row
$array[$row] = $sequences{$rowtxt};
}
else
{
# create a new row
$sequences{$rowtxt} = $array[$row] = $#array + 1;
push @array, @category_table[($row<<8)..($row<<8)+255];
}
}
printf OUTPUT "const unsigned short wctype_table[%d] =\n{\n", $#array+1;
printf OUTPUT " /* offsets */\n%s,\n", DUMP_ARRAY( "0x%04x", 0, @array[0..255] );
printf OUTPUT " /* values */\n%s\n};\n", DUMP_ARRAY( "0x%04x", 0, @array[256..$#array] );
close OUTPUT;
}
################################################################
# read an input file and generate the corresponding .c file
sub HANDLE_FILE
{
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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