2 * msvcrt.dll ctype functions
4 * Copyright 2000 Jon Griffiths
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.
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.
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
25 /* Some abbreviations to make the following table readable */
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_
|_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
68 # define L140 _LOWER | 0x100
69 # define C140 _CONTROL
75 WORD MSVCRT__wctype
[257] =
79 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
80 0x0020, 0x0028 | B110
, 0x0028, 0x0028, 0x0028, 0x0028, 0x0020, 0x0020,
82 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
83 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
85 0x0048, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
86 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
88 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084,
89 0x0084, 0x0084, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
91 0x0010, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0101,
92 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
94 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
95 0x0101, 0x0101, 0x0101, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
97 0x0010, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0102,
98 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
100 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
101 0x0102, 0x0102, 0x0102, 0x0010, 0x0010, 0x0010, 0x0010, 0x0020,
103 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 | S140
, 0x0020, 0x0020,
104 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
106 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
107 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
109 0x0008 | B110
, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
110 0x0010, 0x0010, 0x0010 | L140
, 0x0010, 0x0010, 0x0010 | C140
, 0x0010, 0x0010,
112 0x0010, 0x0010, 0x0010 | D120
, 0x0010 | D120
, 0x0010, 0x0010 | L140
, 0x0010, 0x0010,
113 0x0010, 0x0010 | D120
, 0x0010 | L140
, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
115 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
116 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
118 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0010,
119 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0102,
121 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
122 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
124 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0010,
125 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102
128 WORD
*MSVCRT__pwctype
= MSVCRT__wctype
+ 1;
130 /*********************************************************************
131 * __p__pctype (MSVCRT.@)
133 unsigned short** CDECL
__p__pctype(void)
135 return &get_locinfo()->pctype
;
138 /*********************************************************************
139 * __pctype_func (MSVCRT.@)
141 const unsigned short* CDECL
__pctype_func(void)
143 return get_locinfo()->pctype
;
146 /*********************************************************************
147 * __p__pwctype (MSVCRT.@)
149 unsigned short** CDECL
__p__pwctype(void)
151 return &MSVCRT__pwctype
;
154 /*********************************************************************
155 * __pwctype_func (MSVCRT.@)
157 const unsigned short* CDECL
__pwctype_func(void)
159 return MSVCRT__pwctype
;
162 /*********************************************************************
163 * _isctype_l (MSVCRT.@)
165 int CDECL
_isctype_l(int c
, int type
, _locale_t locale
)
167 pthreadlocinfo locinfo
;
170 locinfo
= get_locinfo();
172 locinfo
= locale
->locinfo
;
174 if (c
>= -1 && c
<= 255)
175 return locinfo
->pctype
[c
] & type
;
177 if (locinfo
->mb_cur_max
!= 1 && c
> 0)
179 /* FIXME: Is there a faster way to do this? */
181 char convert
[3], *pconv
= convert
;
183 if (locinfo
->pctype
[(UINT
)c
>> 8] & _LEADBYTE
)
184 *pconv
++ = (UINT
)c
>> 8;
188 if (GetStringTypeExA(locinfo
->lc_handle
[LC_CTYPE
],
189 CT_CTYPE1
, convert
, convert
[1] ? 2 : 1, &typeInfo
))
190 return typeInfo
& type
;
195 /*********************************************************************
196 * _isctype (MSVCRT.@)
198 int CDECL
_isctype(int c
, int type
)
200 return _isctype_l(c
, type
, NULL
);
203 /*********************************************************************
204 * _isalnum_l (MSVCRT.@)
206 int CDECL
_isalnum_l(int c
, _locale_t locale
)
208 return _isctype_l( c
, _ALPHA
| _DIGIT
, locale
);
211 /*********************************************************************
214 int CDECL
isalnum(int c
)
216 return _isctype( c
, _ALPHA
| _DIGIT
);
219 /*********************************************************************
220 * _isalpha_l (MSVCRT.@)
222 int CDECL
_isalpha_l(int c
, _locale_t locale
)
224 return _isctype_l( c
, _ALPHA
, locale
);
227 /*********************************************************************
230 int CDECL
isalpha(int c
)
232 return _isctype( c
, _ALPHA
);
235 /*********************************************************************
236 * _iscntrl_l (MSVCRT.@)
238 int CDECL
_iscntrl_l(int c
, _locale_t locale
)
240 return _isctype_l( c
, _CONTROL
, locale
);
243 /*********************************************************************
246 int CDECL
iscntrl(int c
)
248 return _isctype( c
, _CONTROL
);
251 /*********************************************************************
252 * _isdigit_l (MSVCRT.@)
254 int CDECL
_isdigit_l(int c
, _locale_t locale
)
256 return _isctype_l( c
, _DIGIT
, locale
);
259 /*********************************************************************
262 int CDECL
isdigit(int c
)
264 return _isctype( c
, _DIGIT
);
267 /*********************************************************************
268 * _isgraph_l (MSVCRT.@)
270 int CDECL
_isgraph_l(int c
, _locale_t locale
)
272 return _isctype_l( c
, _ALPHA
| _DIGIT
| _PUNCT
, locale
);
275 /*********************************************************************
278 int CDECL
isgraph(int c
)
280 return _isctype( c
, _ALPHA
| _DIGIT
| _PUNCT
);
283 /*********************************************************************
284 * _isleadbyte_l (MSVCRT.@)
286 int CDECL
_isleadbyte_l(int c
, _locale_t locale
)
288 return _isctype_l( c
, _LEADBYTE
, locale
);
291 /*********************************************************************
292 * isleadbyte (MSVCRT.@)
294 int CDECL
isleadbyte(int c
)
296 return _isctype( c
, _LEADBYTE
);
299 /*********************************************************************
300 * _islower_l (MSVCRT.@)
302 int CDECL
_islower_l(int c
, _locale_t locale
)
304 return _isctype_l( c
, _LOWER
, locale
);
307 /*********************************************************************
310 int CDECL
islower(int c
)
312 return _isctype( c
, _LOWER
);
315 /*********************************************************************
316 * _isprint_l (MSVCRT.@)
318 int CDECL
_isprint_l(int c
, _locale_t locale
)
320 return _isctype_l( c
, _ALPHA
| _DIGIT
| _BLANK
| _PUNCT
, locale
);
323 /*********************************************************************
326 int CDECL
isprint(int c
)
328 return _isctype( c
, _ALPHA
| _DIGIT
| _BLANK
| _PUNCT
);
331 /*********************************************************************
334 int CDECL
ispunct(int c
)
336 return _isctype( c
, _PUNCT
);
339 /*********************************************************************
340 * _ispunct_l (MSVCR80.@)
342 int CDECL
_ispunct_l(int c
, _locale_t locale
)
344 return _isctype_l( c
, _PUNCT
, locale
);
347 /*********************************************************************
348 * _isspace_l (MSVCRT.@)
350 int CDECL
_isspace_l(int c
, _locale_t locale
)
352 return _isctype_l( c
, _SPACE
, locale
);
355 /*********************************************************************
358 int CDECL
isspace(int c
)
360 return _isctype( c
, _SPACE
);
363 /*********************************************************************
364 * _isupper_l (MSVCRT.@)
366 int CDECL
_isupper_l(int c
, _locale_t locale
)
368 return _isctype_l( c
, _UPPER
, locale
);
371 /*********************************************************************
374 int CDECL
isupper(int c
)
376 return _isctype( c
, _UPPER
);
379 /*********************************************************************
380 * _isxdigit_l (MSVCRT.@)
382 int CDECL
_isxdigit_l(int c
, _locale_t locale
)
384 return _isctype_l( c
, _HEX
, locale
);
387 /*********************************************************************
388 * isxdigit (MSVCRT.@)
390 int CDECL
isxdigit(int c
)
392 return _isctype( c
, _HEX
);
395 /*********************************************************************
396 * _isblank_l (MSVCRT.@)
398 int CDECL
_isblank_l(int c
, _locale_t locale
)
401 if (c
== '\t') return _BLANK
;
403 return _isctype_l( c
, _BLANK
, locale
);
406 /*********************************************************************
409 int CDECL
isblank(int c
)
411 return c
== '\t' || _isctype( c
, _BLANK
);
414 /*********************************************************************
415 * __isascii (MSVCRT.@)
417 int CDECL
__isascii(int c
)
419 return ((unsigned)c
< 0x80);
422 /*********************************************************************
423 * __toascii (MSVCRT.@)
425 int CDECL
__toascii(int c
)
427 return (unsigned)c
& 0x7f;
430 /*********************************************************************
431 * iswascii (MSVCRT.@)
434 int CDECL
iswascii(wchar_t c
)
436 return ((unsigned)c
< 0x80);
439 /*********************************************************************
440 * __iscsym (MSVCRT.@)
442 int CDECL
__iscsym(int c
)
444 return (c
< 127 && (isalnum(c
) || c
== '_'));
447 /*********************************************************************
448 * __iscsymf (MSVCRT.@)
450 int CDECL
__iscsymf(int c
)
452 return (c
< 127 && (isalpha(c
) || c
== '_'));
455 /*********************************************************************
456 * _toupper_l (MSVCRT.@)
458 int CDECL
_toupper_l(int c
, _locale_t locale
)
460 pthreadlocinfo locinfo
;
461 unsigned char str
[2], *p
= str
, ret
[2];
464 locinfo
= get_locinfo();
466 locinfo
= locale
->locinfo
;
468 if((unsigned)c
< 256)
469 return locinfo
->pcumap
[c
];
471 if(locinfo
->pctype
[(c
>>8)&255] & _LEADBYTE
)
479 switch(__crtLCMapStringA(locinfo
->lc_handle
[LC_CTYPE
], LCMAP_UPPERCASE
,
480 (char*)str
, p
-str
, (char*)ret
, 2, locinfo
->lc_codepage
, 0))
487 return ret
[0] + (ret
[1]<<8);
491 /*********************************************************************
494 int CDECL
toupper(int c
)
497 return c
>='a' && c
<='z' ? c
-'a'+'A' : c
;
498 return _toupper_l(c
, NULL
);
501 /*********************************************************************
502 * _toupper (MSVCRT.@)
504 int CDECL
_toupper(int c
)
506 return c
- 0x20; /* sic */
509 /*********************************************************************
510 * _tolower_l (MSVCRT.@)
512 int CDECL
_tolower_l(int c
, _locale_t locale
)
514 pthreadlocinfo locinfo
;
515 unsigned char str
[2], *p
= str
, ret
[2];
518 locinfo
= get_locinfo();
520 locinfo
= locale
->locinfo
;
522 if((unsigned)c
< 256)
523 return locinfo
->pclmap
[c
];
525 if(locinfo
->pctype
[(c
>>8)&255] & _LEADBYTE
)
533 switch(__crtLCMapStringA(locinfo
->lc_handle
[LC_CTYPE
], LCMAP_LOWERCASE
,
534 (char*)str
, p
-str
, (char*)ret
, 2, locinfo
->lc_codepage
, 0))
541 return ret
[0] + (ret
[1]<<8);
545 /*********************************************************************
548 int CDECL
tolower(int c
)
551 return c
>='A' && c
<='Z' ? c
-'A'+'a' : c
;
552 return _tolower_l(c
, NULL
);
555 /*********************************************************************
556 * _tolower (MSVCRT.@)
558 int CDECL
_tolower(int c
)
560 return c
+ 0x20; /* sic */
564 /*********************************************************************
565 * wctype (MSVCR120.@)
567 unsigned short __cdecl
wctype(const char *property
)
569 static const struct {
573 { "alnum", _DIGIT
|_ALPHA
},
575 { "cntrl", _CONTROL
},
577 { "graph", _DIGIT
|_PUNCT
|_ALPHA
},
579 { "print", _DIGIT
|_PUNCT
|_BLANK
|_ALPHA
},
587 for(i
=0; i
<ARRAY_SIZE(properties
); i
++)
588 if(!strcmp(property
, properties
[i
].name
))
589 return properties
[i
].mask
;