(root)/
coreutils-9.4/
gnulib-tests/
unistr/
test-chr.h
       1  /* Test of uN_chr() functions.
       2     Copyright (C) 2008-2023 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 Eric Blake and Bruno Haible <bruno@clisp.org>, 2010.  */
      18  
      19  int
      20  main (void)
      21  {
      22    size_t size = 0x100000;
      23    size_t i;
      24    size_t length;
      25    UNIT *input;
      26    uint32_t *input32 = (uint32_t *) malloc (size * sizeof (uint32_t));
      27    ASSERT (input32);
      28  
      29    input32[0] = 'a';
      30    input32[1] = 'b';
      31    u32_set (input32 + 2, 'c', 1024);
      32    for (i = 1026; i < size - 2; i += 63)
      33      {
      34        size_t last = i + 63 < size - 2 ? i + 63 : size - 2;
      35        ucs4_t uc = 'd' | (i - 1026);
      36        if (uc >= 0xd800 && uc <= 0xdfff)
      37          uc |= 0x100000;
      38        u32_set (input32 + i, uc, last - i);
      39      }
      40  
      41    input32[size - 2] = 'e';
      42    input32[size - 1] = 'a';
      43  
      44    input = U32_TO_U (input32, size, NULL, &length);
      45    ASSERT (input);
      46  
      47    /* Basic behavior tests.  */
      48    ASSERT (U_CHR (input, length, 'a') == input);
      49  
      50    ASSERT (U_CHR (input, 0, 'a') == NULL);
      51    void *page_boundary = zerosize_ptr ();
      52    if (page_boundary)
      53      ASSERT (U_CHR (page_boundary, 0, 'a') == NULL);
      54  
      55    ASSERT (U_CHR (input, length, 'b') == input + 1);
      56    ASSERT (U_CHR (input, length, 'c') == input + 2);
      57    ASSERT (U_CHR (input, length, 'd') == input + 1026);
      58  
      59    {
      60      UNIT *exp = input + 1026;
      61      UNIT *prev = input + 1;
      62      for (i = 1026; i < size - 2; i += 63)
      63        {
      64          UNIT c[6];
      65          size_t n;
      66          ucs4_t uc = 'd' | (i - 1026);
      67          if (uc >= 0xd800 && uc <= 0xdfff)
      68            uc |= 0x100000;
      69          n = U_UCTOMB (c, uc, 6);
      70          ASSERT (exp < input + length - 1);
      71          ASSERT (U_CHR (prev, (length - 1) - (prev - input), uc) == exp);
      72          ASSERT (memcmp (exp, c, n * sizeof (UNIT)) == 0);
      73          prev = exp;
      74          exp += n * 63;
      75        }
      76    }
      77  
      78    ASSERT (U_CHR (input + 1, length - 1, 'a') == input + length - 1);
      79    ASSERT (U_CHR (input + 1, length - 1, 'e') == input + length - 2);
      80  
      81    ASSERT (U_CHR (input, length, 'f') == NULL);
      82    ASSERT (U_CHR (input, length, '\0') == NULL);
      83  
      84    /* Check that a very long haystack is handled quickly if the byte is
      85       found near the beginning.  */
      86    {
      87      size_t repeat = 10000;
      88      for (; repeat > 0; repeat--)
      89        {
      90          ASSERT (U_CHR (input, length, 'c') == input + 2);
      91        }
      92    }
      93  
      94    /* Alignment tests.  */
      95    {
      96      int i, j;
      97      for (i = 0; i < 32; i++)
      98        {
      99          for (j = 0; j < 128; j++)
     100            input[i + j] = j;
     101          for (j = 0; j < 128; j++)
     102            {
     103              ASSERT (U_CHR (input + i, 128, j) == input + i + j);
     104            }
     105        }
     106    }
     107  
     108    /* Check that uN_chr() does not read past the first occurrence of the
     109       byte being searched.  */
     110    {
     111      char *page_boundary = (char *) zerosize_ptr ();
     112      size_t n;
     113  
     114      if (page_boundary != NULL)
     115        {
     116          for (n = 1; n <= 500 / sizeof (UNIT); n++)
     117            {
     118              UNIT *mem = (UNIT *) (page_boundary - n * sizeof (UNIT));
     119              U_SET (mem, 'X', n);
     120              ASSERT (U_CHR (mem, n, 'U') == NULL);
     121  
     122              {
     123                size_t i;
     124  
     125                for (i = 0; i < n; i++)
     126                  {
     127                    mem[i] = 'U';
     128                    ASSERT (U_CHR (mem, 4000, 'U') == mem + i);
     129                    mem[i] = 'X';
     130                  }
     131              }
     132            }
     133        }
     134    }
     135  
     136    free (input);
     137    if (sizeof (UNIT) != sizeof (uint32_t))
     138      free (input32);
     139  
     140    return 0;
     141  }