Blame locale/weight.h

Packit Service 82fcde
/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Written by Ulrich Drepper, <drepper@cygnus.com>.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef _WEIGHT_H_
Packit Service 82fcde
#define _WEIGHT_H_	1
Packit Service 82fcde
Packit Service 82fcde
#include <libc-diag.h>
Packit Service 82fcde
Packit Service 82fcde
/* Find index of weight.  */
Packit Service 82fcde
static inline int32_t __attribute__ ((always_inline))
Packit Service 82fcde
findidx (const int32_t *table,
Packit Service 82fcde
	 const int32_t *indirect,
Packit Service 82fcde
	 const unsigned char *extra,
Packit Service 82fcde
	 const unsigned char **cpp, size_t len)
Packit Service 82fcde
{
Packit Service 82fcde
  int_fast32_t i = table[*(*cpp)++];
Packit Service 82fcde
  const unsigned char *cp;
Packit Service 82fcde
  const unsigned char *usrc;
Packit Service 82fcde
Packit Service 82fcde
  if (i >= 0)
Packit Service 82fcde
    /* This is an index into the weight table.  Cool.  */
Packit Service 82fcde
    return i;
Packit Service 82fcde
Packit Service 82fcde
  /* Oh well, more than one sequence starting with this byte.
Packit Service 82fcde
     Search for the correct one.  */
Packit Service 82fcde
  cp = &extra[-i];
Packit Service 82fcde
  usrc = *cpp;
Packit Service 82fcde
  --len;
Packit Service 82fcde
  while (1)
Packit Service 82fcde
    {
Packit Service 82fcde
      size_t nhere;
Packit Service 82fcde
Packit Service 82fcde
      /* The first thing is the index.  */
Packit Service 82fcde
      i = *((const int32_t *) cp);
Packit Service 82fcde
      cp += sizeof (int32_t);
Packit Service 82fcde
Packit Service 82fcde
      /* Next is the length of the byte sequence.  These are always
Packit Service 82fcde
	 short byte sequences so there is no reason to call any
Packit Service 82fcde
	 function (even if they are inlined).  */
Packit Service 82fcde
      nhere = *cp++;
Packit Service 82fcde
Packit Service 82fcde
      if (i >= 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* It is a single character.  If it matches we found our
Packit Service 82fcde
	     index.  Note that at the end of each list there is an
Packit Service 82fcde
	     entry of length zero which represents the single byte
Packit Service 82fcde
	     sequence.  The first (and here only) byte was tested
Packit Service 82fcde
	     already.  */
Packit Service 82fcde
	  size_t cnt;
Packit Service 82fcde
Packit Service 82fcde
	  /* With GCC 5.3 when compiling with -Os the compiler warns
Packit Service 82fcde
	     that seq2.back_us, which becomes usrc, might be used
Packit Service 82fcde
	     uninitialized.  This can't be true because we pass a length
Packit Service 82fcde
	     of -1 for len at the same time which means that this loop
Packit Service 82fcde
	     never executes.  */
Packit Service 82fcde
	  DIAG_PUSH_NEEDS_COMMENT;
Packit Service 82fcde
	  DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
Packit Service 82fcde
	  for (cnt = 0; cnt < nhere && cnt < len; ++cnt)
Packit Service 82fcde
	    if (cp[cnt] != usrc[cnt])
Packit Service 82fcde
	      break;
Packit Service 82fcde
	  DIAG_POP_NEEDS_COMMENT;
Packit Service 82fcde
Packit Service 82fcde
	  if (cnt == nhere)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Found it.  */
Packit Service 82fcde
	      *cpp += nhere;
Packit Service 82fcde
	      return i;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Up to the next entry.  */
Packit Service 82fcde
	  cp += nhere;
Packit Service 82fcde
	  if (!LOCFILE_ALIGNED_P (1 + nhere))
Packit Service 82fcde
	    cp += LOCFILE_ALIGN - (1 + nhere) % LOCFILE_ALIGN;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* This is a range of characters.  First decide whether the
Packit Service 82fcde
	     current byte sequence lies in the range.  */
Packit Service 82fcde
	  size_t cnt;
Packit Service 82fcde
	  size_t offset = 0;
Packit Service 82fcde
Packit Service 82fcde
	  for (cnt = 0; cnt < nhere && cnt < len; ++cnt)
Packit Service 82fcde
	    if (cp[cnt] != usrc[cnt])
Packit Service 82fcde
	      break;
Packit Service 82fcde
Packit Service 82fcde
	  if (cnt != nhere)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (cnt == len || cp[cnt] > usrc[cnt])
Packit Service 82fcde
		{
Packit Service 82fcde
		  /* Cannot be in this range.  */
Packit Service 82fcde
		  cp += 2 * nhere;
Packit Service 82fcde
		  if (!LOCFILE_ALIGNED_P (1 + 2 * nhere))
Packit Service 82fcde
		    cp += (LOCFILE_ALIGN
Packit Service 82fcde
			   - (1 + 2 * nhere) % LOCFILE_ALIGN);
Packit Service 82fcde
		  continue;
Packit Service 82fcde
		}
Packit Service 82fcde
Packit Service 82fcde
	      /* Test against the end of the range.  */
Packit Service 82fcde
	      for (cnt = 0; cnt < nhere; ++cnt)
Packit Service 82fcde
		if (cp[nhere + cnt] != usrc[cnt])
Packit Service 82fcde
		  break;
Packit Service 82fcde
Packit Service 82fcde
	      if (cnt != nhere && cp[nhere + cnt] < usrc[cnt])
Packit Service 82fcde
		{
Packit Service 82fcde
		  /* Cannot be in this range.  */
Packit Service 82fcde
		  cp += 2 * nhere;
Packit Service 82fcde
		  if (!LOCFILE_ALIGNED_P (1 + 2 * nhere))
Packit Service 82fcde
		    cp += (LOCFILE_ALIGN
Packit Service 82fcde
			   - (1 + 2 * nhere) % LOCFILE_ALIGN);
Packit Service 82fcde
		  continue;
Packit Service 82fcde
		}
Packit Service 82fcde
Packit Service 82fcde
	      /* This range matches the next characters.  Now find
Packit Service 82fcde
		 the offset in the indirect table.  */
Packit Service 82fcde
	      for (cnt = 0; cp[cnt] == usrc[cnt]; ++cnt);
Packit Service 82fcde
Packit Service 82fcde
	      do
Packit Service 82fcde
		{
Packit Service 82fcde
		  offset <<= 8;
Packit Service 82fcde
		  /* With GCC 7 when compiling with -Os the compiler
Packit Service 82fcde
		     warns that seq1.back_us and seq2.back_us, which
Packit Service 82fcde
		     become usrc, might be used uninitialized.  This
Packit Service 82fcde
		     is impossible for the same reason as described
Packit Service 82fcde
		     above.  */
Packit Service 82fcde
		  DIAG_PUSH_NEEDS_COMMENT;
Packit Service 82fcde
		  DIAG_IGNORE_Os_NEEDS_COMMENT (7, "-Wmaybe-uninitialized");
Packit Service 82fcde
		  offset += usrc[cnt] - cp[cnt];
Packit Service 82fcde
		  DIAG_POP_NEEDS_COMMENT;
Packit Service 82fcde
		}
Packit Service 82fcde
	      while (++cnt < nhere);
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  *cpp += nhere;
Packit Service 82fcde
	  return indirect[-i + offset];
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* NOTREACHED */
Packit Service 82fcde
  return 0x43219876;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#endif	/* weight.h */