(root)/
grep-3.11/
gnulib-tests/
test-memrchr.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 (memrchr, void *, (void const *, int, size_t));
      24  
      25  #include <stdlib.h>
      26  
      27  #include "zerosize-ptr.h"
      28  #include "macros.h"
      29  
      30  /* Work around GCC bug 101494.  */
      31  #if 4 < __GNUC__ + (7 <= __GNUC_MINOR__) && __GNUC__ < 12
      32  # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
      33  #endif
      34  
      35  /* Calculating void * + int is not portable, so this wrapper converts
      36     to char * to make the tests easier to write.  */
      37  #define MEMRCHR (char *) memrchr
      38  
      39  int
      40  main (void)
      41  {
      42    size_t n = 0x100000;
      43    char *input = malloc (n);
      44    ASSERT (input);
      45  
      46    input[n - 1] = 'a';
      47    input[n - 2] = 'b';
      48    memset (input + n - 1026, 'c', 1024);
      49    memset (input + 2, 'd', n - 1028);
      50    input[1] = 'e';
      51    input[0] = 'a';
      52  
      53    /* Basic behavior tests.  */
      54    ASSERT (MEMRCHR (input, 'a', n) == input + n - 1);
      55  
      56    ASSERT (MEMRCHR (input, 'a', 0) == NULL);
      57    void *page_boundary = zerosize_ptr ();
      58    if (page_boundary)
      59      ASSERT (MEMRCHR (page_boundary, 'a', 0) == NULL);
      60  
      61    ASSERT (MEMRCHR (input, 'b', n) == input + n - 2);
      62    ASSERT (MEMRCHR (input, 'c', n) == input + n - 3);
      63    ASSERT (MEMRCHR (input, 'd', n) == input + n - 1027);
      64  
      65    ASSERT (MEMRCHR (input, 'a', n - 1) == input);
      66    ASSERT (MEMRCHR (input, 'e', n - 1) == input + 1);
      67  
      68    ASSERT (MEMRCHR (input, 'f', n) == NULL);
      69    ASSERT (MEMRCHR (input, '\0', n) == NULL);
      70  
      71    /* Check that a very long haystack is handled quickly if the byte is
      72       found near the end.  */
      73    {
      74      size_t repeat = 10000;
      75      for (; repeat > 0; repeat--)
      76        {
      77          ASSERT (MEMRCHR (input, 'c', n) == input + n - 3);
      78        }
      79    }
      80  
      81    /* Alignment tests.  */
      82    {
      83      int i, j;
      84      for (i = 0; i < 32; i++)
      85        {
      86          for (j = 0; j < 256; j++)
      87            input[i + j] = j;
      88          for (j = 0; j < 256; j++)
      89            {
      90              ASSERT (MEMRCHR (input + i, j, 256) == input + i + j);
      91            }
      92        }
      93    }
      94  
      95    free (input);
      96  
      97    return 0;
      98  }