diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-21 12:39:20 +0100 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-21 12:39:34 +0100 |
| commit | d699849b2360f90c61f645c5d4d4232cd3e1c962 (patch) | |
| tree | c929ec20ca3b16fe3d34bd75e412ca49f7420125 /tests/test_cmp.c | |
| download | Libft-d699849b2360f90c61f645c5d4d4232cd3e1c962.tar.gz Libft-d699849b2360f90c61f645c5d4d4232cd3e1c962.zip | |
Initial commit: libft Part 1 with tests and documentation
Reimplements 24 libc functions with Doxygen-documented header
and test suite comparing against libc.
Diffstat (limited to 'tests/test_cmp.c')
| -rw-r--r-- | tests/test_cmp.c | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/tests/test_cmp.c b/tests/test_cmp.c new file mode 100644 index 0000000..eea0aea --- /dev/null +++ b/tests/test_cmp.c @@ -0,0 +1,279 @@ +#include "../libft.h" +#include "test_utils.h" + +static void +_s_ft_memchr_null (void) +{ + _s_sink = (size_t)ft_memchr (NULL, 'a', 10); +} +static void +_s_libc_memchr_null (void) +{ + _s_sink = (size_t)memchr (NULL, 'a', 10); +} +static void +_s_ft_memcmp_null_s1 (void) +{ + _s_sink_i = ft_memcmp (NULL, "abc", 3); +} +static void +_s_libc_memcmp_null_s1 (void) +{ + _s_sink_i = memcmp (NULL, "abc", 3); +} +static void +_s_ft_memcmp_null_s2 (void) +{ + _s_sink_i = ft_memcmp ("abc", NULL, 3); +} +static void +_s_libc_memcmp_null_s2 (void) +{ + _s_sink_i = memcmp ("abc", NULL, 3); +} +static void +_s_ft_strncmp_null_s1 (void) +{ + _s_sink_i = ft_strncmp (NULL, "abc", 3); +} +static void +_s_libc_strncmp_null_s1 (void) +{ + _s_sink_i = strncmp (NULL, "abc", 3); +} +static void +_s_ft_strncmp_null_s2 (void) +{ + _s_sink_i = ft_strncmp ("abc", NULL, 3); +} +static void +_s_libc_strncmp_null_s2 (void) +{ + _s_sink_i = strncmp ("abc", NULL, 3); +} + +/* ====================================== + * memchr + * ====================================== */ + +static void +_s_test_memchr (void) +{ + char buf[] = "Hello, World!"; + char all[256]; + int i; + char label[64]; + + printf ("-- memchr --\n"); + + /* NULL */ + _s_check_both_crash ("memchr NULL", _s_ft_memchr_null, _s_libc_memchr_null); + + /* find existing char */ + _s_check ("find 'W'", ft_memchr (buf, 'W', 13) == memchr (buf, 'W', 13)); + + /* find first byte */ + _s_check ("find 'H'", ft_memchr (buf, 'H', 13) == memchr (buf, 'H', 13)); + + /* find last byte */ + _s_check ("find '!'", ft_memchr (buf, '!', 13) == memchr (buf, '!', 13)); + + /* not found */ + _s_check ("not found 'z'", + ft_memchr (buf, 'z', 13) == memchr (buf, 'z', 13)); + + /* n=0 */ + _s_check ("n=0", ft_memchr (buf, 'H', 0) == NULL); + + /* char beyond n */ + _s_check ("beyond n", ft_memchr (buf, '!', 5) == memchr (buf, '!', 5)); + + /* search for null byte */ + _s_check ("find '\\0'", ft_memchr (buf, '\0', 14) == memchr (buf, '\0', 14)); + + /* int truncation to unsigned char */ + _s_check ("int truncation", + ft_memchr (buf, 'H' + 256, 13) == memchr (buf, 'H' + 256, 13)); + + /* all byte values */ + for (i = 0; i < 256; i++) + all[i] = i; + for (i = 0; i < 256; i++) + { + snprintf (label, sizeof (label), "byte %d", i); + _s_check (label, ft_memchr (all, i, 256) == memchr (all, i, 256)); + } + + /* randomized */ + srand (time (NULL)); + for (i = 0; i < 50; i++) + { + unsigned char rnd[256]; + int len = rand () % 256 + 1; + int c = rand () % 256; + int j; + for (j = 0; j < len; j++) + rnd[j] = rand () % 256; + snprintf (label, sizeof (label), "random len=%d c=%d", len, c); + _s_check (label, ft_memchr (rnd, c, len) == memchr (rnd, c, len)); + } +} + +/* ====================================== + * memcmp + * ====================================== */ + +static void +_s_test_memcmp (void) +{ + int i; + unsigned char a[256]; + unsigned char b[256]; + size_t len; + int pos; + char label[64]; + + printf ("-- memcmp --\n"); + + /* NULL */ + _s_check_both_crash ("memcmp NULL s1", _s_ft_memcmp_null_s1, + _s_libc_memcmp_null_s1); + _s_check_both_crash ("memcmp NULL s2", _s_ft_memcmp_null_s2, + _s_libc_memcmp_null_s2); + + /* equal */ + _s_check ("equal", _s_sign (ft_memcmp ("abc", "abc", 3)) + == _s_sign (memcmp ("abc", "abc", 3))); + + /* first less */ + _s_check ("less", _s_sign (ft_memcmp ("abc", "abd", 3)) + == _s_sign (memcmp ("abc", "abd", 3))); + + /* first greater */ + _s_check ("greater", _s_sign (ft_memcmp ("abd", "abc", 3)) + == _s_sign (memcmp ("abd", "abc", 3))); + + /* n=0 */ + _s_check ("n=0", _s_sign (ft_memcmp ("abc", "xyz", 0)) + == _s_sign (memcmp ("abc", "xyz", 0))); + + /* difference at last byte */ + _s_check ("diff at end", _s_sign (ft_memcmp ("abcd", "abce", 4)) + == _s_sign (memcmp ("abcd", "abce", 4))); + + /* unsigned comparison: 0 vs 200 */ + { + unsigned char x[] = { 0 }; + unsigned char y[] = { 200 }; + _s_check ("unsigned 0 vs 200", + _s_sign (ft_memcmp (x, y, 1)) == _s_sign (memcmp (x, y, 1))); + } + + /* randomized */ + srand (time (NULL)); + for (i = 0; i < 50; i++) + { + len = rand () % 255 + 1; + for (pos = 0; pos < (int)len; pos++) + a[pos] = b[pos] = rand () % 256; + /* introduce a random difference sometimes */ + if (i % 2 == 0) + { + pos = rand () % len; + b[pos] = (a[pos] + 1 + rand () % 255) % 256; + } + snprintf (label, sizeof (label), "random len=%zu", len); + _s_check (label, _s_sign (ft_memcmp (a, b, len)) + == _s_sign (memcmp (a, b, len))); + } +} + +/* ====================================== + * strncmp + * ====================================== */ + +static void +_s_test_strncmp (void) +{ + int i; + char a[128]; + char b[128]; + int len; + char label[64]; + + printf ("-- strncmp --\n"); + + /* NULL */ + _s_check_both_crash ("strncmp NULL s1", _s_ft_strncmp_null_s1, + _s_libc_strncmp_null_s1); + _s_check_both_crash ("strncmp NULL s2", _s_ft_strncmp_null_s2, + _s_libc_strncmp_null_s2); + + /* equal strings */ + _s_check ("equal", _s_sign (ft_strncmp ("abc", "abc", 3)) + == _s_sign (strncmp ("abc", "abc", 3))); + + /* less */ + _s_check ("less", _s_sign (ft_strncmp ("abc", "abd", 3)) + == _s_sign (strncmp ("abc", "abd", 3))); + + /* greater */ + _s_check ("greater", _s_sign (ft_strncmp ("abd", "abc", 3)) + == _s_sign (strncmp ("abd", "abc", 3))); + + /* n=0 */ + _s_check ("n=0", _s_sign (ft_strncmp ("abc", "xyz", 0)) + == _s_sign (strncmp ("abc", "xyz", 0))); + + /* n larger than strings */ + _s_check ("n > len", _s_sign (ft_strncmp ("abc", "abc", 100)) + == _s_sign (strncmp ("abc", "abc", 100))); + + /* difference beyond n */ + _s_check ("diff beyond n", _s_sign (ft_strncmp ("abcX", "abcY", 3)) + == _s_sign (strncmp ("abcX", "abcY", 3))); + + /* empty strings */ + _s_check ("both empty", + _s_sign (ft_strncmp ("", "", 5)) == _s_sign (strncmp ("", "", 5))); + + /* one empty */ + _s_check ("s1 empty", _s_sign (ft_strncmp ("", "a", 5)) + == _s_sign (strncmp ("", "a", 5))); + _s_check ("s2 empty", _s_sign (ft_strncmp ("a", "", 5)) + == _s_sign (strncmp ("a", "", 5))); + + /* different lengths, equal prefix */ + _s_check ("shorter s1", _s_sign (ft_strncmp ("ab", "abc", 5)) + == _s_sign (strncmp ("ab", "abc", 5))); + + /* unsigned comparison */ + _s_check ("unsigned", _s_sign (ft_strncmp ("\xff", "\x01", 1)) + == _s_sign (strncmp ("\xff", "\x01", 1))); + + /* randomized */ + for (i = 0; i < 50; i++) + { + len = rand () % 64 + 1; + for (int j = 0; j < len; j++) + a[j] = b[j] = 'A' + rand () % 26; + a[len] = '\0'; + b[len] = '\0'; + if (i % 2 == 0) + b[rand () % len] = 'A' + rand () % 26; + snprintf (label, sizeof (label), "random n=%d", len); + _s_check (label, _s_sign (ft_strncmp (a, b, len)) + == _s_sign (strncmp (a, b, len))); + } +} + +int +main (void) +{ + printf ("=== comparison functions ===\n"); + _s_test_memchr (); + _s_test_memcmp (); + _s_test_strncmp (); + _s_print_results (); + return (_s_fail != 0); +} |
