xref: /openbsd/lib/libc/locale/iswctype_l.c (revision 286f9c70)
1 /*	$OpenBSD: iswctype_l.c,v 1.3 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 <ctype.h>
39 #include <errno.h>
40 #include <locale.h>
41 #include <string.h>
42 #include <wchar.h>
43 #include <wctype.h>
44 
45 #include "rune.h"
46 #include "runetype.h"
47 #include "rune_local.h"
48 #include "_wctrans_local.h"
49 
50 static _RuneLocale	*__runelocale(locale_t);
51 static int		 __isctype_wl(wint_t, _RuneType, locale_t);
52 
53 /*
54  * For all these functions, POSIX says that behaviour is undefined
55  * for LC_GLOBAL_LOCALE and for invalid locale arguments.
56  * The choice made here is to use the C locale in that case.
57  */
58 static _RuneLocale *
__runelocale(locale_t locale)59 __runelocale(locale_t locale)
60 {
61 	_RuneLocale	*rl;
62 
63 	rl = NULL;
64 	if (locale == _LOCALE_UTF8)
65 		rl = _Utf8RuneLocale;
66 	if (rl == NULL)
67 		rl = &_DefaultRuneLocale;
68 	return rl;
69 }
70 
71 static int
__isctype_wl(wint_t c,_RuneType f,locale_t locale)72 __isctype_wl(wint_t c, _RuneType f, locale_t locale)
73 {
74 	_RuneLocale	*rl;
75 	_RuneType	 rt;
76 
77 	rl = __runelocale(locale);
78 	rt = _RUNE_ISCACHED(c) ? rl->rl_runetype[c] : ___runetype_mb(c, rl);
79 	return (rt & f) != 0;
80 }
81 
82 int
iswalnum_l(wint_t c,locale_t locale)83 iswalnum_l(wint_t c, locale_t locale)
84 {
85 	return __isctype_wl(c, _RUNETYPE_A|_RUNETYPE_D, locale);
86 }
87 
88 int
iswalpha_l(wint_t c,locale_t locale)89 iswalpha_l(wint_t c, locale_t locale)
90 {
91 	return __isctype_wl(c, _RUNETYPE_A, locale);
92 }
93 
94 int
iswblank_l(wint_t c,locale_t locale)95 iswblank_l(wint_t c, locale_t locale)
96 {
97 	return __isctype_wl(c, _RUNETYPE_B, locale);
98 }
99 
100 int
iswcntrl_l(wint_t c,locale_t locale)101 iswcntrl_l(wint_t c, locale_t locale)
102 {
103 	return __isctype_wl(c, _RUNETYPE_C, locale);
104 }
105 
106 int
iswdigit_l(wint_t c,locale_t locale)107 iswdigit_l(wint_t c, locale_t locale)
108 {
109 	return __isctype_wl(c, _RUNETYPE_D, locale);
110 }
111 
112 int
iswgraph_l(wint_t c,locale_t locale)113 iswgraph_l(wint_t c, locale_t locale)
114 {
115 	return __isctype_wl(c, _RUNETYPE_G, locale);
116 }
117 
118 int
iswlower_l(wint_t c,locale_t locale)119 iswlower_l(wint_t c, locale_t locale)
120 {
121 	return __isctype_wl(c, _RUNETYPE_L, locale);
122 }
123 
124 int
iswprint_l(wint_t c,locale_t locale)125 iswprint_l(wint_t c, locale_t locale)
126 {
127 	return __isctype_wl(c, _RUNETYPE_R, locale);
128 }
129 
130 int
iswpunct_l(wint_t c,locale_t locale)131 iswpunct_l(wint_t c, locale_t locale)
132 {
133 	return __isctype_wl(c, _RUNETYPE_P, locale);
134 }
135 
136 int
iswspace_l(wint_t c,locale_t locale)137 iswspace_l(wint_t c, locale_t locale)
138 {
139 	return __isctype_wl(c, _RUNETYPE_S, locale);
140 }
141 
142 int
iswupper_l(wint_t c,locale_t locale)143 iswupper_l(wint_t c, locale_t locale)
144 {
145 	return __isctype_wl(c, _RUNETYPE_U, locale);
146 }
147 
148 int
iswxdigit_l(wint_t c,locale_t locale)149 iswxdigit_l(wint_t c, locale_t locale)
150 {
151 	return __isctype_wl(c, _RUNETYPE_X, locale);
152 }
153 
154 wint_t
towupper_l(wint_t c,locale_t locale)155 towupper_l(wint_t c, locale_t locale)
156 {
157 	return _towctrans(c, _wctrans_upper(__runelocale(locale)));
158 }
159 
160 wint_t
towlower_l(wint_t c,locale_t locale)161 towlower_l(wint_t c, locale_t locale)
162 {
163 	return _towctrans(c, _wctrans_lower(__runelocale(locale)));
164 }
165 DEF_WEAK(towlower_l);
166 
167 wctrans_t
wctrans_l(const char * charclass,locale_t locale)168 wctrans_l(const char *charclass, locale_t locale)
169 {
170 	_RuneLocale	*rl;
171 	int		 i;
172 
173 	rl = __runelocale(locale);
174 	if (rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_name == NULL)
175 		_wctrans_init(rl);
176 
177 	for (i = 0; i < _WCTRANS_NINDEXES; i++)
178 		if (strcmp(rl->rl_wctrans[i].te_name, charclass) == 0)
179 			return &rl->rl_wctrans[i];
180 
181 	return NULL;
182 }
183 
184 /*
185  * POSIX says that the behaviour is unspecified if the LC_CTYPE in
186  * the locale argument does not match what was used to get desc.
187  * The choice made here is to simply ignore the locale argument
188  * and rely on the desc argument only.
189  */
190 wint_t
towctrans_l(wint_t c,wctrans_t desc,locale_t locale)191 towctrans_l(wint_t c, wctrans_t desc,
192     locale_t locale __attribute__((__unused__)))
193 {
194 	return towctrans(c, desc);
195 }
196 
197 int
iswctype_l(wint_t c,wctype_t charclass,locale_t locale)198 iswctype_l(wint_t c, wctype_t charclass, locale_t locale)
199 {
200 	if (charclass == (wctype_t)0)
201 		return 0;  /* Required by SUSv3. */
202 
203 	return __isctype_wl(c, ((_WCTypeEntry *)charclass)->te_mask, locale);
204 }
205