1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2004 Tim J. Robbins. 5 * All rights reserved. 6 * 7 * Copyright (c) 2011 The FreeBSD Foundation 8 * All rights reserved. 9 * Portions of this software were developed by David Chisnall 10 * under sponsorship from the FreeBSD Foundation. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include <runetype.h> 38 #include <wchar.h> 39 #include <wctype.h> 40 #include "mblocal.h" 41 42 wint_t 43 nextwctype_l(wint_t wc, wctype_t wct, locale_t locale) 44 { 45 size_t lim; 46 FIX_LOCALE(locale); 47 _RuneLocale *runes = XLOCALE_CTYPE(locale)->runes; 48 _RuneRange *rr = &runes->__runetype_ext; 49 _RuneEntry *base, *re; 50 int noinc; 51 52 noinc = 0; 53 if (wc < _CACHED_RUNES) { 54 wc++; 55 while (wc < _CACHED_RUNES) { 56 if (runes->__runetype[wc] & wct) 57 return (wc); 58 wc++; 59 } 60 wc--; 61 } 62 if (rr->__ranges != NULL && wc < rr->__ranges[0].__min) { 63 wc = rr->__ranges[0].__min; 64 noinc = 1; 65 } 66 67 /* Binary search -- see bsearch.c for explanation. */ 68 base = rr->__ranges; 69 for (lim = rr->__nranges; lim != 0; lim >>= 1) { 70 re = base + (lim >> 1); 71 if (re->__min <= wc && wc <= re->__max) 72 goto found; 73 else if (wc > re->__max) { 74 base = re + 1; 75 lim--; 76 } 77 } 78 return (-1); 79 found: 80 if (!noinc) 81 wc++; 82 if (re->__min <= wc && wc <= re->__max) { 83 if (re->__types != NULL) { 84 for (; wc <= re->__max; wc++) 85 if (re->__types[wc - re->__min] & wct) 86 return (wc); 87 } else if (re->__map & wct) 88 return (wc); 89 } 90 while (++re < rr->__ranges + rr->__nranges) { 91 wc = re->__min; 92 if (re->__types != NULL) { 93 for (; wc <= re->__max; wc++) 94 if (re->__types[wc - re->__min] & wct) 95 return (wc); 96 } else if (re->__map & wct) 97 return (wc); 98 } 99 return (-1); 100 } 101 wint_t 102 nextwctype(wint_t wc, wctype_t wct) 103 { 104 return nextwctype_l(wc, wct, __get_locale()); 105 } 106