1231673Stheraven/*-
2231673Stheraven * Copyright (c) 2011 The FreeBSD Foundation
3231673Stheraven * All rights reserved.
4231673Stheraven *
5231673Stheraven * This software was developed by David Chisnall under sponsorship from
6231673Stheraven * the FreeBSD Foundation.
7231673Stheraven *
8231673Stheraven * Redistribution and use in source and binary forms, with or without
9231673Stheraven * modification, are permitted provided that the following conditions
10231673Stheraven * are met:
11231673Stheraven * 1. Redistributions of source code must retain the above copyright
12231673Stheraven *    notice, this list of conditions and the following disclaimer.
13231673Stheraven * 2. Redistributions in binary form must reproduce the above copyright
14231673Stheraven *    notice, this list of conditions and the following disclaimer in the
15231673Stheraven *    documentation and/or other materials provided with the distribution.
16231673Stheraven *
17231673Stheraven * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18231673Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19231673Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20231673Stheraven * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21231673Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22231673Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23231673Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24231673Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25231673Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26231673Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27231673Stheraven * SUCH DAMAGE.
28231673Stheraven *
29231673Stheraven * $FreeBSD$
30231673Stheraven */
31231673Stheraven
32231673Stheraven
33231673Stheraven#if	(defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \
34231673Stheraven	(!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H))
35231673Stheraven
36231673Stheraven#ifdef _XLOCALE_WCTYPES
37231673Stheraven#define _XLOCALE_WCTYPE_H
38231673Stheraven#else
39231673Stheraven#define _XLOCALE_CTYPE_H
40231673Stheraven#endif
41231673Stheraven
42231673Stheraven#ifndef _LOCALE_T_DEFINED
43231673Stheraven#define _LOCALE_T_DEFINED
44231673Stheraventypedef struct	_xlocale *locale_t;
45231673Stheraven#endif
46231673Stheraven
47232498Stheraven#ifndef _XLOCALE_RUN_FUNCTIONS_DEFINED
48232498Stheraven#define _XLOCALE_RUN_FUNCTIONS_DEFINED 1
49231673Stheravenunsigned long	 ___runetype_l(__ct_rune_t, locale_t) __pure;
50231673Stheraven__ct_rune_t	 ___tolower_l(__ct_rune_t, locale_t) __pure;
51231673Stheraven__ct_rune_t	 ___toupper_l(__ct_rune_t, locale_t) __pure;
52231673Stheraven_RuneLocale	*__runes_for_locale(locale_t, int*);
53231673Stheraven#endif
54231673Stheraven
55231673Stheraven#ifndef _XLOCALE_INLINE
56243032Sdemon#if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__)
57231673Stheraven/* GNU89 inline has nonstandard semantics. */
58232620Sdim#define _XLOCALE_INLINE extern __inline
59231673Stheraven#else
60231673Stheraven/* Hack to work around people who define inline away */
61231673Stheraven#ifdef inline
62232620Sdim#define _XLOCALE_INLINE static __inline
63231673Stheraven#else
64231673Stheraven/* Define with C++ / C99 compatible semantics */
65231673Stheraven#define _XLOCALE_INLINE inline
66231673Stheraven#endif
67231673Stheraven#endif
68231673Stheraven#endif /* _XLOCALE_INLINE */
69231673Stheraven
70231673Stheraven#ifdef _XLOCALE_WCTYPES
71232926Stheraven_XLOCALE_INLINE int
72232929Stheraven__maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
73232931Stheraven_XLOCALE_INLINE int
74232929Stheraven__istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
75232929Stheraven
76232929Stheraven_XLOCALE_INLINE int
77232926Stheraven__maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
78231673Stheraven{
79232926Stheraven	int __limit;
80232926Stheraven	_RuneLocale *runes = __runes_for_locale(__loc, &__limit);
81234573Stheraven	return ((__c < 0 || __c >= _CACHED_RUNES) ? ___runetype_l(__c, __loc) :
82234573Stheraven	        runes->__runetype[__c]) & __f;
83231673Stheraven}
84231673Stheraven
85232931Stheraven_XLOCALE_INLINE int
86232926Stheraven__istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
87231673Stheraven{
88232926Stheraven	return (!!__maskrune_l(__c, __f, __loc));
89231673Stheraven}
90231673Stheraven
91231673Stheraven#define XLOCALE_ISCTYPE(fname, cat) \
92232498Stheraven		_XLOCALE_INLINE int isw##fname##_l(int, locale_t);\
93232498Stheraven		_XLOCALE_INLINE int isw##fname##_l(int __c, locale_t __l)\
94232498Stheraven		{ return __istype_l(__c, cat, __l); }
95231673Stheraven#else
96232926Stheraven_XLOCALE_INLINE int
97232927Stheraven__sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
98232927Stheraven_XLOCALE_INLINE int
99232927Stheraven__sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc);
100232927Stheraven
101232927Stheraven_XLOCALE_INLINE int
102232926Stheraven__sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
103231673Stheraven{
104232926Stheraven	int __limit;
105232926Stheraven	_RuneLocale *runes = __runes_for_locale(__loc, &__limit);
106232926Stheraven	return (__c < 0 || __c >= __limit) ? 0 :
107232926Stheraven	       runes->__runetype[__c] & __f;
108231673Stheraven}
109231673Stheraven
110232926Stheraven_XLOCALE_INLINE int
111232926Stheraven__sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc)
112231673Stheraven{
113232926Stheraven	return (!!__sbmaskrune_l(__c, __f, __loc));
114231673Stheraven}
115231673Stheraven
116232926Stheraven#define XLOCALE_ISCTYPE(__fname, __cat) \
117232926Stheraven		_XLOCALE_INLINE int is##__fname##_l(int, locale_t); \
118232926Stheraven		_XLOCALE_INLINE int is##__fname##_l(int __c, locale_t __l)\
119232926Stheraven		{ return __sbistype_l(__c, __cat, __l); }
120231673Stheraven#endif
121231673Stheraven
122231673StheravenXLOCALE_ISCTYPE(alnum, _CTYPE_A|_CTYPE_D)
123231673StheravenXLOCALE_ISCTYPE(alpha, _CTYPE_A)
124231673StheravenXLOCALE_ISCTYPE(blank, _CTYPE_B)
125231673StheravenXLOCALE_ISCTYPE(cntrl, _CTYPE_C)
126231673StheravenXLOCALE_ISCTYPE(digit, _CTYPE_D)
127231673StheravenXLOCALE_ISCTYPE(graph, _CTYPE_G)
128231673StheravenXLOCALE_ISCTYPE(hexnumber, _CTYPE_X)
129231673StheravenXLOCALE_ISCTYPE(ideogram, _CTYPE_I)
130231673StheravenXLOCALE_ISCTYPE(lower, _CTYPE_L)
131231673StheravenXLOCALE_ISCTYPE(number, _CTYPE_D)
132231673StheravenXLOCALE_ISCTYPE(phonogram, _CTYPE_Q)
133231673StheravenXLOCALE_ISCTYPE(print, _CTYPE_R)
134231673StheravenXLOCALE_ISCTYPE(punct, _CTYPE_P)
135231673StheravenXLOCALE_ISCTYPE(rune, 0xFFFFFF00L)
136231673StheravenXLOCALE_ISCTYPE(space, _CTYPE_S)
137231673StheravenXLOCALE_ISCTYPE(special, _CTYPE_T)
138231673StheravenXLOCALE_ISCTYPE(upper, _CTYPE_U)
139231673StheravenXLOCALE_ISCTYPE(xdigit, _CTYPE_X)
140231673Stheraven#undef XLOCALE_ISCTYPE
141231673Stheraven
142231673Stheraven#ifdef _XLOCALE_WCTYPES
143232498Stheraven_XLOCALE_INLINE int towlower_l(int, locale_t);
144232498Stheraven_XLOCALE_INLINE int __wcwidth_l(__ct_rune_t, locale_t);
145232498Stheraven_XLOCALE_INLINE int towupper_l(int, locale_t);
146232498Stheraven
147232498Stheraven_XLOCALE_INLINE int towlower_l(int __c, locale_t __l)
148231673Stheraven{
149232926Stheraven	int __limit;
150232926Stheraven	_RuneLocale *__runes = __runes_for_locale(__l, &__limit);
151232498Stheraven	return (__c < 0 || __c >= _CACHED_RUNES) ? ___tolower_l(__c, __l) :
152232498Stheraven	       __runes->__maplower[__c];
153231673Stheraven}
154232498Stheraven_XLOCALE_INLINE int towupper_l(int __c, locale_t __l)
155231673Stheraven{
156232926Stheraven	int __limit;
157232926Stheraven	_RuneLocale *__runes = __runes_for_locale(__l, &__limit);
158232498Stheraven	return (__c < 0 || __c >= _CACHED_RUNES) ? ___toupper_l(__c, __l) :
159232498Stheraven	       __runes->__mapupper[__c];
160231673Stheraven}
161231673Stheraven_XLOCALE_INLINE int
162232498Stheraven__wcwidth_l(__ct_rune_t _c, locale_t __l)
163231673Stheraven{
164231673Stheraven	unsigned int _x;
165231673Stheraven
166231673Stheraven	if (_c == 0)
167231673Stheraven		return (0);
168232498Stheraven	_x = (unsigned int)__maskrune_l(_c, _CTYPE_SWM|_CTYPE_R, __l);
169231673Stheraven	if ((_x & _CTYPE_SWM) != 0)
170231673Stheraven		return ((_x & _CTYPE_SWM) >> _CTYPE_SWS);
171231673Stheraven	return ((_x & _CTYPE_R) != 0 ? 1 : -1);
172231673Stheraven}
173232498Stheravenint iswctype_l(wint_t __wc, wctype_t __charclass, locale_t __l);
174232498Stheravenwctype_t wctype_l(const char *property, locale_t __l);
175232498Stheravenwint_t towctrans_l(wint_t __wc, wctrans_t desc, locale_t __l);
176232498Stheravenwint_t nextwctype_l(wint_t __wc, wctype_t wct, locale_t __l);
177232498Stheravenwctrans_t wctrans_l(const char *__charclass, locale_t __l);
178231673Stheraven#undef _XLOCALE_WCTYPES
179231673Stheraven#else
180232498Stheraven_XLOCALE_INLINE int digittoint_l(int, locale_t);
181232498Stheraven_XLOCALE_INLINE int tolower_l(int, locale_t);
182232498Stheraven_XLOCALE_INLINE int toupper_l(int, locale_t);
183231673Stheraven
184232498Stheraven_XLOCALE_INLINE int digittoint_l(int __c, locale_t __l)
185232498Stheraven{ return __sbmaskrune_l((__c), 0xFF, __l); }
186232498Stheraven
187232498Stheraven_XLOCALE_INLINE int tolower_l(int __c, locale_t __l)
188231673Stheraven{
189232498Stheraven	int __limit;
190232498Stheraven	_RuneLocale *__runes = __runes_for_locale(__l, &__limit);
191232498Stheraven	return (__c < 0 || __c >= __limit) ? __c :
192232498Stheraven	       __runes->__maplower[__c];
193231673Stheraven}
194232498Stheraven_XLOCALE_INLINE int toupper_l(int __c, locale_t __l)
195231673Stheraven{
196232498Stheraven	int __limit;
197232498Stheraven	_RuneLocale *__runes = __runes_for_locale(__l, &__limit);
198232498Stheraven	return (__c < 0 || __c >= __limit) ? __c :
199232498Stheraven	       __runes->__mapupper[__c];
200231673Stheraven}
201231673Stheraven#endif
202231673Stheraven#endif /* (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \
203231673Stheraven	(!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H)) */
204