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
)
400 return c
== '\t' || _isctype_l( c
, _BLANK
, locale
);
403 /*********************************************************************
406 int CDECL
isblank(int c
)
408 return c
== '\t' || _isctype( c
, _BLANK
);
411 /*********************************************************************
412 * __isascii (MSVCRT.@)
414 int CDECL
__isascii(int c
)
416 return ((unsigned)c
< 0x80);
419 /*********************************************************************
420 * __toascii (MSVCRT.@)
422 int CDECL
__toascii(int c
)
424 return (unsigned)c
& 0x7f;
427 /*********************************************************************
428 * iswascii (MSVCRT.@)
431 int CDECL
iswascii(wchar_t c
)
433 return ((unsigned)c
< 0x80);
436 /*********************************************************************
437 * __iscsym (MSVCRT.@)
439 int CDECL
__iscsym(int c
)
441 return (c
< 127 && (isalnum(c
) || c
== '_'));
444 /*********************************************************************
445 * __iscsymf (MSVCRT.@)
447 int CDECL
__iscsymf(int c
)
449 return (c
< 127 && (isalpha(c
) || c
== '_'));
452 /*********************************************************************
453 * _toupper_l (MSVCRT.@)
455 int CDECL
_toupper_l(int c
, _locale_t locale
)
457 pthreadlocinfo locinfo
;
458 unsigned char str
[2], *p
= str
, ret
[2];
461 locinfo
= get_locinfo();
463 locinfo
= locale
->locinfo
;
465 if((unsigned)c
< 256)
466 return locinfo
->pcumap
[c
];
468 if(locinfo
->pctype
[(c
>>8)&255] & _LEADBYTE
)
476 switch(__crtLCMapStringA(locinfo
->lc_handle
[LC_CTYPE
], LCMAP_UPPERCASE
,
477 (char*)str
, p
-str
, (char*)ret
, 2, locinfo
->lc_codepage
, 0))
484 return ret
[0] + (ret
[1]<<8);
488 /*********************************************************************
491 int CDECL
toupper(int c
)
494 return c
>='a' && c
<='z' ? c
-'a'+'A' : c
;
495 return _toupper_l(c
, NULL
);
498 /*********************************************************************
499 * _toupper (MSVCRT.@)
501 int CDECL
_toupper(int c
)
503 return c
- 0x20; /* sic */
506 /*********************************************************************
507 * _tolower_l (MSVCRT.@)
509 int CDECL
_tolower_l(int c
, _locale_t locale
)
511 pthreadlocinfo locinfo
;
512 unsigned char str
[2], *p
= str
, ret
[2];
515 locinfo
= get_locinfo();
517 locinfo
= locale
->locinfo
;
519 if((unsigned)c
< 256)
520 return locinfo
->pclmap
[c
];
522 if(locinfo
->pctype
[(c
>>8)&255] & _LEADBYTE
)
530 switch(__crtLCMapStringA(locinfo
->lc_handle
[LC_CTYPE
], LCMAP_LOWERCASE
,
531 (char*)str
, p
-str
, (char*)ret
, 2, locinfo
->lc_codepage
, 0))
538 return ret
[0] + (ret
[1]<<8);
542 /*********************************************************************
545 int CDECL
tolower(int c
)
548 return c
>='A' && c
<='Z' ? c
-'A'+'a' : c
;
549 return _tolower_l(c
, NULL
);
552 /*********************************************************************
553 * _tolower (MSVCRT.@)
555 int CDECL
_tolower(int c
)
557 return c
+ 0x20; /* sic */
561 /*********************************************************************
562 * wctype (MSVCR120.@)
564 unsigned short __cdecl
wctype(const char *property
)
566 static const struct {
570 { "alnum", _DIGIT
|_ALPHA
},
572 { "cntrl", _CONTROL
},
574 { "graph", _DIGIT
|_PUNCT
|_ALPHA
},
576 { "print", _DIGIT
|_PUNCT
|_BLANK
|_ALPHA
},
584 for(i
=0; i
<ARRAY_SIZE(properties
); i
++)
585 if(!strcmp(property
, properties
[i
].name
))
586 return properties
[i
].mask
;