xref: /freebsd/include/xlocale/_ctype.h (revision 06c3fb27)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2011 The FreeBSD Foundation
5  *
6  * This software was developed by David Chisnall under sponsorship from
7  * the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 
32 #if	(defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \
33 	(!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H))
34 
35 #ifdef _XLOCALE_WCTYPES
36 #define _XLOCALE_WCTYPE_H
37 #else
38 #define _XLOCALE_CTYPE_H
39 #endif
40 
41 #ifndef _LOCALE_T_DEFINED
42 #define _LOCALE_T_DEFINED
43 typedef struct	_xlocale *locale_t;
44 #endif
45 
46 #ifndef _XLOCALE_RUN_FUNCTIONS_DEFINED
47 #define _XLOCALE_RUN_FUNCTIONS_DEFINED 1
48 unsigned long	 ___runetype_l(__ct_rune_t, locale_t) __pure;
49 __ct_rune_t	 ___tolower_l(__ct_rune_t, locale_t) __pure;
50 __ct_rune_t	 ___toupper_l(__ct_rune_t, locale_t) __pure;
51 _RuneLocale	*__runes_for_locale(locale_t, int*);
52 #endif
53 
54 #ifndef _XLOCALE_INLINE
55 #if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__)
56 /* GNU89 inline has nonstandard semantics. */
57 #define _XLOCALE_INLINE extern __inline
58 #else
59 /* Hack to work around people who define inline away */
60 #ifdef inline
61 #define _XLOCALE_INLINE static __inline
62 #else
63 /* Define with C++ / C99 compatible semantics */
64 #define _XLOCALE_INLINE inline
65 #endif
66 #endif
67 #endif /* _XLOCALE_INLINE */
68 
69 #ifdef _XLOCALE_WCTYPES
70 _XLOCALE_INLINE int
71 __maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
72 _XLOCALE_INLINE int
73 __istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
74 
75 _XLOCALE_INLINE int
76 __maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
77 {
78 	int __limit;
79 	_RuneLocale *runes = __runes_for_locale(__loc, &__limit);
80 	return ((__c < 0 || __c >= _CACHED_RUNES) ? ___runetype_l(__c, __loc) :
81 	        runes->__runetype[__c]) & __f;
82 }
83 
84 _XLOCALE_INLINE int
85 __istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
86 {
87 	return (!!__maskrune_l(__c, __f, __loc));
88 }
89 
90 #define XLOCALE_ISCTYPE(fname, cat) \
91 		_XLOCALE_INLINE int isw##fname##_l(int, locale_t);\
92 		_XLOCALE_INLINE int isw##fname##_l(int __c, locale_t __l)\
93 		{ return __istype_l(__c, cat, __l); }
94 #else
95 _XLOCALE_INLINE int
96 __sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
97 _XLOCALE_INLINE int
98 __sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
99 
100 _XLOCALE_INLINE int
101 __sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
102 {
103 	int __limit;
104 	_RuneLocale *runes = __runes_for_locale(__loc, &__limit);
105 	return (__c < 0 || __c >= __limit) ? 0 :
106 	       runes->__runetype[__c] & __f;
107 }
108 
109 _XLOCALE_INLINE int
110 __sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
111 {
112 	return (!!__sbmaskrune_l(__c, __f, __loc));
113 }
114 
115 #define XLOCALE_ISCTYPE(__fname, __cat) \
116 		_XLOCALE_INLINE int is##__fname##_l(int, locale_t); \
117 		_XLOCALE_INLINE int is##__fname##_l(int __c, locale_t __l)\
118 		{ return __sbistype_l(__c, __cat, __l); }
119 #endif
120 
121 XLOCALE_ISCTYPE(alnum, _CTYPE_A|_CTYPE_D|_CTYPE_N)
122 XLOCALE_ISCTYPE(alpha, _CTYPE_A)
123 XLOCALE_ISCTYPE(blank, _CTYPE_B)
124 XLOCALE_ISCTYPE(cntrl, _CTYPE_C)
125 XLOCALE_ISCTYPE(digit, _CTYPE_D)
126 XLOCALE_ISCTYPE(graph, _CTYPE_G)
127 XLOCALE_ISCTYPE(hexnumber, _CTYPE_X)
128 XLOCALE_ISCTYPE(ideogram, _CTYPE_I)
129 XLOCALE_ISCTYPE(lower, _CTYPE_L)
130 XLOCALE_ISCTYPE(number, _CTYPE_D|_CTYPE_N)
131 XLOCALE_ISCTYPE(phonogram, _CTYPE_Q)
132 XLOCALE_ISCTYPE(print, _CTYPE_R)
133 XLOCALE_ISCTYPE(punct, _CTYPE_P)
134 XLOCALE_ISCTYPE(rune, 0xFFFFFF00L)
135 XLOCALE_ISCTYPE(space, _CTYPE_S)
136 XLOCALE_ISCTYPE(special, _CTYPE_T)
137 XLOCALE_ISCTYPE(upper, _CTYPE_U)
138 XLOCALE_ISCTYPE(xdigit, _CTYPE_X)
139 #undef XLOCALE_ISCTYPE
140 
141 #ifdef _XLOCALE_WCTYPES
142 _XLOCALE_INLINE int towlower_l(int, locale_t);
143 _XLOCALE_INLINE int __wcwidth_l(__ct_rune_t, locale_t);
144 _XLOCALE_INLINE int towupper_l(int, locale_t);
145 
146 _XLOCALE_INLINE int towlower_l(int __c, locale_t __l)
147 {
148 	int __limit;
149 	_RuneLocale *__runes = __runes_for_locale(__l, &__limit);
150 	return (__c < 0 || __c >= _CACHED_RUNES) ? ___tolower_l(__c, __l) :
151 	       __runes->__maplower[__c];
152 }
153 _XLOCALE_INLINE int towupper_l(int __c, locale_t __l)
154 {
155 	int __limit;
156 	_RuneLocale *__runes = __runes_for_locale(__l, &__limit);
157 	return (__c < 0 || __c >= _CACHED_RUNES) ? ___toupper_l(__c, __l) :
158 	       __runes->__mapupper[__c];
159 }
160 _XLOCALE_INLINE int
161 __wcwidth_l(__ct_rune_t _c, locale_t __l)
162 {
163 	unsigned int _x;
164 
165 	if (_c == 0)
166 		return (0);
167 	_x = (unsigned int)__maskrune_l(_c, _CTYPE_SWM|_CTYPE_R, __l);
168 	if ((_x & _CTYPE_SWM) != 0)
169 		return ((_x & _CTYPE_SWM) >> _CTYPE_SWS);
170 	return ((_x & _CTYPE_R) != 0 ? 1 : -1);
171 }
172 int iswctype_l(wint_t __wc, wctype_t __charclass, locale_t __l);
173 wctype_t wctype_l(const char *property, locale_t __l);
174 wint_t towctrans_l(wint_t __wc, wctrans_t desc, locale_t __l);
175 wint_t nextwctype_l(wint_t __wc, wctype_t wct, locale_t __l);
176 wctrans_t wctrans_l(const char *__charclass, locale_t __l);
177 #undef _XLOCALE_WCTYPES
178 #else
179 _XLOCALE_INLINE int digittoint_l(int, locale_t);
180 _XLOCALE_INLINE int tolower_l(int, locale_t);
181 _XLOCALE_INLINE int toupper_l(int, locale_t);
182 
183 _XLOCALE_INLINE int digittoint_l(int __c, locale_t __l)
184 { return __sbmaskrune_l((__c), 0xFF, __l); }
185 
186 _XLOCALE_INLINE int tolower_l(int __c, locale_t __l)
187 {
188 	int __limit;
189 	_RuneLocale *__runes = __runes_for_locale(__l, &__limit);
190 	return (__c < 0 || __c >= __limit) ? __c :
191 	       __runes->__maplower[__c];
192 }
193 _XLOCALE_INLINE int toupper_l(int __c, locale_t __l)
194 {
195 	int __limit;
196 	_RuneLocale *__runes = __runes_for_locale(__l, &__limit);
197 	return (__c < 0 || __c >= __limit) ? __c :
198 	       __runes->__mapupper[__c];
199 }
200 #endif
201 #endif /* (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \
202 	(!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H)) */
203