test-strdup.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* Test and measure strdup functions.
  2. Copyright (C) 2023-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <support/check.h>
  16. #ifdef WIDE
  17. # include <wchar.h>
  18. # define CHAR wchar_t
  19. # define sfmt "ls"
  20. # define BIG_CHAR WCHAR_MAX
  21. # define SMALL_CHAR 1273
  22. # define STRCMP wcscmp
  23. # define MEMCMP wmemcmp
  24. # define MEMSET wmemset
  25. # define TCS TEST_COMPARE_STRING_WIDE
  26. #else
  27. # define CHAR char
  28. # define sfmt "s"
  29. # define BIG_CHAR CHAR_MAX
  30. # define SMALL_CHAR 127
  31. # define STRCMP strcmp
  32. # define MEMCMP memcmp
  33. # define MEMSET memset
  34. # define TCS TEST_COMPARE_STRING
  35. #endif
  36. #ifndef STRDUP_RESULT
  37. # define STRDUP_RESULT(dst, len) dst
  38. # define TEST_MAIN
  39. # ifndef WIDE
  40. # define TEST_NAME "strdup"
  41. # else
  42. # define TEST_NAME "wcsdup"
  43. # endif
  44. # include "test-string.h"
  45. # ifndef WIDE
  46. # define STRDUP strdup
  47. # else
  48. # define STRDUP wcsdup
  49. # endif
  50. #endif
  51. typedef CHAR *(*proto_t) (const CHAR *);
  52. static void
  53. do_zero_len_test (void)
  54. {
  55. CHAR src[1] = { '\0' };
  56. CHAR *dst = STRDUP (src);
  57. TCS (dst, src);
  58. free (dst);
  59. }
  60. static void
  61. do_one_test (const CHAR *src,
  62. size_t len __attribute__((unused)))
  63. {
  64. CHAR *dst = STRDUP (src);
  65. if (STRCMP (dst, src) != 0)
  66. {
  67. error (0, 0,
  68. "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
  69. TEST_NAME, dst, src);
  70. ret = 1;
  71. free (dst);
  72. return;
  73. }
  74. free (dst);
  75. }
  76. static void
  77. do_test (size_t align1, size_t align2, size_t len, int max_char)
  78. {
  79. size_t i;
  80. CHAR *s1;
  81. /* For wcsdup: align1 and align2 here mean alignment not in bytes,
  82. but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
  83. len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
  84. align1 &= 7;
  85. if ((align1 + len) * sizeof (CHAR) >= page_size)
  86. return;
  87. align2 &= 7;
  88. if ((align2 + len) * sizeof (CHAR) >= page_size)
  89. return;
  90. s1 = (CHAR *) (buf1) + align1;
  91. for (i = 0; i < len; i++)
  92. s1[i] = 32 + 23 * i % (max_char - 32);
  93. s1[len] = 0;
  94. do_one_test (s1, len);
  95. }
  96. static void
  97. do_random_tests (void)
  98. {
  99. size_t i, j, n, align1, align2, len;
  100. CHAR *p1 = (CHAR *)(buf1 + page_size) - 512;
  101. CHAR *res;
  102. for (n = 0; n < ITERATIONS; n++)
  103. {
  104. /* align1 and align2 are expressed as wchar_t and not in bytes for wide
  105. char test, and thus it will be equal to align times wchar_t size.
  106. For non wide version we need to check all alignments from 0 to 63
  107. since some assembly implementations have separate prolog for alignments
  108. more 48. */
  109. align1 = random () & (63 / sizeof (CHAR));
  110. if (random () & 1)
  111. align2 = random () & (63 / sizeof (CHAR));
  112. else
  113. align2 = align1 + (random () & 24);
  114. len = random () & 511;
  115. j = align1;
  116. if (align2 > j)
  117. j = align2;
  118. if (len + j >= 511)
  119. len = 510 - j - (random () & 7);
  120. j = len + align1 + 64;
  121. if (j > 512)
  122. j = 512;
  123. for (i = 0; i < j; i++)
  124. {
  125. if (i == len + align1)
  126. p1[i] = 0;
  127. else
  128. {
  129. p1[i] = random () & BIG_CHAR;
  130. if (i >= align1 && i < len + align1 && !p1[i])
  131. p1[i] = (random () & SMALL_CHAR) + 3;
  132. }
  133. }
  134. res = STRDUP(p1 + align1);
  135. TCS (res, (p1 + align1));
  136. free (res);
  137. }
  138. }
  139. int
  140. test_main (void)
  141. {
  142. size_t i;
  143. test_init ();
  144. printf ("%23s", "");
  145. printf ("\t%s", TEST_NAME);
  146. putchar ('\n');
  147. for (i = 0; i < 16; ++i)
  148. {
  149. do_test (0, 0, i, SMALL_CHAR);
  150. do_test (0, 0, i, BIG_CHAR);
  151. do_test (0, i, i, SMALL_CHAR);
  152. do_test (i, 0, i, BIG_CHAR);
  153. }
  154. for (i = 1; i < 8; ++i)
  155. {
  156. do_test (0, 0, 8 << i, SMALL_CHAR);
  157. do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
  158. }
  159. for (i = 1; i < 8; ++i)
  160. {
  161. do_test (i, 2 * i, 8 << i, SMALL_CHAR);
  162. do_test (2 * i, i, 8 << i, BIG_CHAR);
  163. do_test (i, i, 8 << i, SMALL_CHAR);
  164. do_test (i, i, 8 << i, BIG_CHAR);
  165. }
  166. do_zero_len_test ();
  167. do_random_tests ();
  168. return ret;
  169. }
  170. #include <support/test-driver.c>