1 | /* Copyright (C) 1996-2016 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. |
3 | Written by Ulrich Drepper, <drepper@cygnus.com>. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ |
18 | |
19 | #ifndef _WEIGHTWC_H_ |
20 | #define _WEIGHTWC_H_ 1 |
21 | |
22 | /* Find index of weight. */ |
23 | static inline int32_t __attribute__ ((always_inline)) |
24 | findidx (const int32_t *table, |
25 | const int32_t *indirect, |
26 | const wint_t *, |
27 | const wint_t **cpp, size_t len) |
28 | { |
29 | wint_t ch = *(*cpp)++; |
30 | int32_t i = __collidx_table_lookup ((const char *) table, ch); |
31 | |
32 | if (i >= 0) |
33 | /* This is an index into the weight table. Cool. */ |
34 | return i; |
35 | |
36 | /* Oh well, more than one sequence starting with this byte. |
37 | Search for the correct one. */ |
38 | const int32_t *cp = (const int32_t *) &extra[-i]; |
39 | --len; |
40 | while (1) |
41 | { |
42 | size_t nhere; |
43 | const int32_t *usrc = (const int32_t *) *cpp; |
44 | |
45 | /* The first thing is the index. */ |
46 | i = *cp++; |
47 | |
48 | /* Next is the length of the byte sequence. These are always |
49 | short byte sequences so there is no reason to call any |
50 | function (even if they are inlined). */ |
51 | nhere = *cp++; |
52 | |
53 | if (i >= 0) |
54 | { |
55 | /* It is a single character. If it matches we found our |
56 | index. Note that at the end of each list there is an |
57 | entry of length zero which represents the single byte |
58 | sequence. The first (and here only) byte was tested |
59 | already. */ |
60 | size_t cnt; |
61 | |
62 | for (cnt = 0; cnt < nhere && cnt < len; ++cnt) |
63 | if (cp[cnt] != usrc[cnt]) |
64 | break; |
65 | |
66 | if (cnt == nhere) |
67 | { |
68 | /* Found it. */ |
69 | *cpp += nhere; |
70 | return i; |
71 | } |
72 | |
73 | /* Up to the next entry. */ |
74 | cp += nhere; |
75 | } |
76 | else |
77 | { |
78 | /* This is a range of characters. First decide whether the |
79 | current byte sequence lies in the range. */ |
80 | size_t cnt; |
81 | size_t offset; |
82 | |
83 | for (cnt = 0; cnt < nhere - 1 && cnt < len; ++cnt) |
84 | if (cp[cnt] != usrc[cnt]) |
85 | break; |
86 | |
87 | if (cnt < nhere - 1) |
88 | { |
89 | cp += 2 * nhere; |
90 | continue; |
91 | } |
92 | |
93 | if (cp[nhere - 1] > usrc[nhere -1]) |
94 | { |
95 | cp += 2 * nhere; |
96 | continue; |
97 | } |
98 | |
99 | if (cp[2 * nhere - 1] < usrc[nhere -1]) |
100 | { |
101 | cp += 2 * nhere; |
102 | continue; |
103 | } |
104 | |
105 | /* This range matches the next characters. Now find |
106 | the offset in the indirect table. */ |
107 | offset = usrc[nhere - 1] - cp[nhere - 1]; |
108 | *cpp += nhere; |
109 | |
110 | return indirect[-i + offset]; |
111 | } |
112 | } |
113 | |
114 | /* NOTREACHED */ |
115 | return 0x43219876; |
116 | } |
117 | |
118 | #endif /* weightwc.h */ |
119 | |