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_strl.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_strl.c')
| -rw-r--r-- | tests/test_strl.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/tests/test_strl.c b/tests/test_strl.c new file mode 100644 index 0000000..1ef29af --- /dev/null +++ b/tests/test_strl.c @@ -0,0 +1,252 @@ +#include "../libft.h" +#include "test_utils.h" +#include <bsd/string.h> + +static void +_s_ft_strlcpy_null_dst (void) +{ + _s_sink = ft_strlcpy (NULL, "abc", 10); +} +static void +_s_libc_strlcpy_null_dst (void) +{ + _s_sink = strlcpy (NULL, "abc", 10); +} +static void +_s_ft_strlcpy_null_src (void) +{ + char buf[10]; + _s_sink = ft_strlcpy (buf, NULL, 10); +} +static void +_s_libc_strlcpy_null_src (void) +{ + char buf[10]; + _s_sink = strlcpy (buf, NULL, 10); +} +static void +_s_ft_strlcat_null_dst (void) +{ + _s_sink = ft_strlcat (NULL, "abc", 10); +} +static void +_s_libc_strlcat_null_dst (void) +{ + _s_sink = strlcat (NULL, "abc", 10); +} +static void +_s_ft_strlcat_null_src (void) +{ + char buf[10] = "hi"; + _s_sink = ft_strlcat (buf, NULL, 10); +} +static void +_s_libc_strlcat_null_src (void) +{ + char buf[10] = "hi"; + _s_sink = strlcat (buf, NULL, 10); +} + +/* ====================================== + * strlcpy + * ====================================== */ + +static void +_s_test_strlcpy (void) +{ + char ft_dst[64]; + char libc_dst[64]; + size_t ft_ret; + size_t libc_ret; + int i; + size_t size; + char src[64]; + char label[64]; + + printf ("-- strlcpy --\n"); + + /* NULL */ + _s_check_both_crash ("strlcpy NULL dst", _s_ft_strlcpy_null_dst, + _s_libc_strlcpy_null_dst); + _s_check_both_crash ("strlcpy NULL src", _s_ft_strlcpy_null_src, + _s_libc_strlcpy_null_src); + + /* basic copy */ + ft_ret = ft_strlcpy (ft_dst, "hello", 64); + libc_ret = strlcpy (libc_dst, "hello", 64); + _s_check ("basic copy ret", ft_ret == libc_ret); + _s_check ("basic copy buf", strcmp (ft_dst, libc_dst) == 0); + + /* size=0 */ + memset (ft_dst, 'X', 64); + memset (libc_dst, 'X', 64); + ft_ret = ft_strlcpy (ft_dst, "hello", 0); + libc_ret = strlcpy (libc_dst, "hello", 0); + _s_check ("size=0 ret", ft_ret == libc_ret); + _s_check ("size=0 buf unchanged", ft_dst[0] == 'X'); + + /* truncation */ + ft_ret = ft_strlcpy (ft_dst, "hello world", 6); + libc_ret = strlcpy (libc_dst, "hello world", 6); + _s_check ("truncate ret", ft_ret == libc_ret); + _s_check ("truncate buf", strcmp (ft_dst, libc_dst) == 0); + _s_check ("truncate null term", ft_dst[5] == '\0'); + + /* exact fit */ + ft_ret = ft_strlcpy (ft_dst, "abc", 4); + libc_ret = strlcpy (libc_dst, "abc", 4); + _s_check ("exact fit ret", ft_ret == libc_ret); + _s_check ("exact fit buf", strcmp (ft_dst, libc_dst) == 0); + + /* empty src */ + ft_ret = ft_strlcpy (ft_dst, "", 64); + libc_ret = strlcpy (libc_dst, "", 64); + _s_check ("empty src ret", ft_ret == libc_ret); + _s_check ("empty src buf", strcmp (ft_dst, libc_dst) == 0); + + /* size=1 */ + ft_ret = ft_strlcpy (ft_dst, "hello", 1); + libc_ret = strlcpy (libc_dst, "hello", 1); + _s_check ("size=1 ret", ft_ret == libc_ret); + _s_check ("size=1 buf", ft_dst[0] == '\0'); + + /* randomized */ + srand (time (NULL)); + for (i = 0; i < 50; i++) + { + int len = rand () % 60 + 1; + int j; + for (j = 0; j < len; j++) + src[j] = 'A' + rand () % 26; + src[len] = '\0'; + size = rand () % 64; + memset (ft_dst, 'Z', 64); + memset (libc_dst, 'Z', 64); + ft_ret = ft_strlcpy (ft_dst, src, size); + libc_ret = strlcpy (libc_dst, src, size); + snprintf (label, sizeof (label), "random len=%d size=%zu", len, size); + _s_check (label, + ft_ret == libc_ret && memcmp (ft_dst, libc_dst, 64) == 0); + } +} + +/* ====================================== + * strlcat + * ====================================== */ + +static void +_s_test_strlcat (void) +{ + char ft_dst[64]; + char libc_dst[64]; + size_t ft_ret; + size_t libc_ret; + int i; + size_t size; + char label[64]; + + printf ("-- strlcat --\n"); + + /* NULL */ + _s_check_both_crash ("strlcat NULL dst", _s_ft_strlcat_null_dst, + _s_libc_strlcat_null_dst); + _s_check_both_crash ("strlcat NULL src", _s_ft_strlcat_null_src, + _s_libc_strlcat_null_src); + + /* basic concat */ + strcpy (ft_dst, "hello"); + strcpy (libc_dst, "hello"); + ft_ret = ft_strlcat (ft_dst, " world", 64); + libc_ret = strlcat (libc_dst, " world", 64); + _s_check ("basic ret", ft_ret == libc_ret); + _s_check ("basic buf", strcmp (ft_dst, libc_dst) == 0); + + /* size=0 */ + strcpy (ft_dst, "hi"); + strcpy (libc_dst, "hi"); + ft_ret = ft_strlcat (ft_dst, "abc", 0); + libc_ret = strlcat (libc_dst, "abc", 0); + _s_check ("size=0 ret", ft_ret == libc_ret); + + /* size == dstlen (no room to append) */ + strcpy (ft_dst, "hello"); + strcpy (libc_dst, "hello"); + ft_ret = ft_strlcat (ft_dst, "abc", 5); + libc_ret = strlcat (libc_dst, "abc", 5); + _s_check ("size == dstlen ret", ft_ret == libc_ret); + _s_check ("size == dstlen buf", strcmp (ft_dst, libc_dst) == 0); + + /* size less than dst len */ + strcpy (ft_dst, "hello"); + strcpy (libc_dst, "hello"); + ft_ret = ft_strlcat (ft_dst, "abc", 3); + libc_ret = strlcat (libc_dst, "abc", 3); + _s_check ("size < dstlen ret", ft_ret == libc_ret); + _s_check ("size < dstlen buf", strcmp (ft_dst, libc_dst) == 0); + + /* truncation */ + strcpy (ft_dst, "hello"); + strcpy (libc_dst, "hello"); + ft_ret = ft_strlcat (ft_dst, " world", 8); + libc_ret = strlcat (libc_dst, " world", 8); + _s_check ("truncate ret", ft_ret == libc_ret); + _s_check ("truncate buf", strcmp (ft_dst, libc_dst) == 0); + + /* exact fit */ + strcpy (ft_dst, "abc"); + strcpy (libc_dst, "abc"); + ft_ret = ft_strlcat (ft_dst, "de", 6); + libc_ret = strlcat (libc_dst, "de", 6); + _s_check ("exact fit ret", ft_ret == libc_ret); + _s_check ("exact fit buf", strcmp (ft_dst, libc_dst) == 0); + + /* empty src */ + strcpy (ft_dst, "hello"); + strcpy (libc_dst, "hello"); + ft_ret = ft_strlcat (ft_dst, "", 64); + libc_ret = strlcat (libc_dst, "", 64); + _s_check ("empty src ret", ft_ret == libc_ret); + _s_check ("empty src buf", strcmp (ft_dst, libc_dst) == 0); + + /* empty dst */ + ft_dst[0] = '\0'; + libc_dst[0] = '\0'; + ft_ret = ft_strlcat (ft_dst, "hello", 64); + libc_ret = strlcat (libc_dst, "hello", 64); + _s_check ("empty dst ret", ft_ret == libc_ret); + _s_check ("empty dst buf", strcmp (ft_dst, libc_dst) == 0); + + /* randomized */ + for (i = 0; i < 50; i++) + { + int dlen = rand () % 30; + int slen = rand () % 30 + 1; + int j; + for (j = 0; j < dlen; j++) + ft_dst[j] = libc_dst[j] = 'A' + rand () % 26; + ft_dst[dlen] = libc_dst[dlen] = '\0'; + char src[64]; + for (j = 0; j < slen; j++) + src[j] = 'a' + rand () % 26; + src[slen] = '\0'; + size = rand () % 64; + memset (ft_dst + dlen + 1, 'Z', 63 - dlen); + memset (libc_dst + dlen + 1, 'Z', 63 - dlen); + ft_ret = ft_strlcat (ft_dst, src, size); + libc_ret = strlcat (libc_dst, src, size); + snprintf (label, sizeof (label), "random dlen=%d slen=%d size=%zu", dlen, + slen, size); + _s_check (label, + ft_ret == libc_ret && memcmp (ft_dst, libc_dst, 64) == 0); + } +} + +int +main (void) +{ + printf ("=== strlcpy/strlcat ===\n"); + _s_test_strlcpy (); + _s_test_strlcat (); + _s_print_results (); + return (_s_fail != 0); +} |
