(root)/
glibc-2.38/
string/
test-strdup.c
       1  /* Test and measure strdup functions.
       2     Copyright (C) 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  #include <support/check.h>
      20  
      21  #ifdef WIDE
      22  # include <wchar.h>
      23  # define CHAR wchar_t
      24  # define sfmt "ls"
      25  # define BIG_CHAR WCHAR_MAX
      26  # define SMALL_CHAR 1273
      27  # define STRCMP wcscmp
      28  # define MEMCMP wmemcmp
      29  # define MEMSET wmemset
      30  # define TCS TEST_COMPARE_STRING_WIDE
      31  #else
      32  # define CHAR char
      33  # define sfmt "s"
      34  # define BIG_CHAR CHAR_MAX
      35  # define SMALL_CHAR 127
      36  # define STRCMP strcmp
      37  # define MEMCMP memcmp
      38  # define MEMSET memset
      39  # define TCS TEST_COMPARE_STRING
      40  #endif
      41  
      42  #ifndef STRDUP_RESULT
      43  # define STRDUP_RESULT(dst, len) dst
      44  # define TEST_MAIN
      45  # ifndef WIDE
      46  #  define TEST_NAME "strdup"
      47  # else
      48  #  define TEST_NAME "wcsdup"
      49  # endif
      50  # include "test-string.h"
      51  # ifndef WIDE
      52  #  define STRDUP strdup
      53  # else
      54  #  define STRDUP wcsdup
      55  # endif
      56  #endif
      57  
      58  typedef CHAR *(*proto_t) (const CHAR *);
      59  
      60  static void
      61  do_zero_len_test (void)
      62  {
      63    CHAR src[1] = { '\0' };
      64    CHAR *dst = STRDUP (src);
      65  
      66    TCS (dst, src);
      67    free (dst);
      68  }
      69  
      70  static void
      71  do_one_test (const CHAR *src,
      72  	     size_t len __attribute__((unused)))
      73  {
      74    CHAR *dst = STRDUP (src);
      75  
      76    if (STRCMP (dst, src) != 0)
      77      {
      78        error (0, 0,
      79  	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
      80  	     TEST_NAME, dst, src);
      81        ret = 1;
      82        free (dst);
      83        return;
      84      }
      85    free (dst);
      86  }
      87  
      88  static void
      89  do_test (size_t align1, size_t align2, size_t len, int max_char)
      90  {
      91    size_t i;
      92    CHAR *s1;
      93  /* For wcsdup: align1 and align2 here mean alignment not in bytes,
      94     but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
      95     len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
      96    align1 &= 7;
      97    if ((align1 + len) * sizeof (CHAR) >= page_size)
      98      return;
      99  
     100    align2 &= 7;
     101    if ((align2 + len) * sizeof (CHAR) >= page_size)
     102      return;
     103  
     104    s1 = (CHAR *) (buf1) + align1;
     105  
     106    for (i = 0; i < len; i++)
     107      s1[i] = 32 + 23 * i % (max_char - 32);
     108    s1[len] = 0;
     109  
     110    do_one_test (s1, len);
     111  }
     112  
     113  static void
     114  do_random_tests (void)
     115  {
     116    size_t i, j, n, align1, align2, len;
     117    CHAR *p1 = (CHAR *)(buf1 + page_size) - 512;
     118    CHAR *res;
     119  
     120    for (n = 0; n < ITERATIONS; n++)
     121      {
     122        /* align1 and align2 are expressed as wchar_t and not in bytes for wide
     123       char test, and thus it will be equal to align times wchar_t size.
     124  
     125       For non wide version we need to check all alignments from 0 to 63
     126       since some assembly implementations have separate prolog for alignments
     127       more 48.  */
     128  
     129        align1 = random () & (63 / sizeof (CHAR));
     130        if (random () & 1)
     131  	align2 = random () & (63 / sizeof (CHAR));
     132        else
     133  	align2 = align1 + (random () & 24);
     134        len = random () & 511;
     135        j = align1;
     136        if (align2 > j)
     137  	j = align2;
     138        if (len + j >= 511)
     139  	len = 510 - j - (random () & 7);
     140        j = len + align1 + 64;
     141        if (j > 512)
     142  	j = 512;
     143        for (i = 0; i < j; i++)
     144  	{
     145  	  if (i == len + align1)
     146  	    p1[i] = 0;
     147  	  else
     148  	    {
     149  	      p1[i] = random () & BIG_CHAR;
     150  	      if (i >= align1 && i < len + align1 && !p1[i])
     151  		p1[i] = (random () & SMALL_CHAR) + 3;
     152  	    }
     153  	}
     154  
     155        res =  STRDUP(p1 + align1);
     156        TCS (res, (p1 + align1));
     157        free (res);
     158      }
     159  }
     160  
     161  
     162  int
     163  test_main (void)
     164  {
     165    size_t i;
     166  
     167    test_init ();
     168  
     169    printf ("%23s", "");
     170    printf ("\t%s", TEST_NAME);
     171    putchar ('\n');
     172  
     173    for (i = 0; i < 16; ++i)
     174      {
     175        do_test (0, 0, i, SMALL_CHAR);
     176        do_test (0, 0, i, BIG_CHAR);
     177        do_test (0, i, i, SMALL_CHAR);
     178        do_test (i, 0, i, BIG_CHAR);
     179      }
     180  
     181    for (i = 1; i < 8; ++i)
     182      {
     183        do_test (0, 0, 8 << i, SMALL_CHAR);
     184        do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
     185      }
     186  
     187    for (i = 1; i < 8; ++i)
     188      {
     189        do_test (i, 2 * i, 8 << i, SMALL_CHAR);
     190        do_test (2 * i, i, 8 << i, BIG_CHAR);
     191        do_test (i, i, 8 << i, SMALL_CHAR);
     192        do_test (i, i, 8 << i, BIG_CHAR);
     193      }
     194  
     195    do_zero_len_test ();
     196    do_random_tests ();
     197  
     198    return ret;
     199  }
     200  
     201  #include <support/test-driver.c>