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 50static _RuneLocale *__runelocale(locale_t); 51static 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 */ 58static _RuneLocale * 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 71static int 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 82int 83iswalnum_l(wint_t c, locale_t locale) 84{ 85 return __isctype_wl(c, _RUNETYPE_A|_RUNETYPE_D, locale); 86} 87 88int 89iswalpha_l(wint_t c, locale_t locale) 90{ 91 return __isctype_wl(c, _RUNETYPE_A, locale); 92} 93 94int 95iswblank_l(wint_t c, locale_t locale) 96{ 97 return __isctype_wl(c, _RUNETYPE_B, locale); 98} 99 100int 101iswcntrl_l(wint_t c, locale_t locale) 102{ 103 return __isctype_wl(c, _RUNETYPE_C, locale); 104} 105 106int 107iswdigit_l(wint_t c, locale_t locale) 108{ 109 return __isctype_wl(c, _RUNETYPE_D, locale); 110} 111 112int 113iswgraph_l(wint_t c, locale_t locale) 114{ 115 return __isctype_wl(c, _RUNETYPE_G, locale); 116} 117 118int 119iswlower_l(wint_t c, locale_t locale) 120{ 121 return __isctype_wl(c, _RUNETYPE_L, locale); 122} 123 124int 125iswprint_l(wint_t c, locale_t locale) 126{ 127 return __isctype_wl(c, _RUNETYPE_R, locale); 128} 129 130int 131iswpunct_l(wint_t c, locale_t locale) 132{ 133 return __isctype_wl(c, _RUNETYPE_P, locale); 134} 135 136int 137iswspace_l(wint_t c, locale_t locale) 138{ 139 return __isctype_wl(c, _RUNETYPE_S, locale); 140} 141 142int 143iswupper_l(wint_t c, locale_t locale) 144{ 145 return __isctype_wl(c, _RUNETYPE_U, locale); 146} 147 148int 149iswxdigit_l(wint_t c, locale_t locale) 150{ 151 return __isctype_wl(c, _RUNETYPE_X, locale); 152} 153 154wint_t 155towupper_l(wint_t c, locale_t locale) 156{ 157 return _towctrans(c, _wctrans_upper(__runelocale(locale))); 158} 159 160wint_t 161towlower_l(wint_t c, locale_t locale) 162{ 163 return _towctrans(c, _wctrans_lower(__runelocale(locale))); 164} 165DEF_WEAK(towlower_l); 166 167wctrans_t 168wctrans_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 */ 190wint_t 191towctrans_l(wint_t c, wctrans_t desc, 192 locale_t locale __attribute__((__unused__))) 193{ 194 return towctrans(c, desc); 195} 196 197int 198iswctype_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