(root)/
glibc-2.38/
string/
test-strlen.c
       1  /* Test and measure STRLEN 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  #ifndef WIDE
      21  # define TEST_NAME "strlen"
      22  #else
      23  # define TEST_NAME "wcslen"
      24  #endif
      25  #include "test-string.h"
      26  
      27  #ifndef WIDE
      28  # define STRLEN strlen
      29  # define CHAR char
      30  # define MAX_CHAR CHAR_MAX
      31  #else
      32  # include <wchar.h>
      33  # define STRLEN wcslen
      34  # define CHAR wchar_t
      35  # define MAX_CHAR WCHAR_MAX
      36  #endif
      37  
      38  typedef size_t (*proto_t) (const CHAR *);
      39  
      40  IMPL (STRLEN, 1)
      41  
      42  /* Also check the generic implementation.  */
      43  #undef STRLEN
      44  #undef weak_alias
      45  #define weak_alias(a, b)
      46  #undef libc_hidden_builtin_def
      47  #define libc_hidden_builtin_def(a)
      48  #ifndef WIDE
      49  # define STRLEN __strlen_default
      50  # include "string/strlen.c"
      51  IMPL (__strlen_default, 1)
      52  #else
      53  # define WCSLEN __wcslen_default
      54  # include "wcsmbs/wcslen.c"
      55  IMPL (__wcslen_default, 1)
      56  #endif
      57  
      58  
      59  static void
      60  do_one_test (impl_t *impl, const CHAR *s, size_t exp_len)
      61  {
      62    size_t len = CALL (impl, s);
      63    if (len != exp_len)
      64      {
      65        error (0, 0, "Wrong result in function %s %zd %zd", impl->name,
      66  	     len, exp_len);
      67        ret = 1;
      68        return;
      69      }
      70  }
      71  
      72  static void
      73  do_test (size_t align, size_t len)
      74  {
      75    size_t i;
      76  
      77    align &= (getpagesize () / sizeof (CHAR)) - 1;
      78    if (align + sizeof (CHAR) * len >= page_size)
      79      return;
      80  
      81    CHAR *buf = (CHAR *) (buf1);
      82  
      83    for (i = 0; i < len; ++i)
      84      buf[align + i] = 1 + 11111 * i % MAX_CHAR;
      85    buf[align + len] = 0;
      86  
      87    FOR_EACH_IMPL (impl, 0)
      88      do_one_test (impl, (CHAR *) (buf + align), len);
      89  }
      90  
      91  static void
      92  do_random_tests (void)
      93  {
      94    size_t i, j, n, align, len;
      95    CHAR *p = (CHAR *) (buf1 + page_size - 512 * sizeof (CHAR));
      96  
      97    for (n = 0; n < ITERATIONS; n++)
      98      {
      99        align = random () & 15;
     100        len = random () & 511;
     101        if (len + align > 510)
     102  	len = 511 - align - (random () & 7);
     103        j = len + align + 64;
     104        if (j > 512)
     105  	j = 512;
     106  
     107        for (i = 0; i < j; i++)
     108  	{
     109  	  if (i == len + align)
     110  	    p[i] = 0;
     111  	  else
     112  	    {
     113  	      p[i] = random () & 255;
     114  	      if (i >= align && i < len + align && !p[i])
     115  		p[i] = (random () & 127) + 1;
     116  	    }
     117  	}
     118  
     119        FOR_EACH_IMPL (impl, 1)
     120  	if (CALL (impl, (CHAR *) (p + align)) != len)
     121  	  {
     122  	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd) %zd != %zd, p %p",
     123  		   n, impl->name, align, CALL (impl, (CHAR *) (p + align)),
     124  		   len, p);
     125  	    ret = 1;
     126  	  }
     127      }
     128  }
     129  
     130  int
     131  test_main (void)
     132  {
     133    size_t i;
     134  
     135    test_init ();
     136  
     137    printf ("%20s", "");
     138    FOR_EACH_IMPL (impl, 0)
     139      printf ("\t%s", impl->name);
     140    putchar ('\n');
     141  
     142    /* Checking with only 4 * N alignments for wcslen, other alignments are wrong for wchar_t type arrays*/
     143  
     144    for (i = 1; i < 8; ++i)
     145    {
     146      do_test (sizeof (CHAR) * i, i);
     147      do_test (0, i);
     148    }
     149  
     150    for (i = 2; i <= 12; ++i)
     151      {
     152        do_test (0, 1 << i);
     153        do_test (sizeof (CHAR) * 7, 1 << i);
     154        do_test (sizeof (CHAR) * i, 1 << i);
     155        do_test (sizeof (CHAR) * i, (size_t)((1 << i) / 1.5));
     156      }
     157  
     158    /* Test strings near page boundary */
     159  
     160    size_t maxlength = 64 / sizeof (CHAR) - 1;
     161    size_t pagesize = getpagesize () / sizeof (CHAR);
     162  
     163    for (i = maxlength ; i > 1; --i)
     164      {
     165        /* String stays on the same page.  */
     166        do_test (pagesize - i, i - 1);
     167        /* String crosses page boundary.  */
     168        do_test (pagesize - i, maxlength);
     169      }
     170  
     171    do_random_tests ();
     172    return ret;
     173  }
     174  
     175  #include <support/test-driver.c>