aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_strl.c
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-21 12:39:20 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-21 12:39:34 +0100
commitd699849b2360f90c61f645c5d4d4232cd3e1c962 (patch)
treec929ec20ca3b16fe3d34bd75e412ca49f7420125 /tests/test_strl.c
downloadLibft-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.c252
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);
+}