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