(root)/
glibc-2.38/
string/
test-memrchr.c
       1  /* Test and measure memrchr functions.
       2     Copyright (C) 2013-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library 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 GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #define TEST_MAIN
      20  #define TEST_NAME "memrchr"
      21  #include "test-string.h"
      22  
      23  typedef char *(*proto_t) (const char *, int, size_t);
      24  
      25  IMPL (memrchr, 1)
      26  
      27  /* Also check the generic implementation.  */
      28  #undef weak_alias
      29  #define weak_alias(a, b)
      30  #define MEMRCHR __memrchr_default
      31  #include "string/memrchr.c"
      32  IMPL (__memrchr_default, 1)
      33  
      34  /* Naive implementation to verify results.  */
      35  char *
      36  simple_memrchr (const char *s, int c, size_t n)
      37  {
      38    s = s + n;
      39    while (n--)
      40      if (*--s == (char) c)
      41        return (char *) s;
      42    return NULL;
      43  }
      44  
      45  static void
      46  do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res)
      47  {
      48    char *res = CALL (impl, s, c, n);
      49    if (res != exp_res)
      50      {
      51        error (0, 0, "Wrong result in function %s %p %p", impl->name,
      52  	     res, exp_res);
      53        ret = 1;
      54        return;
      55      }
      56  }
      57  
      58  static void
      59  do_test (size_t align, size_t pos, size_t len, int seek_char)
      60  {
      61    size_t i;
      62    char *result;
      63  
      64    align &= 7;
      65    if (align + len >= page_size)
      66      return;
      67  
      68    for (i = 0; i < len; ++i)
      69      {
      70        buf1[align + i] = 1 + 23 * i % 127;
      71        if (buf1[align + i] == seek_char)
      72          buf1[align + i] = seek_char + 1;
      73      }
      74    buf1[align + len] = 0;
      75  
      76    if (pos < len)
      77      {
      78        buf1[align + pos] = seek_char;
      79        buf1[align + len] = -seek_char;
      80        result = (char *) (buf1 + align + pos);
      81      }
      82    else
      83      {
      84        result = NULL;
      85        buf1[align + len] = seek_char;
      86      }
      87  
      88    FOR_EACH_IMPL (impl, 0)
      89      do_one_test (impl, (char *) (buf1 + align), seek_char, len, result);
      90  }
      91  
      92  static void
      93  do_random_tests (void)
      94  {
      95    size_t i, j, n, align, pos, len;
      96    int seek_char;
      97    char *result;
      98    unsigned char *p = buf1 + page_size - 512;
      99  
     100    for (n = 0; n < ITERATIONS; n++)
     101      {
     102        align = random () & 15;
     103        pos = random () & 511;
     104        if (pos + align >= 512)
     105  	pos = 511 - align - (random () & 7);
     106        len = random () & 511;
     107        if (pos >= len)
     108  	len = pos + (random () & 7);
     109        if (len + align >= 512)
     110          len = 512 - align - (random () & 7);
     111        seek_char = random () & 255;
     112        j = len + align + 64;
     113        if (j > 512)
     114          j = 512;
     115  
     116        for (i = 0; i < j; i++)
     117  	{
     118  	  if (i == pos + align)
     119  	    p[i] = seek_char;
     120  	  else
     121  	    {
     122  	      p[i] = random () & 255;
     123  	      if (p[i] == seek_char)
     124  		p[i] = seek_char + 13;
     125  	    }
     126  	}
     127  
     128        if (pos < len)
     129  	result = (char *) (p + pos + align);
     130        else
     131  	result = NULL;
     132  
     133        FOR_EACH_IMPL (impl, 1)
     134  	if (CALL (impl, (char *) (p + align), seek_char, len) != result)
     135  	  {
     136  	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
     137  		   n, impl->name, align, seek_char, len, pos,
     138  		   CALL (impl, (char *) (p + align), seek_char, len),
     139  		   result, p);
     140  	    ret = 1;
     141  	  }
     142      }
     143  }
     144  
     145  int
     146  test_main (void)
     147  {
     148    size_t i;
     149  
     150    test_init ();
     151  
     152    printf ("%20s", "");
     153    FOR_EACH_IMPL (impl, 0)
     154      printf ("\t%s", impl->name);
     155    putchar ('\n');
     156  
     157    for (i = 1; i < 8; ++i)
     158      {
     159        /* Test len == 0.  */
     160        do_test (i, i, 0, 0);
     161        do_test (i, i, 0, 23);
     162  
     163        do_test (0, 16 << i, 2048, 23);
     164        do_test (i, 64, 256, 23);
     165        do_test (0, 16 << i, 2048, 0);
     166        do_test (i, 64, 256, 0);
     167  
     168        do_test (0, i, 256, 23);
     169        do_test (0, i, 256, 0);
     170        do_test (i, i, 256, 23);
     171        do_test (i, i, 256, 0);
     172  
     173      }
     174    for (i = 1; i < 32; ++i)
     175      {
     176        do_test (0, i, i + 1, 23);
     177        do_test (0, i, i + 1, 0);
     178        do_test (i, i, i + 1, 23);
     179        do_test (i, i, i + 1, 0);
     180  
     181        do_test (0, 1, i + 1, 23);
     182        do_test (0, 2, i + 1, 0);
     183        do_test (i, 1, i + 1, 23);
     184        do_test (i, 2, i + 1, 0);
     185      }
     186  
     187    do_random_tests ();
     188    return ret;
     189  }
     190  
     191  #include <support/test-driver.c>