aboutsummaryrefslogtreecommitdiffstats
path: root/tests/src/test_cmp.c
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-21 15:49:06 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-21 15:51:44 +0100
commit671a58519ef6207b54947ff70eea497ff7eb58ae (patch)
tree783a971119bfed965113b84bc306ba941e884663 /tests/src/test_cmp.c
parentd699849b2360f90c61f645c5d4d4232cd3e1c962 (diff)
downloadLibft-671a58519ef6207b54947ff70eea497ff7eb58ae.tar.gz
Libft-671a58519ef6207b54947ff70eea497ff7eb58ae.zip
Restructure project layout and clean up test suite
Move sources to src/, header to inc/, and tests to tests/src/. Update Makefiles and .gitignore for the new layout. Refactor test harness: add crash-wrapper macros (_S_CRASH, _S_CRASH_I, _S_CRASH_V, _S_CRASH_BUF) replacing 58 hand-written wrappers, add shared _s_test_int_range helper eliminating duplicate _s_test_func, add _S_RAND_ITERS constant, move srand() to main() in all test binaries, and add Doxygen comments to test_utils.h.
Diffstat (limited to 'tests/src/test_cmp.c')
-rw-r--r--tests/src/test_cmp.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/tests/src/test_cmp.c b/tests/src/test_cmp.c
new file mode 100644
index 0000000..d98b584
--- /dev/null
+++ b/tests/src/test_cmp.c
@@ -0,0 +1,238 @@
+#include "libft.h"
+#include "test_utils.h"
+
+_S_CRASH (ft_memchr_null, ft_memchr (NULL, 'a', 10))
+_S_CRASH (libc_memchr_null, memchr (NULL, 'a', 10))
+_S_CRASH_I (ft_memcmp_null_s1, ft_memcmp (NULL, "abc", 3))
+_S_CRASH_I (libc_memcmp_null_s1, memcmp (NULL, "abc", 3))
+_S_CRASH_I (ft_memcmp_null_s2, ft_memcmp ("abc", NULL, 3))
+_S_CRASH_I (libc_memcmp_null_s2, memcmp ("abc", NULL, 3))
+_S_CRASH_I (ft_strncmp_null_s1, ft_strncmp (NULL, "abc", 3))
+_S_CRASH_I (libc_strncmp_null_s1, strncmp (NULL, "abc", 3))
+_S_CRASH_I (ft_strncmp_null_s2, ft_strncmp ("abc", NULL, 3))
+_S_CRASH_I (libc_strncmp_null_s2, strncmp ("abc", NULL, 3))
+
+/* ======================================
+ * memchr
+ * ====================================== */
+
+static void
+_s_test_memchr (void)
+{
+ char buf[] = "Hello, World!";
+ char all[256];
+ int i;
+ char label[64];
+
+ _s_section ("ft_memchr");
+
+ /* NULL */
+ _s_check_both_crash ("memchr NULL", _s_crash_ft_memchr_null,
+ _s_crash_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 */
+ for (i = 0; i < _S_RAND_ITERS; 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];
+
+ _s_section ("ft_memcmp");
+
+ /* NULL */
+ _s_check_both_crash ("memcmp NULL s1", _s_crash_ft_memcmp_null_s1,
+ _s_crash_libc_memcmp_null_s1);
+ _s_check_both_crash ("memcmp NULL s2", _s_crash_ft_memcmp_null_s2,
+ _s_crash_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 */
+ for (i = 0; i < _S_RAND_ITERS; 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];
+
+ _s_section ("ft_strncmp");
+
+ /* NULL */
+ _s_check_both_crash ("strncmp NULL s1", _s_crash_ft_strncmp_null_s1,
+ _s_crash_libc_strncmp_null_s1);
+ _s_check_both_crash ("strncmp NULL s2", _s_crash_ft_strncmp_null_s2,
+ _s_crash_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 < _S_RAND_ITERS; 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)
+{
+ srand (time (NULL));
+ _s_test_memchr ();
+ _s_test_memcmp ();
+ _s_test_strncmp ();
+ _s_print_results ();
+ return (_s_fail != 0);
+}