
1: /* Copyright (C) 1996-2001,2003,2004,2005,2007 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, write to the Free 17: Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18: 02111-1307 USA. */ 19: 20: /* Find index of weight. */ 21: auto inline int32_t 22: __attribute ((always_inline)) 23: findidx (const wint_t **cpp) 24: { 25: wint_t ch = *(*cpp)++; 26: int32_t i = __collidx_table_lookup ((const char *) table, ch); 27: 28: if (i >= 0) 29: /* This is an index into the weight table. Cool. */ 30: return i; 31: 32: /* Oh well, more than one sequence starting with this byte. 33: Search for the correct one. */ 34: const int32_t *cp = (const int32_t *) &extra[-i]; 35: while (1) 36: { 37: size_t nhere; 38: const int32_t *usrc = (const int32_t *) *cpp; 39: 40: /* The first thing is the index. */ 41: i = *cp++; 42: 43: /* Next is the length of the byte sequence. These are always 44: short byte sequences so there is no reason to call any 45: function (even if they are inlined). */ 46: nhere = *cp++; 47: 48: if (i >= 0) 49: { 50: /* It is a single character. If it matches we found our 51: index. Note that at the end of each list there is an 52: entry of length zero which represents the single byte 53: sequence. The first (and here only) byte was tested 54: already. */ 55: size_t cnt; 56: 57: for (cnt = 0; cnt < nhere; ++cnt) 58: if (cp[cnt] != usrc[cnt]) 59: break; 60: 61: if (cnt == nhere) 62: { 63: /* Found it. */ 64: *cpp += nhere; 65: return i; 66: } 67: 68: /* Up to the next entry. */ 69: cp += nhere; 70: } 71: else 72: { 73: /* This is a range of characters. First decide whether the 74: current byte sequence lies in the range. */ 75: size_t cnt; 76: size_t offset; 77: 78: for (cnt = 0; cnt < nhere - 1; ++cnt) 79: if (cp[cnt] != usrc[cnt]) 80: break; 81: 82: if (cnt < nhere - 1) 83: { 84: cp += 2 * nhere; 85: continue; 86: } 87: 88: if (cp[nhere - 1] > usrc[nhere -1]) 89: { 90: cp += 2 * nhere; 91: continue; 92: } 93: 94: if (cp[2 * nhere - 1] < usrc[nhere -1]) 95: { 96: cp += 2 * nhere; 97: continue; 98: } 99: 100: /* This range matches the next characters. Now find 101: the offset in the indirect table. */ 102: offset = usrc[nhere - 1] - cp[nhere - 1]; 103: *cpp += nhere; 104: 105: return indirect[-i + offset]; 106: } 107: } 108: 109: /* NOTREACHED */ 110: return 0x43219876; 111: }