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