(root)/
diffutils-3.10/
gnulib-tests/
test-rawmemchr.c
       1  /*
       2   * Copyright (C) 2008-2023 Free Software Foundation, Inc.
       3   * Written by Eric Blake and Bruno Haible
       4   *
       5   * This program is free software: you can redistribute it and/or modify
       6   * it under the terms of the GNU General Public License as published by
       7   * the Free Software Foundation, either version 3 of the License, or
       8   * (at your option) any later version.
       9   *
      10   * This program is distributed in the hope that it will be useful,
      11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13   * GNU General Public License for more details.
      14   *
      15   * You should have received a copy of the GNU General Public License
      16   * along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <config.h>
      19  
      20  #include <string.h>
      21  
      22  #include "signature.h"
      23  SIGNATURE_CHECK (rawmemchr, void *, (void const *, int));
      24  
      25  #include <stdlib.h>
      26  
      27  #include "zerosize-ptr.h"
      28  #include "macros.h"
      29  
      30  /* Calculating void * + int is not portable, so this wrapper converts
      31     to char * to make the tests easier to write.  */
      32  #define RAWMEMCHR (char *) rawmemchr
      33  
      34  int
      35  main (void)
      36  {
      37    size_t n = 0x100000;
      38    char *input = malloc (n + 1);
      39    ASSERT (input);
      40  
      41    input[0] = 'a';
      42    input[1] = 'b';
      43    memset (input + 2, 'c', 1024);
      44    memset (input + 1026, 'd', n - 1028);
      45    input[n - 2] = 'e';
      46    input[n - 1] = 'a';
      47    input[n] = '\0';
      48  
      49    /* Basic behavior tests.  */
      50    ASSERT (RAWMEMCHR (input, 'a') == input);
      51    ASSERT (RAWMEMCHR (input, 'b') == input + 1);
      52    ASSERT (RAWMEMCHR (input, 'c') == input + 2);
      53    ASSERT (RAWMEMCHR (input, 'd') == input + 1026);
      54  
      55    ASSERT (RAWMEMCHR (input + 1, 'a') == input + n - 1);
      56    ASSERT (RAWMEMCHR (input + 1, 'e') == input + n - 2);
      57    ASSERT (RAWMEMCHR (input + 1, 0x789abc00 | 'e') == input + n - 2);
      58  
      59    ASSERT (RAWMEMCHR (input, '\0') == input + n);
      60  
      61    /* Alignment tests.  */
      62    {
      63      int i, j;
      64      for (i = 0; i < 32; i++)
      65        {
      66          for (j = 0; j < 256; j++)
      67            input[i + j] = j;
      68          for (j = 0; j < 256; j++)
      69            {
      70              ASSERT (RAWMEMCHR (input + i, j) == input + i + j);
      71            }
      72        }
      73    }
      74  
      75    /* Ensure that no unaligned oversized reads occur.  */
      76    {
      77      char *page_boundary = (char *) zerosize_ptr ();
      78      size_t i;
      79  
      80      if (!page_boundary)
      81        page_boundary = input + 4096;
      82      memset (page_boundary - 512, '1', 511);
      83      page_boundary[-1] = '2';
      84      for (i = 1; i <= 512; i++)
      85        ASSERT (RAWMEMCHR (page_boundary - i, (i * 0x01010100) | '2')
      86                == page_boundary - 1);
      87    }
      88  
      89    free (input);
      90  
      91    return 0;
      92  }