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