| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 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 *extra, | 
 | 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 */ |