1163bd69bSGarrett D'Amore /*
2*2d08521bSGarrett D'Amore  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
3163bd69bSGarrett D'Amore  * Copyright (c) 2004 Tim J. Robbins.
4163bd69bSGarrett D'Amore  * All rights reserved.
5163bd69bSGarrett D'Amore  *
6163bd69bSGarrett D'Amore  * Redistribution and use in source and binary forms, with or without
7163bd69bSGarrett D'Amore  * modification, are permitted provided that the following conditions
8163bd69bSGarrett D'Amore  * are met:
9163bd69bSGarrett D'Amore  * 1. Redistributions of source code must retain the above copyright
10163bd69bSGarrett D'Amore  *    notice, this list of conditions and the following disclaimer.
11163bd69bSGarrett D'Amore  * 2. Redistributions in binary form must reproduce the above copyright
12163bd69bSGarrett D'Amore  *    notice, this list of conditions and the following disclaimer in the
13163bd69bSGarrett D'Amore  *    documentation and/or other materials provided with the distribution.
14163bd69bSGarrett D'Amore  *
15163bd69bSGarrett D'Amore  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16163bd69bSGarrett D'Amore  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17163bd69bSGarrett D'Amore  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18163bd69bSGarrett D'Amore  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19163bd69bSGarrett D'Amore  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20163bd69bSGarrett D'Amore  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21163bd69bSGarrett D'Amore  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22163bd69bSGarrett D'Amore  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23163bd69bSGarrett D'Amore  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24163bd69bSGarrett D'Amore  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25163bd69bSGarrett D'Amore  * SUCH DAMAGE.
26163bd69bSGarrett D'Amore  */
27163bd69bSGarrett D'Amore 
28163bd69bSGarrett D'Amore #include "lint.h"
29163bd69bSGarrett D'Amore #include "runetype.h"
30163bd69bSGarrett D'Amore #include <wchar.h>
31163bd69bSGarrett D'Amore #include <wctype.h>
32*2d08521bSGarrett D'Amore #include "localeimpl.h"
33163bd69bSGarrett D'Amore 
34*2d08521bSGarrett D'Amore /*
35*2d08521bSGarrett D'Amore  * nextwctype, while exposed on *BSD/MacOS X, is considered "consolidation
36*2d08521bSGarrett D'Amore  * private" for illumos.  Hence, we keep the _l version static for now.
37*2d08521bSGarrett D'Amore  * If we decide to make this public, just remove the static keyword and
38*2d08521bSGarrett D'Amore  * put it in the headers and mapfile.  (Should fix up the underscore prefix
39*2d08521bSGarrett D'Amore  * to __nextwctype() as well.)
40*2d08521bSGarrett D'Amore  */
41*2d08521bSGarrett D'Amore static wint_t
nextwctype_l(wint_t wc,wctype_t wct,locale_t loc)42*2d08521bSGarrett D'Amore nextwctype_l(wint_t wc, wctype_t wct, locale_t loc)
43163bd69bSGarrett D'Amore {
44163bd69bSGarrett D'Amore 	size_t lim;
45*2d08521bSGarrett D'Amore 	const _RuneLocale *rl;
46*2d08521bSGarrett D'Amore 	const _RuneRange *rr;
47*2d08521bSGarrett D'Amore 	const _RuneEntry *base, *re;
48163bd69bSGarrett D'Amore 	int noinc;
49163bd69bSGarrett D'Amore 
50*2d08521bSGarrett D'Amore 	rl = loc->runelocale;
51*2d08521bSGarrett D'Amore 	rr = &rl->__runetype_ext;
52*2d08521bSGarrett D'Amore 
53163bd69bSGarrett D'Amore 	noinc = 0;
54163bd69bSGarrett D'Amore 	if (wc < _CACHED_RUNES) {
55163bd69bSGarrett D'Amore 		wc++;
56163bd69bSGarrett D'Amore 		while (wc < _CACHED_RUNES) {
57*2d08521bSGarrett D'Amore 			if (rl->__runetype[wc] & wct)
58163bd69bSGarrett D'Amore 				return (wc);
59163bd69bSGarrett D'Amore 			wc++;
60163bd69bSGarrett D'Amore 		}
61163bd69bSGarrett D'Amore 		wc--;
62163bd69bSGarrett D'Amore 	}
63163bd69bSGarrett D'Amore 	if (rr->__ranges != NULL && wc < rr->__ranges[0].__min) {
64163bd69bSGarrett D'Amore 		wc = rr->__ranges[0].__min;
65163bd69bSGarrett D'Amore 		noinc = 1;
66163bd69bSGarrett D'Amore 	}
67163bd69bSGarrett D'Amore 
68163bd69bSGarrett D'Amore 	/* Binary search -- see bsearch.c for explanation. */
69163bd69bSGarrett D'Amore 	base = rr->__ranges;
70163bd69bSGarrett D'Amore 	for (lim = rr->__nranges; lim != 0; lim >>= 1) {
71163bd69bSGarrett D'Amore 		re = base + (lim >> 1);
72163bd69bSGarrett D'Amore 		if (re->__min <= wc && wc <= re->__max)
73163bd69bSGarrett D'Amore 			goto found;
74163bd69bSGarrett D'Amore 		else if (wc > re->__max) {
75163bd69bSGarrett D'Amore 			base = re + 1;
76163bd69bSGarrett D'Amore 			lim--;
77163bd69bSGarrett D'Amore 		}
78163bd69bSGarrett D'Amore 	}
79163bd69bSGarrett D'Amore 	return (-1);
80163bd69bSGarrett D'Amore found:
81163bd69bSGarrett D'Amore 	if (!noinc)
82163bd69bSGarrett D'Amore 		wc++;
83163bd69bSGarrett D'Amore 	if (re->__min <= wc && wc <= re->__max) {
84163bd69bSGarrett D'Amore 		if (re->__types != NULL) {
85163bd69bSGarrett D'Amore 			for (; wc <= re->__max; wc++)
86163bd69bSGarrett D'Amore 				if (re->__types[wc - re->__min] & wct)
87163bd69bSGarrett D'Amore 					return (wc);
88163bd69bSGarrett D'Amore 		} else if (re->__map & wct)
89163bd69bSGarrett D'Amore 			return (wc);
90163bd69bSGarrett D'Amore 	}
91163bd69bSGarrett D'Amore 	while (++re < rr->__ranges + rr->__nranges) {
92163bd69bSGarrett D'Amore 		wc = re->__min;
93163bd69bSGarrett D'Amore 		if (re->__types != NULL) {
94163bd69bSGarrett D'Amore 			for (; wc <= re->__max; wc++)
95163bd69bSGarrett D'Amore 				if (re->__types[wc - re->__min] & wct)
96163bd69bSGarrett D'Amore 					return (wc);
97163bd69bSGarrett D'Amore 		} else if (re->__map & wct)
98163bd69bSGarrett D'Amore 			return (wc);
99163bd69bSGarrett D'Amore 	}
100163bd69bSGarrett D'Amore 	return (-1);
101163bd69bSGarrett D'Amore }
102*2d08521bSGarrett D'Amore 
103*2d08521bSGarrett D'Amore /*
104*2d08521bSGarrett D'Amore  * External, but consolidation private routine.
105*2d08521bSGarrett D'Amore  */
106*2d08521bSGarrett D'Amore wint_t
__nextwctype(wint_t wc,wctype_t wct)107*2d08521bSGarrett D'Amore __nextwctype(wint_t wc, wctype_t wct)
108*2d08521bSGarrett D'Amore {
109*2d08521bSGarrett D'Amore 	return (nextwctype_l(wc, wct, uselocale(NULL)));
110*2d08521bSGarrett D'Amore }
111