1/*	$OpenBSD: iswctype.c,v 1.9 2024/02/04 12:46:01 jca Exp $ */
2/*	$NetBSD: iswctype.c,v 1.15 2005/02/09 21:35:46 kleink Exp $	*/
3
4/*
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
7 * (c) UNIX System Laboratories, Inc.
8 * All or some portions of this file are derived from material licensed
9 * to the University of California by American Telephone and Telegraph
10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11 * the permission of UNIX System Laboratories, Inc.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38#include <wchar.h>
39#include <wctype.h>
40#include <ctype.h>
41#include <errno.h>
42#include <string.h>
43#include "rune.h"
44#include "runetype.h"
45#include "rune_local.h"
46#include "_wctrans_local.h"
47
48static inline _RuneType __runetype_w(wint_t);
49static inline int __isctype_w(wint_t, _RuneType);
50static inline wint_t __toupper_w(wint_t);
51static inline wint_t __tolower_w(wint_t);
52
53static inline _RuneType
54__runetype_w(wint_t c)
55{
56	_RuneLocale *rl = _CurrentRuneLocale();
57
58	return (_RUNE_ISCACHED(c) ?
59		rl->rl_runetype[c] : ___runetype_mb(c, rl));
60}
61
62static inline int
63__isctype_w(wint_t c, _RuneType f)
64{
65	return (!!(__runetype_w(c) & f));
66}
67
68static inline wint_t
69__toupper_w(wint_t c)
70{
71	return (_towctrans(c, _wctrans_upper(_CurrentRuneLocale())));
72}
73
74static inline wint_t
75__tolower_w(wint_t c)
76{
77	return (_towctrans(c, _wctrans_lower(_CurrentRuneLocale())));
78}
79
80int
81iswalnum(wint_t c)
82{
83	return (__isctype_w((c), _RUNETYPE_A|_RUNETYPE_D));
84}
85
86int
87iswalpha(wint_t c)
88{
89	return (__isctype_w((c), _RUNETYPE_A));
90}
91
92int
93iswblank(wint_t c)
94{
95	return (__isctype_w((c), _RUNETYPE_B));
96}
97
98int
99iswcntrl(wint_t c)
100{
101	return (__isctype_w((c), _RUNETYPE_C));
102}
103
104int
105iswdigit(wint_t c)
106{
107	return (__isctype_w((c), _RUNETYPE_D));
108}
109
110int
111iswgraph(wint_t c)
112{
113	return (__isctype_w((c), _RUNETYPE_G));
114}
115
116int
117iswlower(wint_t c)
118{
119	return (__isctype_w((c), _RUNETYPE_L));
120}
121
122int
123iswprint(wint_t c)
124{
125	return (__isctype_w((c), _RUNETYPE_R));
126}
127
128int
129iswpunct(wint_t c)
130{
131	return (__isctype_w((c), _RUNETYPE_P));
132}
133
134int
135iswspace(wint_t c)
136{
137	return (__isctype_w((c), _RUNETYPE_S));
138}
139DEF_STRONG(iswspace);
140
141int
142iswupper(wint_t c)
143{
144	return (__isctype_w((c), _RUNETYPE_U));
145}
146DEF_STRONG(iswupper);
147
148int
149iswxdigit(wint_t c)
150{
151	return (__isctype_w((c), _RUNETYPE_X));
152}
153
154wint_t
155towupper(wint_t c)
156{
157	return (__toupper_w(c));
158}
159
160wint_t
161towlower(wint_t c)
162{
163	return (__tolower_w(c));
164}
165DEF_STRONG(towlower);
166
167int
168wcwidth(wchar_t c)
169{
170	if (__isctype_w((c), _RUNETYPE_R))
171		return (((unsigned)__runetype_w(c) & _RUNETYPE_SWM) >>
172		    _RUNETYPE_SWS);
173	return -1;
174}
175DEF_WEAK(wcwidth);
176
177wctrans_t
178wctrans(const char *charclass)
179{
180	int i;
181	_RuneLocale *rl = _CurrentRuneLocale();
182
183	if (rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_name==NULL)
184		_wctrans_init(rl);
185
186	for (i=0; i<_WCTRANS_NINDEXES; i++)
187		if (!strcmp(rl->rl_wctrans[i].te_name, charclass))
188			return ((wctrans_t)&rl->rl_wctrans[i]);
189
190	return ((wctrans_t)NULL);
191}
192
193wint_t
194towctrans(wint_t c, wctrans_t desc)
195{
196	if (desc==NULL) {
197		errno = EINVAL;
198		return (c);
199	}
200	return (_towctrans(c, (_WCTransEntry *)desc));
201}
202DEF_STRONG(towctrans);
203
204int
205iswctype(wint_t c, wctype_t charclass)
206{
207
208	/*
209	 * SUSv3: If charclass is 0, iswctype() shall return 0.
210	 */
211	if (charclass == (wctype_t)0) {
212		return 0;
213	}
214
215	return (__isctype_w(c, ((_WCTypeEntry *)charclass)->te_mask));
216}
217