Blame locale/weightwc.h

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