msvcrt: Sync _wtempnam with _tempnam.
[wine] / dlls / msvcrt / ctype.c
1 /*
2  * msvcrt.dll ctype functions
3  *
4  * Copyright 2000 Jon Griffiths
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "msvcrt.h"
22 #include "winnls.h"
23 #include "wine/unicode.h"
24
25 /* Some abbreviations to make the following table readable */
26 #define _C_ MSVCRT__CONTROL
27 #define _S_ MSVCRT__SPACE
28 #define _P_ MSVCRT__PUNCT
29 #define _D_ MSVCRT__DIGIT
30 #define _H_ MSVCRT__HEX
31 #define _U_ MSVCRT__UPPER
32 #define _L_ MSVCRT__LOWER
33
34 WORD MSVCRT__ctype [257] = {
35   0, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_C_, _S_|_C_,
36   _S_|_C_, _S_|_C_, _S_|_C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
37   _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|MSVCRT__BLANK,
38   _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_,
39   _P_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_,
40   _D_|_H_, _D_|_H_, _D_|_H_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _U_|_H_,
41   _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_, _U_, _U_, _U_, _U_,
42   _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_,
43   _U_, _P_, _P_, _P_, _P_, _P_, _P_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_,
44   _L_|_H_, _L_|_H_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_,
45   _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _P_, _P_, _P_,
46   _C_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
52 };
53
54 /*********************************************************************
55  *              __p__pctype (MSVCRT.@)
56  */
57 unsigned short** CDECL MSVCRT___p__pctype(void)
58 {
59     return &get_locinfo()->pctype;
60 }
61
62 /*********************************************************************
63  *              __pctype_func (MSVCRT.@)
64  */
65 const unsigned short* CDECL MSVCRT___pctype_func(void)
66 {
67     return get_locinfo()->pctype;
68 }
69
70 /*********************************************************************
71  *              _isctype_l (MSVCRT.@)
72  */
73 int CDECL MSVCRT__isctype_l(int c, int type, MSVCRT__locale_t locale)
74 {
75   MSVCRT_pthreadlocinfo locinfo;
76
77   if(!locale)
78     locinfo = get_locinfo();
79   else
80     locinfo = locale->locinfo;
81
82   if (c >= -1 && c <= 255)
83     return locinfo->pctype[c] & type;
84
85   if (locinfo->mb_cur_max != 1 && c > 0)
86   {
87     /* FIXME: Is there a faster way to do this? */
88     WORD typeInfo;
89     char convert[3], *pconv = convert;
90
91     if (locinfo->pctype[(UINT)c >> 8] & MSVCRT__LEADBYTE)
92       *pconv++ = (UINT)c >> 8;
93     *pconv++ = c & 0xff;
94     *pconv = 0;
95
96     if (GetStringTypeExA(locinfo->lc_handle[MSVCRT_LC_CTYPE],
97                 CT_CTYPE1, convert, convert[1] ? 2 : 1, &typeInfo))
98       return typeInfo & type;
99   }
100   return 0;
101 }
102
103 /*********************************************************************
104  *              _isctype (MSVCRT.@)
105  */
106 int CDECL MSVCRT__isctype(int c, int type)
107 {
108     return MSVCRT__isctype_l(c, type, NULL);
109 }
110
111 /*********************************************************************
112  *              _isalnum_l (MSVCRT.@)
113  */
114 int CDECL MSVCRT__isalnum_l(int c, MSVCRT__locale_t locale)
115 {
116   return MSVCRT__isctype_l( c, MSVCRT__ALPHA | MSVCRT__DIGIT, locale );
117 }
118
119 /*********************************************************************
120  *              isalnum (MSVCRT.@)
121  */
122 int CDECL MSVCRT_isalnum(int c)
123 {
124   return MSVCRT__isctype( c, MSVCRT__ALPHA | MSVCRT__DIGIT );
125 }
126
127 /*********************************************************************
128  *              _isalpha_l (MSVCRT.@)
129  */
130 int CDECL MSVCRT__isalpha_l(int c, MSVCRT__locale_t locale)
131 {
132   return MSVCRT__isctype_l( c, MSVCRT__ALPHA, locale );
133 }
134
135 /*********************************************************************
136  *              isalpha (MSVCRT.@)
137  */
138 int CDECL MSVCRT_isalpha(int c)
139 {
140   return MSVCRT__isctype( c, MSVCRT__ALPHA );
141 }
142
143 /*********************************************************************
144  *              _iscntrl_l (MSVCRT.@)
145  */
146 int CDECL MSVCRT__iscntrl_l(int c, MSVCRT__locale_t locale)
147 {
148   return MSVCRT__isctype_l( c, MSVCRT__CONTROL, locale );
149 }
150
151 /*********************************************************************
152  *              iscntrl (MSVCRT.@)
153  */
154 int CDECL MSVCRT_iscntrl(int c)
155 {
156   return MSVCRT__isctype( c, MSVCRT__CONTROL );
157 }
158
159 /*********************************************************************
160  *              _isdigit_l (MSVCRT.@)
161  */
162 int CDECL MSVCRT__isdigit_l(int c, MSVCRT__locale_t locale)
163 {
164   return MSVCRT__isctype_l( c, MSVCRT__DIGIT, locale );
165 }
166
167 /*********************************************************************
168  *              isdigit (MSVCRT.@)
169  */
170 int CDECL MSVCRT_isdigit(int c)
171 {
172   return MSVCRT__isctype( c, MSVCRT__DIGIT );
173 }
174
175 /*********************************************************************
176  *              _isgraph_l (MSVCRT.@)
177  */
178 int CDECL MSVCRT__isgraph_l(int c, MSVCRT__locale_t locale)
179 {
180   return MSVCRT__isctype_l( c, MSVCRT__ALPHA | MSVCRT__DIGIT | MSVCRT__PUNCT, locale );
181 }
182
183 /*********************************************************************
184  *              isgraph (MSVCRT.@)
185  */
186 int CDECL MSVCRT_isgraph(int c)
187 {
188   return MSVCRT__isctype( c, MSVCRT__ALPHA | MSVCRT__DIGIT | MSVCRT__PUNCT );
189 }
190
191 /*********************************************************************
192  *              _isleadbyte_l (MSVCRT.@)
193  */
194 int CDECL MSVCRT__isleadbyte_l(int c, MSVCRT__locale_t locale)
195 {
196   return MSVCRT__isctype_l( c, MSVCRT__LEADBYTE, locale );
197 }
198
199 /*********************************************************************
200  *              isleadbyte (MSVCRT.@)
201  */
202 int CDECL MSVCRT_isleadbyte(int c)
203 {
204   return MSVCRT__isctype( c, MSVCRT__LEADBYTE );
205 }
206
207 /*********************************************************************
208  *              _islower_l (MSVCRT.@)
209  */
210 int CDECL MSVCRT__islower_l(int c, MSVCRT__locale_t locale)
211 {
212   return MSVCRT__isctype_l( c, MSVCRT__LOWER, locale );
213 }
214
215 /*********************************************************************
216  *              islower (MSVCRT.@)
217  */
218 int CDECL MSVCRT_islower(int c)
219 {
220   return MSVCRT__isctype( c, MSVCRT__LOWER );
221 }
222
223 /*********************************************************************
224  *              _isprint_l (MSVCRT.@)
225  */
226 int CDECL MSVCRT__isprint_l(int c, MSVCRT__locale_t locale)
227 {
228   return MSVCRT__isctype_l( c, MSVCRT__ALPHA | MSVCRT__DIGIT | MSVCRT__BLANK | MSVCRT__PUNCT, locale );
229 }
230
231 /*********************************************************************
232  *              isprint (MSVCRT.@)
233  */
234 int CDECL MSVCRT_isprint(int c)
235 {
236   return MSVCRT__isctype( c, MSVCRT__ALPHA | MSVCRT__DIGIT | MSVCRT__BLANK | MSVCRT__PUNCT );
237 }
238
239 /*********************************************************************
240  *              ispunct (MSVCRT.@)
241  */
242 int CDECL MSVCRT_ispunct(int c)
243 {
244   return MSVCRT__isctype( c, MSVCRT__PUNCT );
245 }
246
247 /*********************************************************************
248  *              _isspace_l (MSVCRT.@)
249  */
250 int CDECL MSVCRT__isspace_l(int c, MSVCRT__locale_t locale)
251 {
252   return MSVCRT__isctype_l( c, MSVCRT__SPACE, locale );
253 }
254
255 /*********************************************************************
256  *              isspace (MSVCRT.@)
257  */
258 int CDECL MSVCRT_isspace(int c)
259 {
260   return MSVCRT__isctype( c, MSVCRT__SPACE );
261 }
262
263 /*********************************************************************
264  *              _isupper_l (MSVCRT.@)
265  */
266 int CDECL MSVCRT__isupper_l(int c, MSVCRT__locale_t locale)
267 {
268   return MSVCRT__isctype_l( c, MSVCRT__UPPER, locale );
269 }
270
271 /*********************************************************************
272  *              isupper (MSVCRT.@)
273  */
274 int CDECL MSVCRT_isupper(int c)
275 {
276   return MSVCRT__isctype( c, MSVCRT__UPPER );
277 }
278
279 /*********************************************************************
280  *              _isxdigit_l (MSVCRT.@)
281  */
282 int CDECL MSVCRT__isxdigit_l(int c, MSVCRT__locale_t locale)
283 {
284   return MSVCRT__isctype_l( c, MSVCRT__HEX, locale );
285 }
286
287 /*********************************************************************
288  *              isxdigit (MSVCRT.@)
289  */
290 int CDECL MSVCRT_isxdigit(int c)
291 {
292   return MSVCRT__isctype( c, MSVCRT__HEX );
293 }
294
295 /*********************************************************************
296  *              __isascii (MSVCRT.@)
297  */
298 int CDECL MSVCRT___isascii(int c)
299 {
300   return isascii((unsigned)c);
301 }
302
303 /*********************************************************************
304  *              __toascii (MSVCRT.@)
305  */
306 int CDECL MSVCRT___toascii(int c)
307 {
308   return (unsigned)c & 0x7f;
309 }
310
311 /*********************************************************************
312  *              iswascii (MSVCRT.@)
313  *
314  */
315 int CDECL MSVCRT_iswascii(MSVCRT_wchar_t c)
316 {
317   return ((unsigned)c < 0x80);
318 }
319
320 /*********************************************************************
321  *              __iscsym (MSVCRT.@)
322  */
323 int CDECL MSVCRT___iscsym(int c)
324 {
325   return (c < 127 && (isalnum(c) || c == '_'));
326 }
327
328 /*********************************************************************
329  *              __iscsymf (MSVCRT.@)
330  */
331 int CDECL MSVCRT___iscsymf(int c)
332 {
333   return (c < 127 && (isalpha(c) || c == '_'));
334 }
335
336 /*********************************************************************
337  *              _toupper_l (MSVCRT.@)
338  */
339 int CDECL MSVCRT__toupper_l(int c, MSVCRT__locale_t locale)
340 {
341     MSVCRT_pthreadlocinfo locinfo;
342
343     if(!locale)
344         locinfo = get_locinfo();
345     else
346         locinfo = locale->locinfo;
347
348     if(c < 256)
349         return locinfo->pcumap[(unsigned char)c];
350
351     if(locinfo->pctype[(c>>8)&255] & MSVCRT__LEADBYTE)
352     {
353         WCHAR wide, upper;
354         char str[2], *p = str;
355         *p++ = (c>>8) & 255;
356         *p++ = c & 255;
357
358         if(!MultiByteToWideChar(locinfo->lc_codepage,
359                     MB_ERR_INVALID_CHARS, str, 2, &wide, 1))
360             return c;
361
362         upper = toupperW(wide);
363         if(upper == wide)
364             return c;
365
366         WideCharToMultiByte(locinfo->lc_codepage, 0,
367                 &upper, 1, str, 2, NULL, NULL);
368
369         return str[0] + (str[1]<<8);
370     }
371
372     return c;
373 }
374
375 /*********************************************************************
376  *              toupper (MSVCRT.@)
377  */
378 int CDECL MSVCRT_toupper(int c)
379 {
380     return MSVCRT__toupper_l(c, NULL);
381 }
382
383 /*********************************************************************
384  *              _toupper (MSVCRT.@)
385  */
386 int CDECL MSVCRT__toupper(int c)
387 {
388     return c - 0x20;  /* sic */
389 }
390
391 /*********************************************************************
392  *              _tolower_l (MSVCRT.@)
393  */
394 int CDECL MSVCRT__tolower_l(int c, MSVCRT__locale_t locale)
395 {
396     MSVCRT_pthreadlocinfo locinfo;
397
398     if(!locale)
399         locinfo = get_locinfo();
400     else
401         locinfo = locale->locinfo;
402
403     if(c < 256)
404         return locinfo->pclmap[(unsigned char)c];
405
406     if(locinfo->pctype[(c>>8)&255] & MSVCRT__LEADBYTE)
407     {
408         WCHAR wide, upper;
409         char str[2], *p = str;
410         *p++ = (c>>8) & 255;
411         *p++ = c & 255;
412
413         if(!MultiByteToWideChar(locinfo->lc_codepage,
414                     MB_ERR_INVALID_CHARS, str, 2, &wide, 1))
415             return c;
416
417         upper = tolowerW(wide);
418         if(upper == wide)
419             return c;
420
421         WideCharToMultiByte(locinfo->lc_codepage, 0,
422                 &upper, 1, str, 2, NULL, NULL);
423
424         return str[0] + (str[1]<<8);
425     }
426
427     return c;
428 }
429
430 /*********************************************************************
431  *              tolower (MSVCRT.@)
432  */
433 int CDECL MSVCRT_tolower(int c)
434 {
435         return MSVCRT__tolower_l(c, NULL);
436 }
437
438 /*********************************************************************
439  *              _tolower (MSVCRT.@)
440  */
441 int CDECL MSVCRT__tolower(int c)
442 {
443     return c + 0x20;  /* sic */
444 }