root/maint/gnulib/tests/unistr/test-strchr.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. test_strchr

   1 /* Test of uN_strchr() functions.
   2    Copyright (C) 2008-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Paolo Bonzini <bonzini@gnu.org>, 2010.
  18    Based on test-chr.h, by Eric Blake and Bruno Haible.  */
  19 
  20 static void
  21 test_strchr (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  22 {
  23   size_t size = 0x100000;
  24   size_t length;
  25   size_t i;
  26   UNIT *input;
  27   uint32_t *input32 = (uint32_t *) malloc ((size + 1) * sizeof (uint32_t));
  28   ASSERT (input32);
  29 
  30   input32[0] = 'a';
  31   input32[1] = 'b';
  32   u32_set (input32 + 2, 'c', 1024);
  33   for (i = 1026; i < size - 2; i += 63)
  34     {
  35       size_t last = i + 63 < size - 2 ? i + 63 : size - 2;
  36       ucs4_t uc = 'd' | (i - 1026);
  37       if (uc >= 0xd800 && uc <= 0xdfff)
  38         uc |= 0x100000;
  39       u32_set (input32 + i, uc, last - i);
  40     }
  41   input32[size - 2] = 'e';
  42   input32[size - 1] = 'a';
  43   input32[size] = 0;
  44 
  45   input = U32_TO_U (input32, size + 1, NULL, &length);
  46   ASSERT (input);
  47 
  48   /* Basic behavior tests.  */
  49   ASSERT (U_STRCHR (input, 'a') == input);
  50   ASSERT (U_STRCHR (input, 'b') == input + 1);
  51   ASSERT (U_STRCHR (input, 'c') == input + 2);
  52 
  53   {
  54     UNIT *exp = input + 1026;
  55     UNIT *prev = input + 2;
  56 
  57     for (i = 1026; i < size - 2; i += 63)
  58       {
  59         UNIT c[6];
  60         size_t n;
  61         ucs4_t uc = 'd' | (i - 1026);
  62         if (uc >= 0xd800 && uc <= 0xdfff)
  63           uc |= 0x100000;
  64         n = U_UCTOMB (c, uc, 6);
  65         ASSERT (exp < input + length - 2);
  66         ASSERT (U_STRCHR (prev, uc) == exp);
  67         ASSERT (memcmp (exp, c, n * sizeof (UNIT)) == 0);
  68         prev = exp;
  69         exp += n * 63;
  70       }
  71   }
  72 
  73   ASSERT (U_STRCHR (input + 1, 'a') == input + length - 2);
  74   ASSERT (U_STRCHR (input + 1, 'e') == input + length - 3);
  75 
  76   ASSERT (U_STRCHR (input, 'f') == NULL);
  77   ASSERT (U_STRCHR (input, '\0') == input + length - 1);
  78 
  79   /* Check that a very long haystack is handled quickly if the byte is
  80      found near the beginning.  */
  81   {
  82     size_t repeat = 10000;
  83     for (; repeat > 0; repeat--)
  84       {
  85         ASSERT (U_STRCHR (input, 'c') == input + 2);
  86       }
  87   }
  88 
  89   /* Alignment tests.  */
  90   {
  91     int i, j;
  92     for (i = 0; i < 32; i++)
  93       {
  94         for (j = 0; j < 127; j++)
  95           input[i + j] = j + 1;
  96         input[i + 128] = 0;
  97         for (j = 0; j < 127; j++)
  98           {
  99             ASSERT (U_STRCHR (input + i, j + 1) == input + i + j);
 100           }
 101       }
 102   }
 103 
 104   /* Check that uN_strchr() does not read past the end of the string.  */
 105   {
 106     char *page_boundary = (char *) zerosize_ptr ();
 107     size_t n;
 108 
 109     if (page_boundary != NULL)
 110       {
 111         for (n = 2; n <= 500 / sizeof (UNIT); n++)
 112           {
 113             UNIT *mem = (UNIT *) (page_boundary - n * sizeof (UNIT));
 114             U_SET (mem, 'X', n - 2);
 115             mem[n - 2] = 0;
 116             ASSERT (U_STRCHR (mem, 'U') == NULL);
 117             mem[n - 2] = 'X';
 118             mem[n - 1] = 0;
 119             ASSERT (U_STRCHR (mem, 'U') == NULL);
 120           }
 121       }
 122   }
 123 
 124 #if 0
 125   /* This check is disabled, because uN_strchr() is allowed to read past the
 126      first occurrence of the byte being searched.  In fact, u8_strchr() does
 127      so, on i586 glibc systems: u8_strchr calls strchr, which in
 128      glibc/sysdeps/i386/i586/strchr.S loads the second word before the
 129      handling of the first word has been completed.  */
 130   /* Check that uN_strchr() does not read past the first occurrence of the
 131      byte being searched.  */
 132   {
 133     char *page_boundary = (char *) zerosize_ptr ();
 134     size_t n;
 135 
 136     if (page_boundary != NULL)
 137       {
 138         for (n = 2; n <= 500 / sizeof (UNIT); n++)
 139           {
 140             UNIT *mem = (UNIT *) (page_boundary - n * sizeof (UNIT));
 141             U_SET (mem, 'X', n - 1);
 142             mem[n - 1] = 0;
 143             ASSERT (U_STRCHR (mem, 'U') == NULL);
 144 
 145             {
 146               size_t i;
 147 
 148               for (i = 0; i < n; i++)
 149                 {
 150                   mem[i] = 'U';
 151                   ASSERT (U_STRCHR (mem, 'U') == mem + i);
 152                   mem[i] = 'X';
 153                 }
 154             }
 155           }
 156       }
 157   }
 158 #endif
 159 
 160   free (input);
 161   if (sizeof (UNIT) != sizeof (uint32_t))
 162     free (input32);
 163 }

/* [previous][next][first][last][top][bottom][index][help] */