1 /* 2 * Copyright 2013 Garrett D'Amore <garrett@damore.org> 3 * Copyright (c) 2004 Tim J. Robbins. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include "lint.h" 29 #include "runetype.h" 30 #include <wchar.h> 31 #include <wctype.h> 32 #include "localeimpl.h" 33 34 /* 35 * nextwctype, while exposed on *BSD/MacOS X, is considered "consolidation 36 * private" for illumos. Hence, we keep the _l version static for now. 37 * If we decide to make this public, just remove the static keyword and 38 * put it in the headers and mapfile. (Should fix up the underscore prefix 39 * to __nextwctype() as well.) 40 */ 41 static wint_t 42 nextwctype_l(wint_t wc, wctype_t wct, locale_t loc) 43 { 44 size_t lim; 45 const _RuneLocale *rl; 46 const _RuneRange *rr; 47 const _RuneEntry *base, *re; 48 int noinc; 49 50 rl = loc->runelocale; 51 rr = &rl->__runetype_ext; 52 53 noinc = 0; 54 if (wc < _CACHED_RUNES) { 55 wc++; 56 while (wc < _CACHED_RUNES) { 57 if (rl->__runetype[wc] & wct) 58 return (wc); 59 wc++; 60 } 61 wc--; 62 } 63 if (rr->__ranges != NULL && wc < rr->__ranges[0].__min) { 64 wc = rr->__ranges[0].__min; 65 noinc = 1; 66 } 67 68 /* Binary search -- see bsearch.c for explanation. */ 69 base = rr->__ranges; 70 for (lim = rr->__nranges; lim != 0; lim >>= 1) { 71 re = base + (lim >> 1); 72 if (re->__min <= wc && wc <= re->__max) 73 goto found; 74 else if (wc > re->__max) { 75 base = re + 1; 76 lim--; 77 } 78 } 79 return (-1); 80 found: 81 if (!noinc) 82 wc++; 83 if (re->__min <= wc && wc <= re->__max) { 84 if (re->__types != NULL) { 85 for (; wc <= re->__max; wc++) 86 if (re->__types[wc - re->__min] & wct) 87 return (wc); 88 } else if (re->__map & wct) 89 return (wc); 90 } 91 while (++re < rr->__ranges + rr->__nranges) { 92 wc = re->__min; 93 if (re->__types != NULL) { 94 for (; wc <= re->__max; wc++) 95 if (re->__types[wc - re->__min] & wct) 96 return (wc); 97 } else if (re->__map & wct) 98 return (wc); 99 } 100 return (-1); 101 } 102 103 /* 104 * External, but consolidation private routine. 105 */ 106 wint_t 107 __nextwctype(wint_t wc, wctype_t wct) 108 { 109 return (nextwctype_l(wc, wct, uselocale(NULL))); 110 }