:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / kernel32 / nls / locale.c
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3                     Addition copyrights might be specified in LGPL.c
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/nls/locale.c
6  * PURPOSE:         National language support functions
7  * PROGRAMMER:      Boudewijn ( ariadne@xs4all.nl)
8  * UPDATE HISTORY:  Modified from Onno Hovers wfc. ( 08/02/99 )
9                     Modified from wine. ( 08/02/99 )
10  *                  
11  */
12
13 /*
14  * nls/locale.c
15  *
16  */
17 /*
18  *      OLE2NLS library
19  *
20  *      Copyright 1995  Martin von Loewis
21  *      Copyright 1998  David Lee Lambert
22  */
23 #undef WIN32_LEAN_AND_MEAN
24 #include<stdlib.h>
25 #include<string.h>
26 #include<windows.h>
27 #include <wchar.h>
28
29 #include <kernel32/thread.h>
30 #include <kernel32/nls.h>
31
32 #undef tolower
33 #undef toupper
34 #undef isupper
35 #undef islower
36 #undef isalnum
37 #undef isalpha
38 #undef isblank
39 #undef isdigit
40
41 #undef towlower
42 #undef towupper
43 #undef iswupper
44 #undef iswlower
45 #undef iswalnum
46 #undef iswalpha
47
48 #define tolower(c)      ((c >= 'A' && c <= 'Z')   ? c - ( 'A' - 'a' ) : c)
49 #define toupper(c)      ((c >= 'a' && c <= 'z')   ? c + 'A' - 'a' : c);
50 #define isupper(c)      (c >= 'A' && c <= 'Z' )
51 #define islower(c)      (c >= 'a' && c <= 'z')
52 #define isalnum(c)      ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')  || (c >= '0' && c <= '9'))
53 #define isalpha(c)      (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
54 #define isblank(c)      ( c == ' ' || c == '\t' )
55 #define isdigit(c)      ((c >= '0' && c <= '9'))
56 #define isspace(c)      ((c == ' '))
57 #define ispunct(c)      ((c == '.'))
58 #define isxdigit(c)     ((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')  || (c >= '0' && c <= '9'))
59 #define iscntrl(c)      ((c >=0x00 && c <= 0x1f) || c == 0x7f)
60
61
62 #define towlower(c)     ((c >= L'A' && c <= L'Z')   ? c - ( L'A' - L'a' ) : c)
63 #define towupper(c)     ((c >= L'a' && c <= L'z')   ? c + L'A' - L'a' : c);
64 #define iswupper(c)     (c >= L'A' && c <= L'Z' )
65 #define iswlower(c)     (c >= L'a' && c <= L'z')
66 #define iswalnum(c)     ((c >= L'A' && c <= L'Z') || (c >= L'a' && c <= L'z')  || (c >= L'0' && c <= L'9'))
67 #define iswalpha(c)     (c >= L'A' && c <= L'Z') || (c >= L'a' && c <= L'z')
68
69 /*
70
71 int OLE_GetFormatA(LCID locale,
72                             DWORD flags,
73                             DWORD tflags,
74                             LPSYSTEMTIME xtime,
75                             LPCSTR _format,     
76                             LPSTR date,         
77                             int datelen);
78 */
79
80 #undef LCID
81
82 #define SYSTEM_DEFAULT_LANGUAGE         LANG_ENGLISH
83 #define SYSTEM_DEFAULT_SUBLANGUAGE      SUBLANG_ENGLISH_US
84 #define SYSTEM_DEFAULT_SORTORDER        SORT_DEFAULT
85
86
87 PLOCALE __UserLocale;
88 PLOCALE __TebLocale;
89 LOCALE  __Locale[LOCALE_ARRAY];
90
91 WINBOOL __LocaleInit(void)
92 {
93    PSTR         locstr;   
94    LCID         lcid;
95    PLOCALE      plocale=NULL;
96    
97    locstr=getenv("WF_LOCALE");
98    if(locstr)
99    {  
100       plocale=__Locale;
101       while((plocale->Id)&&(strcasecmp(locstr,plocale->AbbrName)))
102          plocale++;
103    }
104    /* if we do not have a locale, default */
105    if(!plocale)
106    {
107       lcid=MAKELCID(MAKELANGID(SYSTEM_DEFAULT_LANGUAGE,
108                                SYSTEM_DEFAULT_SUBLANGUAGE),
109                       SYSTEM_DEFAULT_SORTORDER);
110       plocale=__Locale;
111       while((plocale->Id)&&(lcid!=plocale->Id))
112          plocale++;                                                   
113    }
114    /* if this does not work, use our disaster plan */
115    if(!plocale)
116       plocale=__Locale;
117
118    __UserLocale=plocale;
119    __TebLocale=plocale;
120    return TRUE;
121 }
122
123 LANGID STDCALL GetUserDefaultLangID(void)
124 {
125    return LANGIDFROMLCID(__UserLocale->Id);
126 }
127
128 LCID
129 STDCALL
130 GetUserDefaultLCID(void)
131 {
132    return __UserLocale->Id;
133 }
134
135 LANGID STDCALL GetSystemDefaultLangID(void)
136 {
137    return MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US);
138 }
139
140 LCID STDCALL GetSystemDefaultLCID(void)
141 {
142    return MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), 
143                    SORT_DEFAULT);
144 }
145
146 LCID STDCALL GetThreadLocale(void)
147 {
148    return __TebLocale;
149 }
150
151 WINBOOL STDCALL SetThreadLocale(LCID  Locale)
152 {
153    PLOCALE plocale;
154
155    plocale=__Locale;   
156    /* find locale */
157    while((plocale->Id)&&(Locale!=plocale->Id))
158       plocale++;      
159    if(!plocale) {
160         SetLastError(ERROR_INVALID_PARAMETER);
161         return FALSE;
162    }
163    __TebLocale=plocale;
164    return TRUE;   
165 }
166
167 WINBOOL
168 STDCALL
169 IsValidLocale(
170     LCID   Locale,
171     DWORD  dwFlags)
172 {
173    PLOCALE plocale;
174
175    plocale=__Locale;   
176    
177    /* find locale */
178    while((plocale->Id)&&(Locale!=plocale->Id))
179       plocale++;     
180    /* is it valid ?? */    
181    if(!plocale)
182       return FALSE;
183    else
184       return TRUE;   
185 }
186
187 LPSTR static __xtoa(LPSTR str, DWORD val)
188 {
189    LPSTR retstr=str;
190    DWORD hex;
191    
192    do
193    {
194       hex=val%16;
195       if(hex<10)
196          *str=val + '0';
197       else
198          *str=val + 'A';
199       val=val/16;
200       str++;
201    }
202    while(val);
203    return retstr;
204 }
205
206 LPWSTR static __xtow(LPWSTR str, DWORD val)
207 {
208    LPWSTR retstr=str;
209    DWORD hex;
210    
211    do
212    {
213       hex=val%16;
214       if(hex<10)
215          *str=val + '0';
216       else
217          *str=val + 'A';
218       val=val/16;
219       str++;
220    }
221    while(val);
222    return retstr;
223 }
224
225
226 WINBOOL
227 STDCALL
228 EnumSystemLocalesA(
229     LOCALE_ENUMPROC lpLocaleEnumProc,
230     DWORD            dwFlags)
231 {
232    CHAR         locstr[10];
233    BOOL         retval;
234    PLOCALE      plocale;   
235    
236    if(!lpLocaleEnumProc) {
237         SetLastError(ERROR_INVALID_PARAMETER);
238         return FALSE;
239    }
240       
241    plocale=__Locale;
242    retval=TRUE;
243    while((plocale->Id)&&(retval))
244    {
245       __xtoa(locstr,plocale->Id); 
246       retval=lpLocaleEnumProc((void *)locstr);
247    }
248    return TRUE;
249 }
250 WINBOOL
251 STDCALL
252 EnumSystemLocalesW(
253     LOCALE_ENUMPROC lpLocaleEnumProc,
254     DWORD            dwFlags)
255 {
256    WCHAR        locstr[10];
257    WINBOOL      retval=TRUE;
258    PLOCALE      plocale=__Locale;  
259    
260    
261    if(!lpLocaleEnumProc) {
262         SetLastError(ERROR_INVALID_PARAMETER);
263         return FALSE;
264    }
265       
266    while((plocale->Id)&&(retval))
267    {
268       __xtow(locstr,plocale->Id);
269       retval=lpLocaleEnumProc((void *)locstr);
270    }
271    return TRUE;
272 }
273
274 int
275 STDCALL
276 GetLocaleInfoW(
277     LCID     Locale,
278     LCTYPE   LCType,
279     LPWSTR  lpLCData,
280     int      cchData)
281 {
282    INT          retcnt=0;
283    PLOCALE      plocale=__Locale;  
284    LPWSTR       infostr; 
285    
286    while(plocale->Id!=Locale)
287       plocale++;
288    
289    if(LCType<89)
290       infostr=plocale->Info0[LCType];
291    else if((LCType>0x1000)&&(LCType<0x1011))
292       infostr=plocale->Info1[LCType-0x1000];
293    else
294       { SetLastError(ERROR_INVALID_PARAMETER); return 0; }
295       
296    if(cchData)
297    {   
298       /* I really need a wide string copy, here */
299       do      
300       {
301          *lpLCData=*infostr;
302          infostr++;
303          lpLCData++;
304          cchData--;
305          retcnt++;
306       }
307       while((*infostr)&&(cchData));
308    }
309    else
310    {
311       /* I really need a wide string length, here */
312       do
313       {
314          infostr++;
315          retcnt++;
316       }
317       while(*infostr);
318    }
319    return retcnt;
320 }
321 int
322 STDCALL
323 GetLocaleInfoA(
324     LCID     Locale,
325     LCTYPE   LCType,
326     LPSTR  lpLCData,
327     int      cchData)
328 {
329    INT          retcnt=0;
330    PLOCALE      plocale=__Locale;  
331    LPWSTR       infostr; 
332    
333    while(plocale->Id!=Locale)
334       plocale++;
335    
336    if(LCType<89)
337       infostr=plocale->Info0[LCType];
338    else if((LCType>0x1000)&&(LCType<0x1011))
339       infostr=plocale->Info1[LCType-0x1000];
340    else
341       { SetLastError(ERROR_INVALID_PARAMETER); return 0; }
342       
343    if(cchData)
344    {   
345       /* I really need a wide string copy, here */
346       do      
347       {
348          *lpLCData=*infostr;
349          infostr++;
350          lpLCData++;
351          cchData--;
352          retcnt++;
353       }
354       while((*infostr)&&(cchData));
355    }
356    else
357    {
358       /* I really need a wide string length, here */
359       do
360       {
361          infostr++;
362          retcnt++;
363       }
364       while(*infostr);
365    }
366    return retcnt;
367 }
368
369 const struct map_lcid2str {
370         LCID            langid;
371         const char      *langname;
372 } languages[]={
373         {0x0401,"Arabic (Saudi Arabia)"},
374         {0x0801,"Arabic (Iraq)"},
375         {0x0c01,"Arabic (Egypt)"},
376         {0x1001,"Arabic (Libya)"},
377         {0x1401,"Arabic (Algeria)"},
378         {0x1801,"Arabic (Morocco)"},
379         {0x1c01,"Arabic (Tunisia)"},
380         {0x2001,"Arabic (Oman)"},
381         {0x2401,"Arabic (Yemen)"},
382         {0x2801,"Arabic (Syria)"},
383         {0x2c01,"Arabic (Jordan)"},
384         {0x3001,"Arabic (Lebanon)"},
385         {0x3401,"Arabic (Kuwait)"},
386         {0x3801,"Arabic (United Arab Emirates)"},
387         {0x3c01,"Arabic (Bahrain)"},
388         {0x4001,"Arabic (Qatar)"},
389         {0x0402,"Bulgarian"},
390         {0x0403,"Catalan"},
391         {0x0404,"Chinese (Taiwan)"},
392         {0x0804,"Chinese (People's Republic of China)"},
393         {0x0c04,"Chinese (Hong Kong)"},
394         {0x1004,"Chinese (Singapore)"},
395         {0x1404,"Chinese (Macau)"},
396         {0x0405,"Czech"},
397         {0x0406,"Danish"},
398         {0x0407,"German (Germany)"},
399         {0x0807,"German (Switzerland)"},
400         {0x0c07,"German (Austria)"},
401         {0x1007,"German (Luxembourg)"},
402         {0x1407,"German (Liechtenstein)"},
403         {0x0408,"Greek"},
404         {0x0409,"English (United States)"},
405         {0x0809,"English (United Kingdom)"},
406         {0x0c09,"English (Australia)"},
407         {0x1009,"English (Canada)"},
408         {0x1409,"English (New Zealand)"},
409         {0x1809,"English (Ireland)"},
410         {0x1c09,"English (South Africa)"},
411         {0x2009,"English (Jamaica)"},
412         {0x2409,"English (Caribbean)"},
413         {0x2809,"English (Belize)"},
414         {0x2c09,"English (Trinidad)"},
415         {0x3009,"English (Zimbabwe)"},
416         {0x3409,"English (Philippines)"},
417         {0x040a,"Spanish (Spain, traditional sorting)"},
418         {0x080a,"Spanish (Mexico)"},
419         {0x0c0a,"Spanish (Spain, international sorting)"},
420         {0x100a,"Spanish (Guatemala)"},
421         {0x140a,"Spanish (Costa Rica)"},
422         {0x180a,"Spanish (Panama)"},
423         {0x1c0a,"Spanish (Dominican Republic)"},
424         {0x200a,"Spanish (Venezuela)"},
425         {0x240a,"Spanish (Colombia)"},
426         {0x280a,"Spanish (Peru)"},
427         {0x2c0a,"Spanish (Argentina)"},
428         {0x300a,"Spanish (Ecuador)"},
429         {0x340a,"Spanish (Chile)"},
430         {0x380a,"Spanish (Uruguay)"},
431         {0x3c0a,"Spanish (Paraguay)"},
432         {0x400a,"Spanish (Bolivia)"},
433         {0x440a,"Spanish (El Salvador)"},
434         {0x480a,"Spanish (Honduras)"},
435         {0x4c0a,"Spanish (Nicaragua)"},
436         {0x500a,"Spanish (Puerto Rico)"},
437         {0x040b,"Finnish"},
438         {0x040c,"French (France)"},
439         {0x080c,"French (Belgium)"},
440         {0x0c0c,"French (Canada)"},
441         {0x100c,"French (Switzerland)"},
442         {0x140c,"French (Luxembourg)"},
443         {0x180c,"French (Monaco)"},
444         {0x040d,"Hebrew"},
445         {0x040e,"Hungarian"},
446         {0x040f,"Icelandic"},
447         {0x0410,"Italian (Italy)"},
448         {0x0810,"Italian (Switzerland)"},
449         {0x0411,"Japanese"},
450         {0x0412,"Korean (Wansung)"},
451         {0x0812,"Korean (Johab)"},
452         {0x0413,"Dutch (Netherlands)"},
453         {0x0813,"Dutch (Belgium)"},
454         {0x0414,"Norwegian (Bokmal)"},
455         {0x0814,"Norwegian (Nynorsk)"},
456         {0x0415,"Polish"},
457         {0x0416,"Portuguese (Brazil)"},
458         {0x0816,"Portuguese (Portugal)"},
459         {0x0417,"Rhaeto Romanic"},
460         {0x0418,"Romanian"},
461         {0x0818,"Moldavian"},
462         {0x0419,"Russian (Russia)"},
463         {0x0819,"Russian (Moldavia)"},
464         {0x041a,"Croatian"},
465         {0x081a,"Serbian (latin)"},
466         {0x0c1a,"Serbian (cyrillic)"},
467         {0x041b,"Slovak"},
468         {0x041c,"Albanian"},
469         {0x041d,"Swedish (Sweden)"},
470         {0x081d,"Swedish (Finland)"},
471         {0x041e,"Thai"},
472         {0x041f,"Turkish"},
473         {0x0420,"Urdu"},
474         {0x0421,"Indonesian"},
475         {0x0422,"Ukrainian"},
476         {0x0423,"Belarusian"},
477         {0x0424,"Slovene"},
478         {0x0425,"Estonian"},
479         {0x0426,"Latvian"},
480         {0x0427,"Lithuanian (modern)"},
481         {0x0827,"Lithuanian (classic)"},
482         {0x0428,"Maori"},
483         {0x0429,"Farsi"},
484         {0x042a,"Vietnamese"},
485         {0x042b,"Armenian"},
486         {0x042c,"Azeri (latin)"},
487         {0x082c,"Azeri (cyrillic)"},
488         {0x042d,"Basque"},
489         {0x042e,"Sorbian"},
490         {0x042f,"Macedonian"},
491         {0x0430,"Sutu"},
492         {0x0431,"Tsonga"},
493         {0x0432,"Tswana"},
494         {0x0433,"Venda"},
495         {0x0434,"Xhosa"},
496         {0x0435,"Zulu"},
497         {0x0436,"Afrikaans"},
498         {0x0437,"Georgian"},
499         {0x0438,"Faeroese"},
500         {0x0439,"Hindi"},
501         {0x043a,"Maltese"},
502         {0x043b,"Saami"},
503         {0x043c,"Irish gaelic"},
504         {0x083c,"Scottish gaelic"},
505         {0x043e,"Malay (Malaysia)"},
506         {0x083e,"Malay (Brunei Darussalam)"},
507         {0x043f,"Kazak"},
508         {0x0441,"Swahili"},
509         {0x0443,"Uzbek (latin)"},
510         {0x0843,"Uzbek (cyrillic)"},
511         {0x0444,"Tatar"},
512         {0x0445,"Bengali"},
513         {0x0446,"Punjabi"},
514         {0x0447,"Gujarati"},
515         {0x0448,"Oriya"},
516         {0x0449,"Tamil"},
517         {0x044a,"Telugu"},
518         {0x044b,"Kannada"},
519         {0x044c,"Malayalam"},
520         {0x044d,"Assamese"},
521         {0x044e,"Marathi"},
522         {0x044f,"Sanskrit"},
523         {0x0457,"Konkani"},
524         {0x048f,"Esperanto"}, /* Non official */
525         {0x0000,"Unknown"}
526     
527 };
528
529
530 static const unsigned char CT_CType2_LUT[] = {
531   C2_NOTAPPLICABLE, /*   -   0 */
532   C2_NOTAPPLICABLE, /*   -   1 */
533   C2_NOTAPPLICABLE, /*   -   2 */
534   C2_NOTAPPLICABLE, /*   -   3 */
535   C2_NOTAPPLICABLE, /*   -   4 */
536   C2_NOTAPPLICABLE, /*   -   5 */
537   C2_NOTAPPLICABLE, /*   -   6 */
538   C2_NOTAPPLICABLE, /*   -   7 */
539   C2_NOTAPPLICABLE, /*   -   8 */
540   C2_SEGMENTSEPARATOR, /*   -   9 */
541   C2_NOTAPPLICABLE, /*   -  10 */
542   C2_NOTAPPLICABLE, /*   -  11 */
543   C2_NOTAPPLICABLE, /*   -  12 */
544   C2_NOTAPPLICABLE, /*   -  13 */
545   C2_NOTAPPLICABLE, /*   -  14 */
546   C2_NOTAPPLICABLE, /*   -  15 */
547   C2_NOTAPPLICABLE, /*   -  16 */
548   C2_NOTAPPLICABLE, /*   -  17 */
549   C2_NOTAPPLICABLE, /*   -  18 */
550   C2_NOTAPPLICABLE, /*   -  19 */
551   C2_NOTAPPLICABLE, /*   -  20 */
552   C2_NOTAPPLICABLE, /*   -  21 */
553   C2_NOTAPPLICABLE, /*   -  22 */
554   C2_NOTAPPLICABLE, /*   -  23 */
555   C2_NOTAPPLICABLE, /*   -  24 */
556   C2_NOTAPPLICABLE, /*   -  25 */
557   C2_NOTAPPLICABLE, /*   -  26 */
558   C2_NOTAPPLICABLE, /*   -  27 */
559   C2_NOTAPPLICABLE, /*   -  28 */
560   C2_NOTAPPLICABLE, /*   -  29 */
561   C2_NOTAPPLICABLE, /*   -  30 */
562   C2_NOTAPPLICABLE, /*   -  31 */
563   C2_WHITESPACE, /*   -  32 */
564   C2_OTHERNEUTRAL, /* ! -  33 */
565   C2_OTHERNEUTRAL, /* " -  34 */ /* " */
566   C2_EUROPETERMINATOR, /* # -  35 */
567   C2_EUROPETERMINATOR, /* $ -  36 */
568   C2_EUROPETERMINATOR, /* % -  37 */
569   C2_LEFTTORIGHT, /* & -  38 */
570   C2_OTHERNEUTRAL, /* ' -  39 */
571   C2_OTHERNEUTRAL, /* ( -  40 */
572   C2_OTHERNEUTRAL, /* ) -  41 */
573   C2_OTHERNEUTRAL, /* * -  42 */
574   C2_EUROPETERMINATOR, /* + -  43 */
575   C2_COMMONSEPARATOR, /* , -  44 */
576   C2_EUROPETERMINATOR, /* - -  45 */
577   C2_EUROPESEPARATOR, /* . -  46 */
578   C2_EUROPESEPARATOR, /* / -  47 */
579   C2_EUROPENUMBER, /* 0 -  48 */
580   C2_EUROPENUMBER, /* 1 -  49 */
581   C2_EUROPENUMBER, /* 2 -  50 */
582   C2_EUROPENUMBER, /* 3 -  51 */
583   C2_EUROPENUMBER, /* 4 -  52 */
584   C2_EUROPENUMBER, /* 5 -  53 */
585   C2_EUROPENUMBER, /* 6 -  54 */
586   C2_EUROPENUMBER, /* 7 -  55 */
587   C2_EUROPENUMBER, /* 8 -  56 */
588   C2_EUROPENUMBER, /* 9 -  57 */
589   C2_COMMONSEPARATOR, /* : -  58 */
590   C2_OTHERNEUTRAL, /* ; -  59 */
591   C2_OTHERNEUTRAL, /* < -  60 */
592   C2_OTHERNEUTRAL, /* = -  61 */
593   C2_OTHERNEUTRAL, /* > -  62 */
594   C2_OTHERNEUTRAL, /* ? -  63 */
595   C2_LEFTTORIGHT, /* @ -  64 */
596   C2_LEFTTORIGHT, /* A -  65 */
597   C2_LEFTTORIGHT, /* B -  66 */
598   C2_LEFTTORIGHT, /* C -  67 */
599   C2_LEFTTORIGHT, /* D -  68 */
600   C2_LEFTTORIGHT, /* E -  69 */
601   C2_LEFTTORIGHT, /* F -  70 */
602   C2_LEFTTORIGHT, /* G -  71 */
603   C2_LEFTTORIGHT, /* H -  72 */
604   C2_LEFTTORIGHT, /* I -  73 */
605   C2_LEFTTORIGHT, /* J -  74 */
606   C2_LEFTTORIGHT, /* K -  75 */
607   C2_LEFTTORIGHT, /* L -  76 */
608   C2_LEFTTORIGHT, /* M -  77 */
609   C2_LEFTTORIGHT, /* N -  78 */
610   C2_LEFTTORIGHT, /* O -  79 */
611   C2_LEFTTORIGHT, /* P -  80 */
612   C2_LEFTTORIGHT, /* Q -  81 */
613   C2_LEFTTORIGHT, /* R -  82 */
614   C2_LEFTTORIGHT, /* S -  83 */
615   C2_LEFTTORIGHT, /* T -  84 */
616   C2_LEFTTORIGHT, /* U -  85 */
617   C2_LEFTTORIGHT, /* V -  86 */
618   C2_LEFTTORIGHT, /* W -  87 */
619   C2_LEFTTORIGHT, /* X -  88 */
620   C2_LEFTTORIGHT, /* Y -  89 */
621   C2_LEFTTORIGHT, /* Z -  90 */
622   C2_OTHERNEUTRAL, /* [ -  91 */
623   C2_OTHERNEUTRAL, /* \ -  92 */
624   C2_OTHERNEUTRAL, /* ] -  93 */
625   C2_OTHERNEUTRAL, /* ^ -  94 */
626   C2_OTHERNEUTRAL, /* _ -  95 */
627   C2_OTHERNEUTRAL, /* ` -  96 */
628   C2_LEFTTORIGHT, /* a -  97 */
629   C2_LEFTTORIGHT, /* b -  98 */
630   C2_LEFTTORIGHT, /* c -  99 */
631   C2_LEFTTORIGHT, /* d - 100 */
632   C2_LEFTTORIGHT, /* e - 101 */
633   C2_LEFTTORIGHT, /* f - 102 */
634   C2_LEFTTORIGHT, /* g - 103 */
635   C2_LEFTTORIGHT, /* h - 104 */
636   C2_LEFTTORIGHT, /* i - 105 */
637   C2_LEFTTORIGHT, /* j - 106 */
638   C2_LEFTTORIGHT, /* k - 107 */
639   C2_LEFTTORIGHT, /* l - 108 */
640   C2_LEFTTORIGHT, /* m - 109 */
641   C2_LEFTTORIGHT, /* n - 110 */
642   C2_LEFTTORIGHT, /* o - 111 */
643   C2_LEFTTORIGHT, /* p - 112 */
644   C2_LEFTTORIGHT, /* q - 113 */
645   C2_LEFTTORIGHT, /* r - 114 */
646   C2_LEFTTORIGHT, /* s - 115 */
647   C2_LEFTTORIGHT, /* t - 116 */
648   C2_LEFTTORIGHT, /* u - 117 */
649   C2_LEFTTORIGHT, /* v - 118 */
650   C2_LEFTTORIGHT, /* w - 119 */
651   C2_LEFTTORIGHT, /* x - 120 */
652   C2_LEFTTORIGHT, /* y - 121 */
653   C2_LEFTTORIGHT, /* z - 122 */
654   C2_OTHERNEUTRAL, /* { - 123 */
655   C2_OTHERNEUTRAL, /* | - 124 */
656   C2_OTHERNEUTRAL, /* } - 125 */
657   C2_OTHERNEUTRAL, /* ~ - 126 */
658   C2_NOTAPPLICABLE, /* \7f - 127 */
659   C2_NOTAPPLICABLE, /* \80 - 128 */
660   C2_NOTAPPLICABLE, /* \81 - 129 */
661   C2_OTHERNEUTRAL, /* \82 - 130 */
662   C2_LEFTTORIGHT, /* \83 - 131 */
663   C2_OTHERNEUTRAL, /* \84 - 132 */
664   C2_OTHERNEUTRAL, /* \85 - 133 */
665   C2_OTHERNEUTRAL, /* \86 - 134 */
666   C2_OTHERNEUTRAL, /* \87 - 135 */
667   C2_LEFTTORIGHT, /* \88 - 136 */
668   C2_EUROPETERMINATOR, /* \89 - 137 */
669   C2_LEFTTORIGHT, /* \8a - 138 */
670   C2_OTHERNEUTRAL, /* \8b - 139 */
671   C2_LEFTTORIGHT, /* \8c - 140 */
672   C2_NOTAPPLICABLE, /* \8d - 141 */
673   C2_NOTAPPLICABLE, /* \8e - 142 */
674   C2_NOTAPPLICABLE, /* \8f - 143 */
675   C2_NOTAPPLICABLE, /* \90 - 144 */
676   C2_OTHERNEUTRAL, /* \91 - 145 */
677   C2_OTHERNEUTRAL, /* \92 - 146 */
678   C2_OTHERNEUTRAL, /* \93 - 147 */
679   C2_OTHERNEUTRAL, /* \94 - 148 */
680   C2_OTHERNEUTRAL, /* \95 - 149 */
681   C2_OTHERNEUTRAL, /* \96 - 150 */
682   C2_OTHERNEUTRAL, /* \97 - 151 */
683   C2_LEFTTORIGHT, /* \98 - 152 */
684   C2_OTHERNEUTRAL, /* \99 - 153 */
685   C2_LEFTTORIGHT, /* \9a - 154 */
686   C2_OTHERNEUTRAL, /* \9b - 155 */
687   C2_LEFTTORIGHT, /* \9c - 156 */
688   C2_NOTAPPLICABLE, /* \9d - 157 */
689   C2_NOTAPPLICABLE, /* \9e - 158 */
690   C2_LEFTTORIGHT, /* \9f - 159 */
691   C2_WHITESPACE, /*   - 160 */
692   C2_OTHERNEUTRAL, /* ¡ - 161 */
693   C2_EUROPETERMINATOR, /* ¢ - 162 */
694   C2_EUROPETERMINATOR, /* £ - 163 */
695   C2_EUROPETERMINATOR, /* ¤ - 164 */
696   C2_EUROPETERMINATOR, /* ¥ - 165 */
697   C2_OTHERNEUTRAL, /* ¦ - 166 */
698   C2_OTHERNEUTRAL, /* § - 167 */
699   C2_OTHERNEUTRAL, /* ¨ - 168 */
700   C2_OTHERNEUTRAL, /* © - 169 */
701   C2_OTHERNEUTRAL, /* ª - 170 */
702   C2_OTHERNEUTRAL, /* « - 171 */
703   C2_OTHERNEUTRAL, /* ¬ - 172 */
704   C2_OTHERNEUTRAL, /* ­ - 173 */
705   C2_OTHERNEUTRAL, /* ® - 174 */
706   C2_OTHERNEUTRAL, /* ¯ - 175 */
707   C2_EUROPETERMINATOR, /* ° - 176 */
708   C2_EUROPETERMINATOR, /* ± - 177 */
709   C2_EUROPENUMBER, /* ² - 178 */
710   C2_EUROPENUMBER, /* ³ - 179 */
711   C2_OTHERNEUTRAL, /* ´ - 180 */
712   C2_OTHERNEUTRAL, /* µ - 181 */
713   C2_OTHERNEUTRAL, /* ¶ - 182 */
714   C2_OTHERNEUTRAL, /* · - 183 */
715   C2_OTHERNEUTRAL, /* ¸ - 184 */
716   C2_EUROPENUMBER, /* ¹ - 185 */
717   C2_OTHERNEUTRAL, /* º - 186 */
718   C2_OTHERNEUTRAL, /* » - 187 */
719   C2_OTHERNEUTRAL, /* ¼ - 188 */
720   C2_OTHERNEUTRAL, /* ½ - 189 */
721   C2_OTHERNEUTRAL, /* ¾ - 190 */
722   C2_OTHERNEUTRAL, /* ¿ - 191 */
723   C2_LEFTTORIGHT, /* À - 192 */
724   C2_LEFTTORIGHT, /* Á - 193 */
725   C2_LEFTTORIGHT, /* Â - 194 */
726   C2_LEFTTORIGHT, /* Ã - 195 */
727   C2_LEFTTORIGHT, /* Ä - 196 */
728   C2_LEFTTORIGHT, /* Å - 197 */
729   C2_LEFTTORIGHT, /* Æ - 198 */
730   C2_LEFTTORIGHT, /* Ç - 199 */
731   C2_LEFTTORIGHT, /* È - 200 */
732   C2_LEFTTORIGHT, /* É - 201 */
733   C2_LEFTTORIGHT, /* Ê - 202 */
734   C2_LEFTTORIGHT, /* Ë - 203 */
735   C2_LEFTTORIGHT, /* Ì - 204 */
736   C2_LEFTTORIGHT, /* Í - 205 */
737   C2_LEFTTORIGHT, /* Î - 206 */
738   C2_LEFTTORIGHT, /* Ï - 207 */
739   C2_LEFTTORIGHT, /* Ð - 208 */
740   C2_LEFTTORIGHT, /* Ñ - 209 */
741   C2_LEFTTORIGHT, /* Ò - 210 */
742   C2_LEFTTORIGHT, /* Ó - 211 */
743   C2_LEFTTORIGHT, /* Ô - 212 */
744   C2_LEFTTORIGHT, /* Õ - 213 */
745   C2_LEFTTORIGHT, /* Ö - 214 */
746   C2_OTHERNEUTRAL, /* × - 215 */
747   C2_LEFTTORIGHT, /* Ø - 216 */
748   C2_LEFTTORIGHT, /* Ù - 217 */
749   C2_LEFTTORIGHT, /* Ú - 218 */
750   C2_LEFTTORIGHT, /* Û - 219 */
751   C2_LEFTTORIGHT, /* Ü - 220 */
752   C2_LEFTTORIGHT, /* Ý - 221 */
753   C2_LEFTTORIGHT, /* Þ - 222 */
754   C2_LEFTTORIGHT, /* ß - 223 */
755   C2_LEFTTORIGHT, /* à - 224 */
756   C2_LEFTTORIGHT, /* á - 225 */
757   C2_LEFTTORIGHT, /* â - 226 */
758   C2_LEFTTORIGHT, /* ã - 227 */
759   C2_LEFTTORIGHT, /* ä - 228 */
760   C2_LEFTTORIGHT, /* å - 229 */
761   C2_LEFTTORIGHT, /* æ - 230 */
762   C2_LEFTTORIGHT, /* ç - 231 */
763   C2_LEFTTORIGHT, /* è - 232 */
764   C2_LEFTTORIGHT, /* é - 233 */
765   C2_LEFTTORIGHT, /* ê - 234 */
766   C2_LEFTTORIGHT, /* ë - 235 */
767   C2_LEFTTORIGHT, /* ì - 236 */
768   C2_LEFTTORIGHT, /* í - 237 */
769   C2_LEFTTORIGHT, /* î - 238 */
770   C2_LEFTTORIGHT, /* ï - 239 */
771   C2_LEFTTORIGHT, /* ð - 240 */
772   C2_LEFTTORIGHT, /* ñ - 241 */
773   C2_LEFTTORIGHT, /* ò - 242 */
774   C2_LEFTTORIGHT, /* ó - 243 */
775   C2_LEFTTORIGHT, /* ô - 244 */
776   C2_LEFTTORIGHT, /* õ - 245 */
777   C2_LEFTTORIGHT, /* ö - 246 */
778   C2_OTHERNEUTRAL, /* ÷ - 247 */
779   C2_LEFTTORIGHT, /* ø - 248 */
780   C2_LEFTTORIGHT, /* ù - 249 */
781   C2_LEFTTORIGHT, /* ú - 250 */
782   C2_LEFTTORIGHT, /* û - 251 */
783   C2_LEFTTORIGHT, /* ü - 252 */
784   C2_LEFTTORIGHT, /* ý - 253 */
785   C2_LEFTTORIGHT, /* þ - 254 */
786   C2_LEFTTORIGHT /* ÿ - 255 */
787 };
788
789 static const WORD CT_CType3_LUT[] = { 
790   0x0000, /*   -   0 */
791   0x0000, /*   -   1 */
792   0x0000, /*   -   2 */
793   0x0000, /*   -   3 */
794   0x0000, /*   -   4 */
795   0x0000, /*   -   5 */
796   0x0000, /*   -   6 */
797   0x0000, /*   -   7 */
798   0x0000, /*   -   8 */
799   0x0008, /*   -   9 */
800   0x0008, /*   -  10 */
801   0x0008, /*   -  11 */
802   0x0008, /*   -  12 */
803   0x0008, /*   -  13 */
804   0x0000, /*   -  14 */
805   0x0000, /*   -  15 */
806   0x0000, /*   -  16 */
807   0x0000, /*   -  17 */
808   0x0000, /*   -  18 */
809   0x0000, /*   -  19 */
810   0x0000, /*   -  20 */
811   0x0000, /*   -  21 */
812   0x0000, /*   -  22 */
813   0x0000, /*   -  23 */
814   0x0000, /*   -  24 */
815   0x0000, /*   -  25 */
816   0x0000, /*   -  26 */
817   0x0000, /*   -  27 */
818   0x0000, /*   -  28 */
819   0x0000, /*   -  29 */
820   0x0000, /*   -  30 */
821   0x0000, /*   -  31 */
822   0x0048, /*   -  32 */
823   0x0048, /* ! -  33 */
824   0x0448, /* " -  34 */ /* " */
825   0x0048, /* # -  35 */
826   0x0448, /* $ -  36 */
827   0x0048, /* % -  37 */
828   0x0048, /* & -  38 */
829   0x0440, /* ' -  39 */
830   0x0048, /* ( -  40 */
831   0x0048, /* ) -  41 */
832   0x0048, /* * -  42 */
833   0x0048, /* + -  43 */
834   0x0048, /* , -  44 */
835   0x0440, /* - -  45 */
836   0x0048, /* . -  46 */
837   0x0448, /* / -  47 */
838   0x0040, /* 0 -  48 */
839   0x0040, /* 1 -  49 */
840   0x0040, /* 2 -  50 */
841   0x0040, /* 3 -  51 */
842   0x0040, /* 4 -  52 */
843   0x0040, /* 5 -  53 */
844   0x0040, /* 6 -  54 */
845   0x0040, /* 7 -  55 */
846   0x0040, /* 8 -  56 */
847   0x0040, /* 9 -  57 */
848   0x0048, /* : -  58 */
849   0x0048, /* ; -  59 */
850   0x0048, /* < -  60 */
851   0x0448, /* = -  61 */
852   0x0048, /* > -  62 */
853   0x0048, /* ? -  63 */
854   0x0448, /* @ -  64 */
855   0x8040, /* A -  65 */
856   0x8040, /* B -  66 */
857   0x8040, /* C -  67 */
858   0x8040, /* D -  68 */
859   0x8040, /* E -  69 */
860   0x8040, /* F -  70 */
861   0x8040, /* G -  71 */
862   0x8040, /* H -  72 */
863   0x8040, /* I -  73 */
864   0x8040, /* J -  74 */
865   0x8040, /* K -  75 */
866   0x8040, /* L -  76 */
867   0x8040, /* M -  77 */
868   0x8040, /* N -  78 */
869   0x8040, /* O -  79 */
870   0x8040, /* P -  80 */
871   0x8040, /* Q -  81 */
872   0x8040, /* R -  82 */
873   0x8040, /* S -  83 */
874   0x8040, /* T -  84 */
875   0x8040, /* U -  85 */
876   0x8040, /* V -  86 */
877   0x8040, /* W -  87 */
878   0x8040, /* X -  88 */
879   0x8040, /* Y -  89 */
880   0x8040, /* Z -  90 */
881   0x0048, /* [ -  91 */
882   0x0448, /* \ -  92 */
883   0x0048, /* ] -  93 */
884   0x0448, /* ^ -  94 */
885   0x0448, /* _ -  95 */
886   0x0448, /* ` -  96 */
887   0x8040, /* a -  97 */
888   0x8040, /* b -  98 */
889   0x8040, /* c -  99 */
890   0x8040, /* d - 100 */
891   0x8040, /* e - 101 */
892   0x8040, /* f - 102 */
893   0x8040, /* g - 103 */
894   0x8040, /* h - 104 */
895   0x8040, /* i - 105 */
896   0x8040, /* j - 106 */
897   0x8040, /* k - 107 */
898   0x8040, /* l - 108 */
899   0x8040, /* m - 109 */
900   0x8040, /* n - 110 */
901   0x8040, /* o - 111 */
902   0x8040, /* p - 112 */
903   0x8040, /* q - 113 */
904   0x8040, /* r - 114 */
905   0x8040, /* s - 115 */
906   0x8040, /* t - 116 */
907   0x8040, /* u - 117 */
908   0x8040, /* v - 118 */
909   0x8040, /* w - 119 */
910   0x8040, /* x - 120 */
911   0x8040, /* y - 121 */
912   0x8040, /* z - 122 */
913   0x0048, /* { - 123 */
914   0x0048, /* | - 124 */
915   0x0048, /* } - 125 */
916   0x0448, /* ~ - 126 */
917   0x0000, /* \7f - 127 */
918   0x0000, /* \80 - 128 */
919   0x0000, /* \81 - 129 */
920   0x0008, /* \82 - 130 */
921   0x8000, /* \83 - 131 */
922   0x0008, /* \84 - 132 */
923   0x0008, /* \85 - 133 */
924   0x0008, /* \86 - 134 */
925   0x0008, /* \87 - 135 */
926   0x0001, /* \88 - 136 */
927   0x0008, /* \89 - 137 */
928   0x8003, /* \8a - 138 */
929   0x0008, /* \8b - 139 */
930   0x8000, /* \8c - 140 */
931   0x0000, /* \8d - 141 */
932   0x0000, /* \8e - 142 */
933   0x0000, /* \8f - 143 */
934   0x0000, /* \90 - 144 */
935   0x0088, /* \91 - 145 */
936   0x0088, /* \92 - 146 */
937   0x0088, /* \93 - 147 */
938   0x0088, /* \94 - 148 */
939   0x0008, /* \95 - 149 */
940   0x0400, /* \96 - 150 */
941   0x0400, /* \97 - 151 */
942   0x0408, /* \98 - 152 */
943   0x0000, /* \99 - 153 */
944   0x8003, /* \9a - 154 */
945   0x0008, /* \9b - 155 */
946   0x8000, /* \9c - 156 */
947   0x0000, /* \9d - 157 */
948   0x0000, /* \9e - 158 */
949   0x8003, /* \9f - 159 */
950   0x0008, /*   - 160 */
951   0x0008, /* ¡ - 161 */
952   0x0048, /* ¢ - 162 */
953   0x0048, /* £ - 163 */
954   0x0008, /* ¤ - 164 */
955   0x0048, /* ¥ - 165 */
956   0x0048, /* ¦ - 166 */
957   0x0008, /* § - 167 */
958   0x0408, /* ¨ - 168 */
959   0x0008, /* © - 169 */
960   0x0400, /* ª - 170 */
961   0x0008, /* « - 171 */
962   0x0048, /* ¬ - 172 */
963   0x0408, /* ­ - 173 */
964   0x0008, /* ® - 174 */
965   0x0448, /* ¯ - 175 */
966   0x0008, /* ° - 176 */
967   0x0008, /* ± - 177 */
968   0x0000, /* ² - 178 */
969   0x0000, /* ³ - 179 */
970   0x0408, /* ´ - 180 */
971   0x0008, /* µ - 181 */
972   0x0008, /* ¶ - 182 */
973   0x0008, /* · - 183 */
974   0x0408, /* ¸ - 184 */
975   0x0000, /* ¹ - 185 */
976   0x0400, /* º - 186 */
977   0x0008, /* » - 187 */
978   0x0000, /* ¼ - 188 */
979   0x0000, /* ½ - 189 */
980   0x0000, /* ¾ - 190 */
981   0x0008, /* ¿ - 191 */
982   0x8003, /* À - 192 */
983   0x8003, /* Á - 193 */
984   0x8003, /* Â - 194 */
985   0x8003, /* Ã - 195 */
986   0x8003, /* Ä - 196 */
987   0x8003, /* Å - 197 */
988   0x8000, /* Æ - 198 */
989   0x8003, /* Ç - 199 */
990   0x8003, /* È - 200 */
991   0x8003, /* É - 201 */
992   0x8003, /* Ê - 202 */
993   0x8003, /* Ë - 203 */
994   0x8003, /* Ì - 204 */
995   0x8003, /* Í - 205 */
996   0x8003, /* Î - 206 */
997   0x8003, /* Ï - 207 */
998   0x8000, /* Ð - 208 */
999   0x8003, /* Ñ - 209 */
1000   0x8003, /* Ò - 210 */
1001   0x8003, /* Ó - 211 */
1002   0x8003, /* Ô - 212 */
1003   0x8003, /* Õ - 213 */
1004   0x8003, /* Ö - 214 */
1005   0x0008, /* × - 215 */
1006   0x8003, /* Ø - 216 */
1007   0x8003, /* Ù - 217 */
1008   0x8003, /* Ú - 218 */
1009   0x8003, /* Û - 219 */
1010   0x8003, /* Ü - 220 */
1011   0x8003, /* Ý - 221 */
1012   0x8000, /* Þ - 222 */
1013   0x8000, /* ß - 223 */
1014   0x8003, /* à - 224 */
1015   0x8003, /* á - 225 */
1016   0x8003, /* â - 226 */
1017   0x8003, /* ã - 227 */
1018   0x8003, /* ä - 228 */
1019   0x8003, /* å - 229 */
1020   0x8000, /* æ - 230 */
1021   0x8003, /* ç - 231 */
1022   0x8003, /* è - 232 */
1023   0x8003, /* é - 233 */
1024   0x8003, /* ê - 234 */
1025   0x8003, /* ë - 235 */
1026   0x8003, /* ì - 236 */
1027   0x8003, /* í - 237 */
1028   0x8003, /* î - 238 */
1029   0x8003, /* ï - 239 */
1030   0x8000, /* ð - 240 */
1031   0x8003, /* ñ - 241 */
1032   0x8003, /* ò - 242 */
1033   0x8003, /* ó - 243 */
1034   0x8003, /* ô - 244 */
1035   0x8003, /* õ - 245 */
1036   0x8003, /* ö - 246 */
1037   0x0008, /* ÷ - 247 */
1038   0x8003, /* ø - 248 */
1039   0x8003, /* ù - 249 */
1040   0x8003, /* ú - 250 */
1041   0x8003, /* û - 251 */
1042   0x8003, /* ü - 252 */
1043   0x8003, /* ý - 253 */
1044   0x8000, /* þ - 254 */
1045   0x8003  /* ÿ - 255 */
1046 };
1047
1048
1049
1050 WINBOOL
1051 STDCALL
1052 GetStringTypeExA(
1053     LCID     Locale,
1054     DWORD    dwInfoType,
1055     LPCSTR lpSrcStr,
1056     int      cchSrc,
1057     LPWORD   lpCharType)
1058 {
1059         int     i;
1060         
1061         if ((lpSrcStr==NULL) || (lpCharType==NULL) || (lpSrcStr==(LPCSTR)lpCharType))
1062         {
1063           SetLastError(ERROR_INVALID_PARAMETER);
1064           return FALSE;
1065         }
1066
1067         if (cchSrc==-1)
1068           cchSrc=lstrlenA(lpSrcStr)+1;
1069           
1070         switch (dwInfoType) {
1071         case CT_CTYPE1:
1072           for (i=0;i<cchSrc;i++) 
1073           {
1074             lpCharType[i] = 0;
1075             if (isdigit(lpSrcStr[i])) lpCharType[i]|=C1_DIGIT;
1076             if (isalpha(lpSrcStr[i])) lpCharType[i]|=C1_ALPHA;
1077             if (islower(lpSrcStr[i])) lpCharType[i]|=C1_LOWER;
1078             if (isupper(lpSrcStr[i])) lpCharType[i]|=C1_UPPER;
1079             if (isspace(lpSrcStr[i])) lpCharType[i]|=C1_SPACE;
1080             if (ispunct(lpSrcStr[i])) lpCharType[i]|=C1_PUNCT;
1081             if (iscntrl(lpSrcStr[i])) lpCharType[i]|=C1_CNTRL;
1082             if (isblank(lpSrcStr[i])) lpCharType[i]|=C1_BLANK; 
1083             if (isxdigit(lpSrcStr[i])) lpCharType[i]|=C1_XDIGIT; 
1084         }
1085         return TRUE;
1086
1087         case CT_CTYPE2:
1088           for (i=0;i<cchSrc;i++) 
1089           {
1090             lpCharType[i]=(WORD)CT_CType2_LUT[i];
1091           }
1092           return TRUE;
1093
1094         case CT_CTYPE3:
1095           for (i=0;i<cchSrc;i++) 
1096           {
1097             lpCharType[i]=CT_CType3_LUT[i];
1098           }
1099           return TRUE;
1100
1101         default:
1102           return FALSE;
1103         }
1104 }
1105
1106 WINBOOL
1107 STDCALL
1108 GetStringTypeA(
1109     LCID     Locale,
1110     DWORD    dwInfoType,
1111     LPCSTR   lpSrcStr,
1112     int      cchSrc,
1113     LPWORD   lpCharType)
1114 {
1115         return GetStringTypeExA(Locale, dwInfoType, lpSrcStr, cchSrc, lpCharType);
1116 }
1117
1118 WINBOOL
1119 STDCALL
1120 GetStringTypeExW(
1121     LCID     Locale,
1122     DWORD    dwInfoType,
1123     LPCWSTR lpSrcStr,
1124     int      cchSrc,
1125     LPWORD   lpCharType)
1126 {
1127         int     i;
1128         
1129         if ((lpSrcStr==NULL) || (lpCharType==NULL) || (lpSrcStr==(LPCWSTR)lpCharType))
1130         {
1131           SetLastError(ERROR_INVALID_PARAMETER);
1132           return FALSE;
1133         }
1134
1135         if (cchSrc==-1)
1136           cchSrc=lstrlenW(lpSrcStr)+1;
1137           
1138         switch (dwInfoType) {
1139         case CT_CTYPE1:
1140           for (i=0;i<cchSrc;i++) 
1141           {
1142             lpCharType[i] = 0;
1143             if (isdigit(lpSrcStr[i])) lpCharType[i]|=C1_DIGIT;
1144             if (iswalpha(lpSrcStr[i])) lpCharType[i]|=C1_ALPHA;
1145             if (iswlower(lpSrcStr[i])) lpCharType[i]|=C1_LOWER;
1146             if (iswupper(lpSrcStr[i])) lpCharType[i]|=C1_UPPER;
1147             if (isspace(lpSrcStr[i])) lpCharType[i]|=C1_SPACE;
1148             if (ispunct(lpSrcStr[i])) lpCharType[i]|=C1_PUNCT;
1149             if (iscntrl(lpSrcStr[i])) lpCharType[i]|=C1_CNTRL;
1150             if (isblank(lpSrcStr[i])) lpCharType[i]|=C1_BLANK; 
1151             if (isxdigit(lpSrcStr[i])) lpCharType[i]|=C1_XDIGIT; 
1152         }
1153         return TRUE;
1154
1155         case CT_CTYPE2:
1156           for (i=0;i<cchSrc;i++) 
1157           {
1158             lpCharType[i]=(WORD)CT_CType2_LUT[i];
1159           }
1160           return TRUE;
1161
1162         case CT_CTYPE3:
1163           for (i=0;i<cchSrc;i++) 
1164           {
1165             lpCharType[i]=CT_CType3_LUT[i];
1166           }
1167           return TRUE;
1168
1169         default:
1170           return FALSE;
1171         }
1172 }
1173
1174 WINBOOL
1175 STDCALL
1176 GetStringTypeW(
1177     DWORD    dwInfoType,
1178     LPCWSTR  lpSrcStr,
1179     int      cchSrc,
1180     LPWORD   lpCharType)
1181 {
1182         LCID     Locale = GetThreadLocale();
1183         return GetStringTypeExW(Locale, dwInfoType, lpSrcStr, cchSrc, lpCharType);
1184 }
1185
1186 DWORD
1187 STDCALL
1188 VerLanguageNameA(
1189         DWORD wLang,
1190         LPSTR szLang,
1191         DWORD nSize
1192         )
1193 {
1194         int     i;
1195         int len;
1196         for (i=0;languages[i].langid!=0;i++)
1197                 if (wLang==languages[i].langid)
1198                         break;
1199
1200         len = min(strlen(languages[i].langname),nSize);
1201         strncpy(szLang,languages[i].langname,len);
1202         return len;
1203 }
1204
1205 DWORD
1206 STDCALL
1207 VerLanguageNameW(
1208         DWORD wLang,
1209         LPWSTR szLang,
1210         DWORD nSize
1211         )
1212 {
1213         int     i,j;
1214         
1215         for (i=0;languages[i].langid!=0;i++)
1216                 if (wLang==languages[i].langid)
1217                         break;
1218         for(j=0;j<nSize && languages[i].langname[j] != 0 ;i++)
1219                 szLang[j] = languages[i].langname[j];
1220         szLang[j] = 0;
1221         return strlen(languages[i].langname);
1222 }
1223
1224
1225
1226
1227 int
1228 STDCALL
1229 GetDateFormatW(
1230     LCID     Locale,
1231     DWORD    dwFlags,
1232     CONST SYSTEMTIME *lpDate,
1233     LPCWSTR lpFormat,
1234     LPWSTR  lpDateStr,
1235     int      cchDate)
1236 {
1237         return 0;
1238 }
1239
1240 /******************************************************************************
1241  *              GetDateFormatA  [KERNEL32.310]
1242  * Makes an ASCII string of the date
1243  *
1244  * This function uses format to format the date,  or,  if format
1245  * is NULL, uses the default for the locale.  format is a string
1246  * of literal fields and characters as follows:
1247  *
1248  * - d    single-digit (no leading zero) day (of month)
1249  * - dd   two-digit day (of month)
1250  * - ddd  short day-of-week name
1251  * - dddd long day-of-week name
1252  * - M    single-digit month
1253  * - MM   two-digit month
1254  * - MMM  short month name
1255  * - MMMM full month name
1256  * - y    two-digit year, no leading 0
1257  * - yy   two-digit year
1258  * - yyyy four-digit year
1259  * - gg   era string
1260  *
1261  */
1262 int STDCALL GetDateFormatA(LCID locale,DWORD flags,
1263                               CONST SYSTEMTIME *xtime,
1264                               LPCSTR format, LPSTR date,int datelen) 
1265 {
1266    
1267   char format_buf[40];
1268   LPCSTR thisformat;
1269   SYSTEMTIME t;
1270   LPSYSTEMTIME thistime;
1271   LCID thislocale;
1272   INT ret;
1273
1274
1275   
1276   thislocale = OLE2NLS_CheckLocale ( locale );
1277
1278   if (xtime == NULL) {
1279      GetSystemTime(&t);
1280      thisti