(root)/
glibc-2.38/
string/
test-strrchr.c
       1  /* Test and measure STRCHR functions.
       2     Copyright (C) 1999-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  #ifdef WIDE
      21  # define TEST_NAME "wcsrchr"
      22  #else
      23  # define TEST_NAME "strrchr"
      24  #endif
      25  #include "test-string.h"
      26  
      27  #ifdef WIDE
      28  # include <wchar.h>
      29  # define STRRCHR wcsrchr
      30  # define CHAR wchar_t
      31  # define UCHAR wchar_t
      32  # define BIG_CHAR WCHAR_MAX
      33  # define SMALL_CHAR 1273
      34  #else
      35  # define STRRCHR strrchr
      36  # define CHAR char
      37  # define UCHAR unsigned char
      38  # define BIG_CHAR CHAR_MAX
      39  # define SMALL_CHAR 127
      40  #endif
      41  
      42  typedef CHAR *(*proto_t) (const CHAR *, int);
      43  
      44  IMPL (STRRCHR, 1)
      45  
      46  /* Also check the generic implementation.  */
      47  #undef STRRCHR
      48  #undef weak_alias
      49  #define weak_alias(a, b)
      50  #undef libc_hidden_builtin_def
      51  #define libc_hidden_builtin_def(a)
      52  #undef libc_hidden_def
      53  #define libc_hidden_def(a)
      54  #undef libc_hidden_weak
      55  #define libc_hidden_weak(a)
      56  #ifndef WIDE
      57  # define STRLEN __strlen_default
      58  # include "string/strlen.c"
      59  # define MEMRCHR __memrchr_default
      60  # include "string/memrchr.c"
      61  # define STRRCHR __strrchr_default
      62  # include "string/strrchr.c"
      63  # define STRRCHR_DEFAULT __strrchr_default
      64  #else
      65  # define WCSRCHR __wcsrchr_default
      66  # include "wcsmbs/wcsrchr.c"
      67  # define STRRCHR_DEFAULT __wcsrchr_default
      68  #endif
      69  IMPL (STRRCHR_DEFAULT, 1)
      70  
      71  static void
      72  do_one_test (impl_t *impl, const CHAR *s, int c, CHAR *exp_res)
      73  {
      74    CHAR *res = CALL (impl, s, c);
      75    if (res != exp_res)
      76      {
      77        error (0, 0, "Wrong result in function %s %p %p", impl->name,
      78  	     res, exp_res);
      79        ret = 1;
      80        return;
      81      }
      82  }
      83  
      84  static void
      85  do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
      86  /* For wcsrchr: align here means align not in bytes,
      87     but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
      88     len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
      89  {
      90    size_t i;
      91    CHAR *result;
      92    CHAR *buf = (CHAR *) buf1;
      93  
      94    align &= 7;
      95    if ( (align + len) * sizeof (CHAR) >= page_size)
      96      return;
      97  
      98    for (i = 0; i < len; ++i)
      99      {
     100        buf[align + i] = (random () * random ()) & max_char;
     101        if (!buf[align + i])
     102  	buf[align + i] = (random () * random ()) & max_char;
     103        if (!buf[align + i])
     104  	buf[align + i] = 1;
     105        if ((i > pos || pos >= len) && buf[align + i] == seek_char)
     106  	buf[align + i] = seek_char + 10 + (random () & 15);
     107      }
     108    buf[align + len] = 0;
     109  
     110    if (pos < len)
     111      {
     112        buf[align + pos] = seek_char;
     113        result = (CHAR *) (buf + align + pos);
     114      }
     115    else if (seek_char == 0)
     116      result = (CHAR *) (buf + align + len);
     117    else
     118      result = NULL;
     119  
     120    FOR_EACH_IMPL (impl, 0)
     121      do_one_test (impl, (CHAR *) (buf + align), seek_char, result);
     122  }
     123  
     124  static void
     125  do_random_tests (void)
     126  {
     127    size_t i, j, n, align, pos, len;
     128    int seek_char;
     129    CHAR *result;
     130    UCHAR *p = (UCHAR *) (buf1 + page_size) - 512;
     131  
     132    for (n = 0; n < ITERATIONS; n++)
     133      {
     134        align = random () & (63 / sizeof (CHAR));
     135        /* For wcsrchr: align here means align not in bytes, but in wchar_ts,
     136  	 in bytes it will equal to align * (sizeof (wchar_t)).
     137  	 For strrchr we need to check all alignments from 0 to 63 since
     138  	 some assembly implementations have separate prolog for alignments
     139  	 more 48. */
     140        pos = random () & 511;
     141        if (pos + align >= 511)
     142  	pos = 510 - align - (random () & 7);
     143        len = random () & 511;
     144        /* len for wcschr here isn't in bytes but it's number of wchar_t
     145  	 symbols.  */
     146        if (pos >= len)
     147  	len = pos + (random () & 7);
     148        if (len + align >= 512)
     149  	len = 511 - align - (random () & 7);
     150        seek_char = random () & 255;
     151        if (seek_char && pos == len)
     152  	{
     153  	  if (pos)
     154  	    --pos;
     155  	  else
     156  	    ++len;
     157  	}
     158        j = len + align + 64;
     159        if (j > 512)
     160  	j = 512;
     161  
     162        for (i = 0; i < j; i++)
     163  	{
     164  	  if (i == pos + align)
     165  	    p[i] = seek_char;
     166  	  else if (i == len + align)
     167  	    p[i] = 0;
     168  	  else
     169  	    {
     170  	      p[i] = random () & 255;
     171  	      if (((i > pos + align && i < len + align) || pos > len)
     172  		  && p[i] == seek_char)
     173  		p[i] = seek_char + 13;
     174  	      if (i < len + align && !p[i])
     175  		{
     176  		  p[i] = seek_char - 13;
     177  		  if (!p[i])
     178  		    p[i] = 140;
     179  		}
     180  	    }
     181  	}
     182  
     183        if (pos <= len)
     184  	result = (CHAR *) (p + pos + align);
     185        else if (seek_char == 0)
     186  	result = (CHAR *) (p + len + align);
     187        else
     188  	result = NULL;
     189  
     190        FOR_EACH_IMPL (impl, 1)
     191  	if (CALL (impl, (CHAR *) (p + align), seek_char) != result)
     192  	  {
     193  	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
     194  		   n, impl->name, align, seek_char, len, pos,
     195  		   CALL (impl, (CHAR *) (p + align), seek_char), result, p);
     196  	    ret = 1;
     197  	  }
     198      }
     199  }
     200  
     201  int
     202  test_main (void)
     203  {
     204    size_t i;
     205  
     206    test_init ();
     207  
     208    printf ("%20s", "");
     209    FOR_EACH_IMPL (impl, 0)
     210      printf ("\t%s", impl->name);
     211    putchar ('\n');
     212  
     213    for (i = 1; i < 8; ++i)
     214      {
     215        do_test (0, 16 << i, 2048, 23, SMALL_CHAR);
     216        do_test (i, 16 << i, 2048, 23, SMALL_CHAR);
     217      }
     218  
     219    for (i = 1; i < 8; ++i)
     220      {
     221        do_test (i, 64, 256, 23, SMALL_CHAR);
     222        do_test (i, 64, 256, 23, BIG_CHAR);
     223      }
     224  
     225    for (i = 0; i < 32; ++i)
     226      {
     227        do_test (0, i, i + 1, 23, SMALL_CHAR);
     228        do_test (0, i, i + 1, 23, BIG_CHAR);
     229      }
     230  
     231    for (i = 1; i < 8; ++i)
     232      {
     233        do_test (0, 16 << i, 2048, 0, SMALL_CHAR);
     234        do_test (i, 16 << i, 2048, 0, SMALL_CHAR);
     235      }
     236  
     237    for (i = 1; i < 8; ++i)
     238      {
     239        do_test (i, 64, 256, 0, SMALL_CHAR);
     240        do_test (i, 64, 256, 0, BIG_CHAR);
     241      }
     242  
     243    for (i = 0; i < 32; ++i)
     244      {
     245        do_test (0, i, i + 1, 0, SMALL_CHAR);
     246        do_test (0, i, i + 1, 0, BIG_CHAR);
     247      }
     248  
     249    do_random_tests ();
     250    return ret;
     251  }
     252  
     253  #include <support/test-driver.c>