test-strchr.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /* Test STRCHR functions.
  2. Copyright (C) 1999-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Written by Jakub Jelinek <jakub@redhat.com>, 1999.
  5. Added wcschr support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011
  6. The GNU C Library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Lesser General Public
  8. License as published by the Free Software Foundation; either
  9. version 2.1 of the License, or (at your option) any later version.
  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. You should have received a copy of the GNU Lesser General Public
  15. License along with the GNU C Library; if not, see
  16. <http://www.gnu.org/licenses/>. */
  17. #define TEST_MAIN
  18. #ifndef WIDE
  19. # ifdef USE_FOR_STRCHRNUL
  20. # define TEST_NAME "strchrnul"
  21. # else
  22. # define TEST_NAME "strchr"
  23. # endif /* !USE_FOR_STRCHRNUL */
  24. #else
  25. # ifdef USE_FOR_STRCHRNUL
  26. # define TEST_NAME "wcschrnul"
  27. # else
  28. # define TEST_NAME "wcschr"
  29. # endif /* !USE_FOR_STRCHRNUL */
  30. #endif /* WIDE */
  31. #include "test-string.h"
  32. #ifndef WIDE
  33. # ifdef USE_FOR_STRCHRNUL
  34. # define STRCHR strchrnul
  35. # define stupid_STRCHR stupid_STRCHRNUL
  36. # define simple_STRCHR simple_STRCHRNUL
  37. # else
  38. # define STRCHR strchr
  39. # endif /* !USE_FOR_STRCHRNUL */
  40. # define STRLEN strlen
  41. # define CHAR char
  42. # define BIG_CHAR CHAR_MAX
  43. # define MIDDLE_CHAR 127
  44. # define SMALL_CHAR 23
  45. # define UCHAR unsigned char
  46. # define L(s) s
  47. #else
  48. # include <wchar.h>
  49. # ifdef USE_FOR_STRCHRNUL
  50. # define STRCHR wcschrnul
  51. # define stupid_STRCHR stupid_WCSCHRNUL
  52. # define simple_STRCHR simple_WCSCHRNUL
  53. # else
  54. # define STRCHR wcschr
  55. # endif /* !USE_FOR_STRCHRNUL */
  56. # define STRLEN wcslen
  57. # define CHAR wchar_t
  58. # define BIG_CHAR WCHAR_MAX
  59. # define MIDDLE_CHAR 1121
  60. # define SMALL_CHAR 851
  61. # define UCHAR wchar_t
  62. # define L(s) L ## s
  63. #endif /* WIDE */
  64. #ifdef USE_FOR_STRCHRNUL
  65. # define NULLRET(endptr) endptr
  66. #else
  67. # define NULLRET(endptr) NULL
  68. #endif /* !USE_FOR_STRCHRNUL */
  69. typedef CHAR *(*proto_t) (const CHAR *, int);
  70. CHAR *
  71. simple_STRCHR (const CHAR *s, int c)
  72. {
  73. for (; *s != (CHAR) c; ++s)
  74. if (*s == '\0')
  75. return NULLRET ((CHAR *) s);
  76. return (CHAR *) s;
  77. }
  78. CHAR *
  79. stupid_STRCHR (const CHAR *s, int c)
  80. {
  81. size_t n = STRLEN (s) + 1;
  82. while (n--)
  83. if (*s++ == (CHAR) c)
  84. return (CHAR *) s - 1;
  85. return NULLRET ((CHAR *) s - 1);
  86. }
  87. IMPL (stupid_STRCHR, 0)
  88. IMPL (simple_STRCHR, 0)
  89. IMPL (STRCHR, 1)
  90. static int
  91. check_result (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
  92. {
  93. CHAR *res = CALL (impl, s, c);
  94. if (res != exp_res)
  95. {
  96. error (0, 0, "Wrong result in function %s %#x %p %p", impl->name,
  97. c, res, exp_res);
  98. ret = 1;
  99. return -1;
  100. }
  101. return 0;
  102. }
  103. static void
  104. do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
  105. {
  106. if (check_result (impl, s, c, exp_res) < 0)
  107. return;
  108. }
  109. static void
  110. do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
  111. /* For wcschr: align here means align not in bytes,
  112. but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
  113. len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
  114. {
  115. size_t i;
  116. CHAR *result;
  117. CHAR *buf = (CHAR *) buf1;
  118. align &= 15;
  119. if ((align + len) * sizeof (CHAR) >= page_size)
  120. return;
  121. for (i = 0; i < len; ++i)
  122. {
  123. buf[align + i] = 32 + 23 * i % max_char;
  124. if (buf[align + i] == seek_char)
  125. buf[align + i] = seek_char + 1;
  126. else if (buf[align + i] == 0)
  127. buf[align + i] = 1;
  128. }
  129. buf[align + len] = 0;
  130. if (pos < len)
  131. {
  132. buf[align + pos] = seek_char;
  133. result = buf + align + pos;
  134. }
  135. else if (seek_char == 0)
  136. result = buf + align + len;
  137. else
  138. result = NULLRET (buf + align + len);
  139. FOR_EACH_IMPL (impl, 0)
  140. do_one_test (impl, buf + align, seek_char, result);
  141. }
  142. static void
  143. do_random_tests (void)
  144. {
  145. size_t i, j, n, align, pos, len;
  146. int seek_char;
  147. CHAR *result;
  148. UCHAR *p = (UCHAR *) (buf1 + page_size - 512 * sizeof (CHAR));
  149. for (n = 0; n < ITERATIONS; n++)
  150. {
  151. /* For wcschr: align here means align not in bytes, but in wchar_ts,
  152. in bytes it will equal to align * (sizeof (wchar_t)). */
  153. align = random () & 15;
  154. pos = random () & 511;
  155. seek_char = random () & 255;
  156. if (pos + align >= 511)
  157. pos = 510 - align - (random () & 7);
  158. /* len for wcschr here isn't in bytes but it's number of wchar_t
  159. symbols. */
  160. len = random () & 511;
  161. if ((pos == len && seek_char)
  162. || (pos > len && (random () & 1)))
  163. len = pos + 1 + (random () & 7);
  164. if (len + align >= 512)
  165. len = 511 - align - (random () & 7);
  166. if (pos == len && seek_char)
  167. len = pos + 1;
  168. j = (pos > len ? pos : len) + align + 64;
  169. if (j > 512)
  170. j = 512;
  171. for (i = 0; i < j; i++)
  172. {
  173. if (i == pos + align)
  174. p[i] = seek_char;
  175. else if (i == len + align)
  176. p[i] = 0;
  177. else
  178. {
  179. p[i] = random () & 255;
  180. if (i < pos + align && p[i] == seek_char)
  181. p[i] = seek_char + 13;
  182. if (i < len + align && !p[i])
  183. {
  184. p[i] = seek_char - 13;
  185. if (!p[i])
  186. p[i] = 140;
  187. }
  188. }
  189. }
  190. if (pos <= len)
  191. result = (CHAR *) (p + pos + align);
  192. else if (seek_char == 0)
  193. result = (CHAR *) (p + len + align);
  194. else
  195. result = NULLRET ((CHAR *) (p + len + align));
  196. FOR_EACH_IMPL (impl, 1)
  197. if (CALL (impl, (CHAR *) (p + align), seek_char) != result)
  198. {
  199. error (0, 0, "Iteration %zd - wrong result in function \
  200. %s (align in bytes: %zd, seek_char: %d, len: %zd, pos: %zd) %p != %p, p %p",
  201. n, impl->name, align * sizeof (CHAR), seek_char, len, pos,
  202. CALL (impl, (CHAR *) (p + align), seek_char), result, p);
  203. ret = 1;
  204. }
  205. }
  206. }
  207. static void
  208. check1 (void)
  209. {
  210. CHAR s[] __attribute__((aligned(16))) = L ("\xff");
  211. CHAR c = L ('\xfe');
  212. CHAR *exp_result = stupid_STRCHR (s, c);
  213. FOR_EACH_IMPL (impl, 0)
  214. check_result (impl, s, c, exp_result);
  215. }
  216. int
  217. test_main (void)
  218. {
  219. size_t i;
  220. test_init ();
  221. check1 ();
  222. printf ("%20s", "");
  223. FOR_EACH_IMPL (impl, 0)
  224. printf ("\t%s", impl->name);
  225. putchar ('\n');
  226. for (i = 1; i < 8; ++i)
  227. {
  228. do_test (0, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
  229. do_test (i, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
  230. }
  231. for (i = 1; i < 8; ++i)
  232. {
  233. do_test (i, 64, 256, SMALL_CHAR, MIDDLE_CHAR);
  234. do_test (i, 64, 256, SMALL_CHAR, BIG_CHAR);
  235. }
  236. for (i = 0; i < 32; ++i)
  237. {
  238. do_test (0, i, i + 1, SMALL_CHAR, MIDDLE_CHAR);
  239. do_test (0, i, i + 1, SMALL_CHAR, BIG_CHAR);
  240. }
  241. for (i = 1; i < 8; ++i)
  242. {
  243. do_test (0, 16 << i, 2048, 0, MIDDLE_CHAR);
  244. do_test (i, 16 << i, 2048, 0, MIDDLE_CHAR);
  245. }
  246. for (i = 1; i < 8; ++i)
  247. {
  248. do_test (i, 64, 256, 0, MIDDLE_CHAR);
  249. do_test (i, 64, 256, 0, BIG_CHAR);
  250. }
  251. for (i = 0; i < 32; ++i)
  252. {
  253. do_test (0, i, i + 1, 0, MIDDLE_CHAR);
  254. do_test (0, i, i + 1, 0, BIG_CHAR);
  255. }
  256. do_random_tests ();
  257. return ret;
  258. }
  259. #include <support/test-driver.c>