You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /** @file
  25. *
  26. * String self-tests
  27. *
  28. * memcpy() tests are handled separately
  29. */
  30. /* Forcibly enable assertions */
  31. #undef NDEBUG
  32. #include <stdint.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <strings.h>
  37. #include <ipxe/string.h>
  38. #include <ipxe/test.h>
  39. /**
  40. * Perform string self-tests
  41. *
  42. */
  43. static void string_test_exec ( void ) {
  44. /* Test strlen() */
  45. ok ( strlen ( "" ) == 0 );
  46. ok ( strlen ( "Hello" ) == 5 );
  47. ok ( strlen ( "Hello world!" ) == 12 );
  48. ok ( strlen ( "Hello\0world!" ) == 5 );
  49. /* Test strnlen() */
  50. ok ( strnlen ( "", 0 ) == 0 );
  51. ok ( strnlen ( "", 10 ) == 0 );
  52. ok ( strnlen ( "Hello", 0 ) == 0 );
  53. ok ( strnlen ( "Hello", 3 ) == 3 );
  54. ok ( strnlen ( "Hello", 5 ) == 5 );
  55. ok ( strnlen ( "Hello", 16 ) == 5 );
  56. ok ( strnlen ( "Hello world!", 5 ) == 5 );
  57. ok ( strnlen ( "Hello world!", 11 ) == 11 );
  58. ok ( strnlen ( "Hello world!", 16 ) == 12 );
  59. /* Test strchr() */
  60. ok ( strchr ( "", 'a' ) == NULL );
  61. ok ( *(strchr ( "Testing", 'e' )) == 'e' );
  62. ok ( *(strchr ( "Testing", 'g' )) == 'g' );
  63. ok ( strchr ( "Testing", 'x' ) == NULL );
  64. /* Test strrchr() */
  65. ok ( strrchr ( "", 'a' ) == NULL );
  66. ok ( *(strrchr ( "Haystack", 'a' )) == 'a' );
  67. ok ( *(strrchr ( "Haystack", 'k' )) == 'k' );
  68. ok ( strrchr ( "Haystack", 'x' ) == NULL );
  69. /* Test memchr() */
  70. ok ( memchr ( "", '\0', 0 ) == NULL );
  71. ok ( *((uint8_t *)memchr ( "post\0null", 'l', 9 )) == 'l' );
  72. ok ( *((uint8_t *)memchr ( "post\0null", '\0', 9 )) == '\0' );
  73. ok ( memchr ( "thingy", 'z', 6 ) == NULL );
  74. /* Test strcmp() */
  75. ok ( strcmp ( "", "" ) == 0 );
  76. ok ( strcmp ( "Hello", "Hello" ) == 0 );
  77. ok ( strcmp ( "Hello", "hello" ) != 0 );
  78. ok ( strcmp ( "Hello", "Hello world!" ) != 0 );
  79. ok ( strcmp ( "Hello world!", "Hello" ) != 0 );
  80. /* Test strncmp() */
  81. ok ( strncmp ( "", "", 0 ) == 0 );
  82. ok ( strncmp ( "", "", 15 ) == 0 );
  83. ok ( strncmp ( "Goodbye", "Goodbye", 16 ) == 0 );
  84. ok ( strncmp ( "Goodbye", "Hello", 16 ) != 0 );
  85. ok ( strncmp ( "Goodbye", "Goodbye world", 32 ) != 0 );
  86. ok ( strncmp ( "Goodbye", "Goodbye world", 7 ) == 0 );
  87. /* Test strcasecmp() */
  88. ok ( strcasecmp ( "", "" ) == 0 );
  89. ok ( strcasecmp ( "Uncle Jack", "Uncle jack" ) == 0 );
  90. ok ( strcasecmp ( "Uncle Jack", "Uncle" ) != 0 );
  91. ok ( strcasecmp ( "Uncle", "Uncle Jack" ) != 0 );
  92. ok ( strcasecmp ( "not", "equal" ) != 0 );
  93. /* Test memcmp() */
  94. ok ( memcmp ( "", "", 0 ) == 0 );
  95. ok ( memcmp ( "Foo", "Foo", 3 ) == 0 );
  96. ok ( memcmp ( "Foo", "Bar", 3 ) != 0 );
  97. /* Test strstr() */
  98. {
  99. const char haystack[] = "find me!";
  100. char *found;
  101. found = strstr ( haystack, "find" );
  102. ok ( found == &haystack[0] );
  103. found = strstr ( haystack, "me" );
  104. ok ( found == &haystack[5] );
  105. found = strstr ( haystack, "me." );
  106. ok ( found == NULL );
  107. }
  108. /* Test memset() */
  109. {
  110. static uint8_t test[7] = { '>', 1, 1, 1, 1, 1, '<' };
  111. static const uint8_t expected[7] = { '>', 0, 0, 0, 0, 0, '<' };
  112. memset ( ( test + 1 ), 0, ( sizeof ( test ) - 2 ) );
  113. ok ( memcmp ( test, expected, sizeof ( test ) ) == 0 );
  114. }
  115. {
  116. static uint8_t test[4] = { '>', 0, 0, '<' };
  117. static const uint8_t expected[4] = { '>', 0xeb, 0xeb, '<' };
  118. memset ( ( test + 1 ), 0xeb, ( sizeof ( test ) - 2 ) );
  119. ok ( memcmp ( test, expected, sizeof ( test ) ) == 0 );
  120. }
  121. /* Test memmove() */
  122. {
  123. static uint8_t test[11] =
  124. { '>', 1, 2, 3, 4, 5, 6, 7, 8, 9, '<' };
  125. static const uint8_t expected[11] =
  126. { '>', 3, 4, 5, 6, 7, 8, 7, 8, 9, '<' };
  127. memmove ( ( test + 1 ), ( test + 3 ), 6 );
  128. ok ( memcmp ( test, expected, sizeof ( test ) ) == 0 );
  129. }
  130. {
  131. static uint8_t test[12] =
  132. { '>', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, '<' };
  133. static const uint8_t expected[12] =
  134. { '>', 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, '<' };
  135. memmove ( ( test + 6 ), ( test + 1 ), 5 );
  136. ok ( memcmp ( test, expected, sizeof ( test ) ) == 0 );
  137. }
  138. /* Test memswap() */
  139. {
  140. static uint8_t test[8] =
  141. { '>', 1, 2, 3, 7, 8, 9, '<' };
  142. static const uint8_t expected[8] =
  143. { '>', 7, 8, 9, 1, 2, 3, '<' };
  144. memswap ( ( test + 1 ), ( test + 4 ), 3 );
  145. ok ( memcmp ( test, expected, sizeof ( test ) ) == 0 );
  146. }
  147. /* Test strdup() */
  148. {
  149. const char *orig = "testing testing";
  150. char *dup = strdup ( orig );
  151. ok ( dup != NULL );
  152. ok ( dup != orig );
  153. ok ( strcmp ( dup, orig ) == 0 );
  154. free ( dup );
  155. }
  156. /* Test strndup() */
  157. {
  158. const char *normal = "testing testing";
  159. const char unterminated[6] = { 'h', 'e', 'l', 'l', 'o', '!' };
  160. char *dup;
  161. dup = strndup ( normal, 32 );
  162. ok ( dup != NULL );
  163. ok ( dup != normal );
  164. ok ( strcmp ( dup, normal ) == 0 );
  165. free ( dup );
  166. dup = strndup ( normal, 4 );
  167. ok ( dup != NULL );
  168. ok ( strcmp ( dup, "test" ) == 0 );
  169. free ( dup );
  170. dup = strndup ( unterminated, 5 );
  171. ok ( dup != NULL );
  172. ok ( strcmp ( dup, "hello" ) == 0 );
  173. free ( dup );
  174. }
  175. /* Test strcpy() */
  176. {
  177. const char longer[7] = "copyme";
  178. const char shorter[3] = "hi";
  179. char dest[7];
  180. char *copy;
  181. copy = strcpy ( dest, longer );
  182. ok ( copy == dest );
  183. ok ( memcmp ( dest, longer, 7 ) == 0 );
  184. copy = strcpy ( dest, shorter );
  185. ok ( copy == dest );
  186. ok ( memcmp ( dest, shorter, 3 ) == 0 );
  187. ok ( memcmp ( ( dest + 3 ), ( longer + 3 ), 4 ) == 0 );
  188. }
  189. /* Test strncpy() */
  190. {
  191. const char src[5] = "copy";
  192. const char orig[8] = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' };
  193. const char zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  194. char dest[8];
  195. char *copy;
  196. memcpy ( dest, orig, sizeof ( dest ) );
  197. copy = strncpy ( dest, src, 5 );
  198. ok ( copy == dest );
  199. ok ( memcmp ( dest, src, 5 ) == 0 );
  200. ok ( memcmp ( dest + 5, orig + 5, 3 ) == 0 );
  201. memcpy ( dest, orig, sizeof ( dest ) );
  202. copy = strncpy ( dest, src, 4 );
  203. ok ( copy == dest );
  204. ok ( memcmp ( dest, src, 4 ) == 0 );
  205. ok ( memcmp ( dest + 4, orig + 4, 4 ) == 0 );
  206. memcpy ( dest, orig, sizeof ( dest ) );
  207. copy = strncpy ( dest, src, 8 );
  208. ok ( copy == dest );
  209. ok ( memcmp ( dest, src, 5 ) == 0 );
  210. ok ( memcmp ( dest + 5, zero + 5, 3 ) == 0 );
  211. memcpy ( dest, orig, sizeof ( dest ) );
  212. copy = strncpy ( dest, "", 8 );
  213. ok ( copy == dest );
  214. ok ( memcmp ( dest, zero, 8 ) == 0 );
  215. }
  216. /* Test strcat() */
  217. {
  218. char buf[16] = "append";
  219. char *dest;
  220. dest = strcat ( buf, " this" );
  221. ok ( dest == buf );
  222. ok ( strcmp ( buf, "append this" ) == 0 );
  223. }
  224. /* Test digit_value() */
  225. {
  226. unsigned int i;
  227. char buf[2];
  228. for ( i = 0 ; i < 16 ; i++ ) {
  229. snprintf ( buf, sizeof ( buf ), "%x", i );
  230. ok ( digit_value ( buf[0] ) == i );
  231. snprintf ( buf, sizeof ( buf ), "%X", i );
  232. ok ( digit_value ( buf[0] ) == i );
  233. }
  234. ok ( digit_value ( 0 ) >= 16 );
  235. ok ( digit_value ( 9 ) >= 16 );
  236. ok ( digit_value ( '0' - 1 ) >= 16 );
  237. ok ( digit_value ( '9' + 1 ) >= 16 );
  238. ok ( digit_value ( 'A' - 1 ) >= 16 );
  239. ok ( digit_value ( 'F' + 1 ) >= 16 );
  240. ok ( digit_value ( 'a' - 1 ) >= 16 );
  241. ok ( digit_value ( 'f' + 1 ) >= 16 );
  242. }
  243. /* Test strtoul() */
  244. ok ( strtoul ( "12345", NULL, 0 ) == 12345UL );
  245. ok ( strtoul ( " 741", NULL, 10 ) == 741UL );
  246. ok ( strtoul ( " 555a", NULL, 0 ) == 555UL );
  247. ok ( strtoul ( " 555a", NULL, 16 ) == 0x555aUL );
  248. ok ( strtoul ( "-12", NULL, 0 ) == -12UL );
  249. ok ( strtoul ( "+3", NULL, 0 ) == 3UL );
  250. ok ( strtoul ( "721", NULL, 0 ) == 721UL );
  251. ok ( strtoul ( "721", NULL, 8 ) == 0721UL );
  252. ok ( strtoul ( "0721", NULL, 0 ) == 0721UL );
  253. ok ( strtoul ( "", NULL, 0 ) == 0UL );
  254. ok ( strtoul ( "\t0xcAfe", NULL, 0 ) == 0xcafeUL );
  255. ok ( strtoul ( "0xffffffff", NULL, 0 ) == 0xffffffffUL );
  256. {
  257. static const char string[] = "123aHa.world";
  258. char *endp;
  259. ok ( strtoul ( string, &endp, 0 ) == 123UL );
  260. ok ( endp == &string[3] );
  261. ok ( strtoul ( string, &endp, 16 ) == 0x123aUL );
  262. ok ( endp == &string[4] );
  263. ok ( strtoul ( string, &endp, 26 ) ==
  264. ( ( ( ( ( 1 * 26 + 2 ) * 26 + 3 ) * 26 + 10 ) * 26
  265. + 17 ) * 26 + 10 ) );
  266. ok ( endp == &string[6] );
  267. }
  268. }
  269. /** String self-test */
  270. struct self_test string_test __self_test = {
  271. .name = "string",
  272. .exec = string_test_exec,
  273. };