From 671a58519ef6207b54947ff70eea497ff7eb58ae Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Sat, 21 Feb 2026 15:49:06 +0100 Subject: 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. --- .gitignore | 6 +- Makefile | 22 +++- ft_atoi.c | 26 ----- ft_bzero.c | 7 -- ft_calloc.c | 19 ---- ft_isalnum.c | 7 -- ft_isalpha.c | 7 -- ft_isascii.c | 7 -- ft_isdigit.c | 7 -- ft_isprint.c | 7 -- ft_memchr.c | 16 --- ft_memcmp.c | 19 ---- ft_memcpy.c | 16 --- ft_memmove.c | 26 ----- ft_memset.c | 12 -- ft_strchr.c | 7 -- ft_strdup.c | 16 --- ft_strlcat.c | 23 ---- ft_strlcpy.c | 20 ---- ft_strlen.c | 12 -- ft_strncmp.c | 16 --- ft_strnstr.c | 19 ---- ft_strrchr.c | 18 --- ft_tolower.c | 9 -- ft_toupper.c | 9 -- inc/libft.h | 106 +++++++++++++++++ lib/.gitkeep | 0 libft.h | 106 ----------------- src/ft_atoi.c | 26 +++++ src/ft_bzero.c | 7 ++ src/ft_calloc.c | 19 ++++ src/ft_isalnum.c | 7 ++ src/ft_isalpha.c | 7 ++ src/ft_isascii.c | 7 ++ src/ft_isdigit.c | 7 ++ src/ft_isprint.c | 7 ++ src/ft_memchr.c | 16 +++ src/ft_memcmp.c | 19 ++++ src/ft_memcpy.c | 16 +++ src/ft_memmove.c | 26 +++++ src/ft_memset.c | 12 ++ src/ft_strchr.c | 7 ++ src/ft_strdup.c | 16 +++ src/ft_strlcat.c | 23 ++++ src/ft_strlcpy.c | 20 ++++ src/ft_strlen.c | 12 ++ src/ft_strncmp.c | 16 +++ src/ft_strnstr.c | 19 ++++ src/ft_strrchr.c | 18 +++ src/ft_tolower.c | 9 ++ src/ft_toupper.c | 9 ++ tests/.gitignore | 3 + tests/Makefile | 29 +++-- tests/bin/.gitkeep | 0 tests/inc/test_utils.h | 246 ++++++++++++++++++++++++++++++++++++++++ tests/src/test_alloc.c | 151 ++++++++++++++++++++++++ tests/src/test_atoi.c | 49 ++++++++ tests/src/test_case.c | 14 +++ tests/src/test_cmp.c | 238 ++++++++++++++++++++++++++++++++++++++ tests/src/test_is.c | 20 ++++ tests/src/test_mem.c | 249 ++++++++++++++++++++++++++++++++++++++++ tests/src/test_search.c | 253 +++++++++++++++++++++++++++++++++++++++++ tests/src/test_strl.c | 227 +++++++++++++++++++++++++++++++++++++ tests/src/test_strlen.c | 76 +++++++++++++ tests/test_alloc.c | 159 -------------------------- tests/test_atoi.c | 58 ---------- tests/test_case.c | 36 ------ tests/test_cmp.c | 279 --------------------------------------------- tests/test_is.c | 43 ------- tests/test_mem.c | 296 ------------------------------------------------ tests/test_search.c | 285 ---------------------------------------------- tests/test_strl.c | 252 ----------------------------------------- tests/test_strlen.c | 109 ------------------ 73 files changed, 1998 insertions(+), 1964 deletions(-) delete mode 100644 ft_atoi.c delete mode 100644 ft_bzero.c delete mode 100644 ft_calloc.c delete mode 100644 ft_isalnum.c delete mode 100644 ft_isalpha.c delete mode 100644 ft_isascii.c delete mode 100644 ft_isdigit.c delete mode 100644 ft_isprint.c delete mode 100644 ft_memchr.c delete mode 100644 ft_memcmp.c delete mode 100644 ft_memcpy.c delete mode 100644 ft_memmove.c delete mode 100644 ft_memset.c delete mode 100644 ft_strchr.c delete mode 100644 ft_strdup.c delete mode 100644 ft_strlcat.c delete mode 100644 ft_strlcpy.c delete mode 100644 ft_strlen.c delete mode 100644 ft_strncmp.c delete mode 100644 ft_strnstr.c delete mode 100644 ft_strrchr.c delete mode 100644 ft_tolower.c delete mode 100644 ft_toupper.c create mode 100644 inc/libft.h create mode 100644 lib/.gitkeep delete mode 100644 libft.h create mode 100644 src/ft_atoi.c create mode 100644 src/ft_bzero.c create mode 100644 src/ft_calloc.c create mode 100644 src/ft_isalnum.c create mode 100644 src/ft_isalpha.c create mode 100644 src/ft_isascii.c create mode 100644 src/ft_isdigit.c create mode 100644 src/ft_isprint.c create mode 100644 src/ft_memchr.c create mode 100644 src/ft_memcmp.c create mode 100644 src/ft_memcpy.c create mode 100644 src/ft_memmove.c create mode 100644 src/ft_memset.c create mode 100644 src/ft_strchr.c create mode 100644 src/ft_strdup.c create mode 100644 src/ft_strlcat.c create mode 100644 src/ft_strlcpy.c create mode 100644 src/ft_strlen.c create mode 100644 src/ft_strncmp.c create mode 100644 src/ft_strnstr.c create mode 100644 src/ft_strrchr.c create mode 100644 src/ft_tolower.c create mode 100644 src/ft_toupper.c create mode 100644 tests/.gitignore create mode 100644 tests/bin/.gitkeep create mode 100644 tests/inc/test_utils.h create mode 100644 tests/src/test_alloc.c create mode 100644 tests/src/test_atoi.c create mode 100644 tests/src/test_case.c create mode 100644 tests/src/test_cmp.c create mode 100644 tests/src/test_is.c create mode 100644 tests/src/test_mem.c create mode 100644 tests/src/test_search.c create mode 100644 tests/src/test_strl.c create mode 100644 tests/src/test_strlen.c delete mode 100644 tests/test_alloc.c delete mode 100644 tests/test_atoi.c delete mode 100644 tests/test_case.c delete mode 100644 tests/test_cmp.c delete mode 100644 tests/test_is.c delete mode 100644 tests/test_mem.c delete mode 100644 tests/test_search.c delete mode 100644 tests/test_strl.c delete mode 100644 tests/test_strlen.c diff --git a/.gitignore b/.gitignore index ef58cd4..71e00b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.o *.a -tests/test_* -!tests/test_*.c +obj/* +lib/* +bin/* +!.gitkeep diff --git a/Makefile b/Makefile index 55e0d7b..c1af191 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,13 @@ -NAME = libft.a - CC = cc CFLAGS = -Wall -Wextra -Werror +SRCDIR = src +INCDIR = inc +OBJDIR = obj +LIBDIR = lib + +NAME = $(LIBDIR)/libft.a + SRCS = ft_isalpha.c ft_isdigit.c ft_isalnum.c ft_isascii.c ft_isprint.c \ ft_strlen.c ft_memset.c ft_bzero.c ft_memcpy.c ft_memmove.c \ ft_memchr.c ft_memcmp.c ft_strncmp.c \ @@ -11,18 +16,25 @@ SRCS = ft_isalpha.c ft_isdigit.c ft_isalnum.c ft_isascii.c ft_isprint.c \ ft_calloc.c ft_strdup.c \ ft_toupper.c ft_tolower.c -OBJS = $(SRCS:.c=.o) +OBJS = $(SRCS:%.c=$(OBJDIR)/%.o) -$(NAME): $(OBJS) +$(NAME): $(OBJS) | $(LIBDIR) ar rcs $(NAME) $(OBJS) all: $(NAME) +$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) + $(CC) $(CFLAGS) -I $(INCDIR) -c $< -o $@ + +$(OBJDIR): + mkdir -p $(OBJDIR) + clean: - rm -f $(OBJS) + rm -rf $(OBJDIR) fclean: clean rm -f $(NAME) + $(MAKE) -C tests clean re: fclean all diff --git a/ft_atoi.c b/ft_atoi.c deleted file mode 100644 index 2fe091a..0000000 --- a/ft_atoi.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "libft.h" - -int -ft_atoi (const char *nptr) -{ - int sign; - int result; - - result = 0; - sign = 1; - // Skip isspace() characters: space, \t, \n, \v, \f, \r. - while (*nptr == ' ' || (*nptr >= '\t' && *nptr <= '\r')) - nptr++; - if (*nptr == '-' || *nptr == '+') - { - if (*nptr == '-') - sign = -1; - nptr++; - } - while (*nptr >= '0' && *nptr <= '9') - { - result = result * 10 + (*nptr - '0'); - nptr++; - } - return (result * sign); -} diff --git a/ft_bzero.c b/ft_bzero.c deleted file mode 100644 index 10f67bd..0000000 --- a/ft_bzero.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libft.h" - -void -ft_bzero (void *s, size_t n) -{ - ft_memset (s, 0, n); -} diff --git a/ft_calloc.c b/ft_calloc.c deleted file mode 100644 index 7726c64..0000000 --- a/ft_calloc.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "libft.h" -#include - -void * -ft_calloc (size_t nmemb, size_t size) -{ - void *ptr; - size_t total; - - // Detect multiplication overflow before allocating. - if (nmemb && size > (size_t)-1 / nmemb) - return (NULL); - total = nmemb * size; - ptr = malloc (total); - if (!ptr) - return (NULL); - ft_bzero (ptr, total); - return (ptr); -} diff --git a/ft_isalnum.c b/ft_isalnum.c deleted file mode 100644 index 4b477f8..0000000 --- a/ft_isalnum.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libft.h" - -int -ft_isalnum (int c) -{ - return (ft_isalpha (c) || ft_isdigit (c)); -} diff --git a/ft_isalpha.c b/ft_isalpha.c deleted file mode 100644 index c19cf58..0000000 --- a/ft_isalpha.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libft.h" - -int -ft_isalpha (int c) -{ - return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); -} diff --git a/ft_isascii.c b/ft_isascii.c deleted file mode 100644 index f9e877e..0000000 --- a/ft_isascii.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libft.h" - -int -ft_isascii (int c) -{ - return (c >= 0 && c <= 127); -} diff --git a/ft_isdigit.c b/ft_isdigit.c deleted file mode 100644 index 43de53f..0000000 --- a/ft_isdigit.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libft.h" - -int -ft_isdigit (int c) -{ - return (c >= '0' && c <= '9'); -} diff --git a/ft_isprint.c b/ft_isprint.c deleted file mode 100644 index 73964ff..0000000 --- a/ft_isprint.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libft.h" - -int -ft_isprint (int c) -{ - return (c >= 32 && c <= 126); -} diff --git a/ft_memchr.c b/ft_memchr.c deleted file mode 100644 index 08d5c3e..0000000 --- a/ft_memchr.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "libft.h" - -void * -ft_memchr (const void *s, int c, size_t n) -{ - const unsigned char *ptr; - - ptr = s; - while (n--) - { - if (*ptr == (unsigned char)c) - return ((void *)ptr); - ptr++; - } - return (NULL); -} diff --git a/ft_memcmp.c b/ft_memcmp.c deleted file mode 100644 index ce6cc77..0000000 --- a/ft_memcmp.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "libft.h" - -int -ft_memcmp (const void *s1, const void *s2, size_t n) -{ - const unsigned char *p1; - const unsigned char *p2; - - p1 = s1; - p2 = s2; - while (n--) - { - if (*p1 != *p2) - return (*p1 - *p2); - p1++; - p2++; - } - return (0); -} diff --git a/ft_memcpy.c b/ft_memcpy.c deleted file mode 100644 index 26c4f76..0000000 --- a/ft_memcpy.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "libft.h" - -void * -ft_memcpy (void *dest, const void *src, size_t n) -{ - unsigned char *dst_bytes; - const unsigned char *src_bytes; - - if (!dest && !src) - return (dest); - dst_bytes = dest; - src_bytes = src; - while (n--) - *dst_bytes++ = *src_bytes++; - return (dest); -} diff --git a/ft_memmove.c b/ft_memmove.c deleted file mode 100644 index ace0d90..0000000 --- a/ft_memmove.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "libft.h" - -void * -ft_memmove (void *dest, const void *src, size_t n) -{ - unsigned char *dst_bytes; - const unsigned char *src_bytes; - - if (!dest && !src) - return (dest); - dst_bytes = dest; - src_bytes = src; - if (dst_bytes > src_bytes) - { - dst_bytes += n; - src_bytes += n; - while (n--) - *--dst_bytes = *--src_bytes; - } - else - { - while (n--) - *dst_bytes++ = *src_bytes++; - } - return (dest); -} diff --git a/ft_memset.c b/ft_memset.c deleted file mode 100644 index 5be8fe6..0000000 --- a/ft_memset.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "libft.h" - -void * -ft_memset (void *s, int c, size_t n) -{ - unsigned char *ptr; - - ptr = s; - while (n--) - *ptr++ = (unsigned char)c; - return (s); -} diff --git a/ft_strchr.c b/ft_strchr.c deleted file mode 100644 index 0952232..0000000 --- a/ft_strchr.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libft.h" - -char * -ft_strchr (const char *s, int c) -{ - return (ft_memchr (s, c, ft_strlen (s) + 1)); -} diff --git a/ft_strdup.c b/ft_strdup.c deleted file mode 100644 index 3a6be31..0000000 --- a/ft_strdup.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "libft.h" -#include - -char * -ft_strdup (const char *s) -{ - size_t len; - char *dup; - - len = ft_strlen (s); - dup = malloc (len + 1); - if (!dup) - return (NULL); - ft_memcpy (dup, s, len + 1); - return (dup); -} diff --git a/ft_strlcat.c b/ft_strlcat.c deleted file mode 100644 index 1274ba5..0000000 --- a/ft_strlcat.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "libft.h" - -size_t -ft_strlcat (char *dst, const char *src, size_t size) -{ - size_t dst_len; - size_t src_len; - size_t avail; - - dst_len = ft_strlen (dst); - src_len = ft_strlen (src); - if (dst_len >= size) - return (size + src_len); - avail = size - dst_len - 1; - if (src_len < avail) - ft_memcpy (dst + dst_len, src, src_len + 1); - else - { - ft_memcpy (dst + dst_len, src, avail); - dst[size - 1] = '\0'; - } - return (dst_len + src_len); -} diff --git a/ft_strlcpy.c b/ft_strlcpy.c deleted file mode 100644 index 2611041..0000000 --- a/ft_strlcpy.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "libft.h" - -size_t -ft_strlcpy (char *dst, const char *src, size_t size) -{ - size_t src_len; - - src_len = ft_strlen (src); - if (size > 0) - { - if (src_len < size) - ft_memcpy (dst, src, src_len + 1); - else - { - ft_memcpy (dst, src, size - 1); - dst[size - 1] = '\0'; - } - } - return (src_len); -} diff --git a/ft_strlen.c b/ft_strlen.c deleted file mode 100644 index 06b0aae..0000000 --- a/ft_strlen.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "libft.h" - -size_t -ft_strlen (const char *s) -{ - size_t i; - - i = 0; - while (s[i]) - i++; - return (i); -} diff --git a/ft_strncmp.c b/ft_strncmp.c deleted file mode 100644 index 2fa1099..0000000 --- a/ft_strncmp.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "libft.h" - -int -ft_strncmp (const char *s1, const char *s2, size_t n) -{ - while (n--) - { - if ((unsigned char)*s1 != (unsigned char)*s2) - return ((unsigned char)*s1 - (unsigned char)*s2); - if (*s1 == '\0') - return (0); - s1++; - s2++; - } - return (0); -} diff --git a/ft_strnstr.c b/ft_strnstr.c deleted file mode 100644 index 23ac891..0000000 --- a/ft_strnstr.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "libft.h" - -char * -ft_strnstr (const char *big, const char *little, size_t len) -{ - size_t llen; - - if (*little == '\0') - return ((char *)big); - llen = ft_strlen (little); - while (*big && len >= llen) - { - if (ft_memcmp (big, little, llen) == 0) - return ((char *)big); - big++; - len--; - } - return (NULL); -} diff --git a/ft_strrchr.c b/ft_strrchr.c deleted file mode 100644 index 8ec72d1..0000000 --- a/ft_strrchr.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "libft.h" - -char * -ft_strrchr (const char *s, int c) -{ - size_t len; - - len = ft_strlen (s); - while (len > 0) - { - if (s[len] == (char)c) - return ((char *)s + len); - len--; - } - if (s[0] == (char)c) - return ((char *)s); - return (NULL); -} diff --git a/ft_tolower.c b/ft_tolower.c deleted file mode 100644 index 52fbc94..0000000 --- a/ft_tolower.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "libft.h" - -int -ft_tolower (int c) -{ - if (c >= 'A' && c <= 'Z') - return (c + ('a' - 'A')); - return (c); -} diff --git a/ft_toupper.c b/ft_toupper.c deleted file mode 100644 index e52e0fa..0000000 --- a/ft_toupper.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "libft.h" - -int -ft_toupper (int c) -{ - if (c >= 'a' && c <= 'z') - return (c - ('a' - 'A')); - return (c); -} diff --git a/inc/libft.h b/inc/libft.h new file mode 100644 index 0000000..d57cd8d --- /dev/null +++ b/inc/libft.h @@ -0,0 +1,106 @@ +/** + * @file libft.h + * @brief Reimplementations of standard C library functions. + * + * Every function mirrors its libc counterpart unless noted otherwise. + * Functions that operate on raw memory interpret bytes as unsigned char. + * BSD extensions (strlcpy, strlcat, strnstr) follow the OpenBSD semantics. + */ + +#ifndef LIBFT_H +#define LIBFT_H + +#include + +/* ====================================== + * Character classification & conversion + * ====================================== */ + +/** @brief Return non-zero if @p c is an alphabetic letter. */ +int ft_isalpha (int c); +/** @brief Return non-zero if @p c is a decimal digit. */ +int ft_isdigit (int c); +/** @brief Return non-zero if @p c is alphanumeric. */ +int ft_isalnum (int c); +/** @brief Return non-zero if @p c is a 7-bit ASCII value. */ +int ft_isascii (int c); +/** @brief Return non-zero if @p c is a printable character. */ +int ft_isprint (int c); +/** @brief Convert @p c to uppercase if it is a lowercase letter. */ +int ft_toupper (int c); +/** @brief Convert @p c to lowercase if it is an uppercase letter. */ +int ft_tolower (int c); + +/* ====================================== + * String examination + * ====================================== */ + +/** @brief Return the length of the string @p s. */ +size_t ft_strlen (const char *s); +/** + * @brief Compare at most @p n bytes of @p s1 and @p s2. + * @return Negative, zero, or positive integer. + */ +int ft_strncmp (const char *s1, const char *s2, size_t n); +/** @brief Return a pointer to the first occurrence of @p c in @p s. */ +char *ft_strchr (const char *s, int c); +/** @brief Return a pointer to the last occurrence of @p c in @p s. */ +char *ft_strrchr (const char *s, int c); +/** + * @brief Locate @p little in @p big, searching at most @p len bytes. + * @note BSD extension — not available in glibc. + */ +char *ft_strnstr (const char *big, const char *little, size_t len); +/** @brief Convert the initial portion of @p nptr to int. */ +int ft_atoi (const char *nptr); + +/* ====================================== + * String manipulation + * ====================================== */ + +/** + * @brief Copy @p src into @p dst, NUL-terminating the result. + * @return Length of @p src. + * @note BSD extension — not available in glibc. + */ +size_t ft_strlcpy (char *dst, const char *src, size_t size); +/** + * @brief Append @p src to @p dst, NUL-terminating the result. + * @return Intended total length (dst_len + src_len). + * @note BSD extension — not available in glibc. + */ +size_t ft_strlcat (char *dst, const char *src, size_t size); +/** @brief Return a malloc'd duplicate of @p s. */ +char *ft_strdup (const char *s); + +/* ====================================== + * Memory operations + * ====================================== */ + +/** @brief Fill @p n bytes of @p s with the byte @p c. */ +void *ft_memset (void *s, int c, size_t n); +/** @brief Zero @p n bytes starting at @p s. */ +void ft_bzero (void *s, size_t n); +/** @brief Copy @p n bytes from @p src to @p dest (no overlap). */ +void *ft_memcpy (void *dest, const void *src, size_t n); +/** @brief Copy @p n bytes from @p src to @p dest (overlap-safe). */ +void *ft_memmove (void *dest, const void *src, size_t n); +/** @brief Scan @p n bytes of @p s for the byte @p c. */ +void *ft_memchr (const void *s, int c, size_t n); +/** + * @brief Compare @p n bytes of @p s1 and @p s2. + * @return Negative, zero, or positive integer. + */ +int ft_memcmp (const void *s1, const void *s2, size_t n); + +/* ====================================== + * Memory allocation + * ====================================== */ + +/** + * @brief Allocate zeroed memory for @p nmemb elements of @p size bytes. + * @return NULL on overflow or allocation failure. + */ +void *ft_calloc (size_t nmemb, size_t size); + +#endif diff --git a/lib/.gitkeep b/lib/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/libft.h b/libft.h deleted file mode 100644 index d57cd8d..0000000 --- a/libft.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file libft.h - * @brief Reimplementations of standard C library functions. - * - * Every function mirrors its libc counterpart unless noted otherwise. - * Functions that operate on raw memory interpret bytes as unsigned char. - * BSD extensions (strlcpy, strlcat, strnstr) follow the OpenBSD semantics. - */ - -#ifndef LIBFT_H -#define LIBFT_H - -#include - -/* ====================================== - * Character classification & conversion - * ====================================== */ - -/** @brief Return non-zero if @p c is an alphabetic letter. */ -int ft_isalpha (int c); -/** @brief Return non-zero if @p c is a decimal digit. */ -int ft_isdigit (int c); -/** @brief Return non-zero if @p c is alphanumeric. */ -int ft_isalnum (int c); -/** @brief Return non-zero if @p c is a 7-bit ASCII value. */ -int ft_isascii (int c); -/** @brief Return non-zero if @p c is a printable character. */ -int ft_isprint (int c); -/** @brief Convert @p c to uppercase if it is a lowercase letter. */ -int ft_toupper (int c); -/** @brief Convert @p c to lowercase if it is an uppercase letter. */ -int ft_tolower (int c); - -/* ====================================== - * String examination - * ====================================== */ - -/** @brief Return the length of the string @p s. */ -size_t ft_strlen (const char *s); -/** - * @brief Compare at most @p n bytes of @p s1 and @p s2. - * @return Negative, zero, or positive integer. - */ -int ft_strncmp (const char *s1, const char *s2, size_t n); -/** @brief Return a pointer to the first occurrence of @p c in @p s. */ -char *ft_strchr (const char *s, int c); -/** @brief Return a pointer to the last occurrence of @p c in @p s. */ -char *ft_strrchr (const char *s, int c); -/** - * @brief Locate @p little in @p big, searching at most @p len bytes. - * @note BSD extension — not available in glibc. - */ -char *ft_strnstr (const char *big, const char *little, size_t len); -/** @brief Convert the initial portion of @p nptr to int. */ -int ft_atoi (const char *nptr); - -/* ====================================== - * String manipulation - * ====================================== */ - -/** - * @brief Copy @p src into @p dst, NUL-terminating the result. - * @return Length of @p src. - * @note BSD extension — not available in glibc. - */ -size_t ft_strlcpy (char *dst, const char *src, size_t size); -/** - * @brief Append @p src to @p dst, NUL-terminating the result. - * @return Intended total length (dst_len + src_len). - * @note BSD extension — not available in glibc. - */ -size_t ft_strlcat (char *dst, const char *src, size_t size); -/** @brief Return a malloc'd duplicate of @p s. */ -char *ft_strdup (const char *s); - -/* ====================================== - * Memory operations - * ====================================== */ - -/** @brief Fill @p n bytes of @p s with the byte @p c. */ -void *ft_memset (void *s, int c, size_t n); -/** @brief Zero @p n bytes starting at @p s. */ -void ft_bzero (void *s, size_t n); -/** @brief Copy @p n bytes from @p src to @p dest (no overlap). */ -void *ft_memcpy (void *dest, const void *src, size_t n); -/** @brief Copy @p n bytes from @p src to @p dest (overlap-safe). */ -void *ft_memmove (void *dest, const void *src, size_t n); -/** @brief Scan @p n bytes of @p s for the byte @p c. */ -void *ft_memchr (const void *s, int c, size_t n); -/** - * @brief Compare @p n bytes of @p s1 and @p s2. - * @return Negative, zero, or positive integer. - */ -int ft_memcmp (const void *s1, const void *s2, size_t n); - -/* ====================================== - * Memory allocation - * ====================================== */ - -/** - * @brief Allocate zeroed memory for @p nmemb elements of @p size bytes. - * @return NULL on overflow or allocation failure. - */ -void *ft_calloc (size_t nmemb, size_t size); - -#endif diff --git a/src/ft_atoi.c b/src/ft_atoi.c new file mode 100644 index 0000000..2fe091a --- /dev/null +++ b/src/ft_atoi.c @@ -0,0 +1,26 @@ +#include "libft.h" + +int +ft_atoi (const char *nptr) +{ + int sign; + int result; + + result = 0; + sign = 1; + // Skip isspace() characters: space, \t, \n, \v, \f, \r. + while (*nptr == ' ' || (*nptr >= '\t' && *nptr <= '\r')) + nptr++; + if (*nptr == '-' || *nptr == '+') + { + if (*nptr == '-') + sign = -1; + nptr++; + } + while (*nptr >= '0' && *nptr <= '9') + { + result = result * 10 + (*nptr - '0'); + nptr++; + } + return (result * sign); +} diff --git a/src/ft_bzero.c b/src/ft_bzero.c new file mode 100644 index 0000000..10f67bd --- /dev/null +++ b/src/ft_bzero.c @@ -0,0 +1,7 @@ +#include "libft.h" + +void +ft_bzero (void *s, size_t n) +{ + ft_memset (s, 0, n); +} diff --git a/src/ft_calloc.c b/src/ft_calloc.c new file mode 100644 index 0000000..7726c64 --- /dev/null +++ b/src/ft_calloc.c @@ -0,0 +1,19 @@ +#include "libft.h" +#include + +void * +ft_calloc (size_t nmemb, size_t size) +{ + void *ptr; + size_t total; + + // Detect multiplication overflow before allocating. + if (nmemb && size > (size_t)-1 / nmemb) + return (NULL); + total = nmemb * size; + ptr = malloc (total); + if (!ptr) + return (NULL); + ft_bzero (ptr, total); + return (ptr); +} diff --git a/src/ft_isalnum.c b/src/ft_isalnum.c new file mode 100644 index 0000000..4b477f8 --- /dev/null +++ b/src/ft_isalnum.c @@ -0,0 +1,7 @@ +#include "libft.h" + +int +ft_isalnum (int c) +{ + return (ft_isalpha (c) || ft_isdigit (c)); +} diff --git a/src/ft_isalpha.c b/src/ft_isalpha.c new file mode 100644 index 0000000..c19cf58 --- /dev/null +++ b/src/ft_isalpha.c @@ -0,0 +1,7 @@ +#include "libft.h" + +int +ft_isalpha (int c) +{ + return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); +} diff --git a/src/ft_isascii.c b/src/ft_isascii.c new file mode 100644 index 0000000..f9e877e --- /dev/null +++ b/src/ft_isascii.c @@ -0,0 +1,7 @@ +#include "libft.h" + +int +ft_isascii (int c) +{ + return (c >= 0 && c <= 127); +} diff --git a/src/ft_isdigit.c b/src/ft_isdigit.c new file mode 100644 index 0000000..43de53f --- /dev/null +++ b/src/ft_isdigit.c @@ -0,0 +1,7 @@ +#include "libft.h" + +int +ft_isdigit (int c) +{ + return (c >= '0' && c <= '9'); +} diff --git a/src/ft_isprint.c b/src/ft_isprint.c new file mode 100644 index 0000000..73964ff --- /dev/null +++ b/src/ft_isprint.c @@ -0,0 +1,7 @@ +#include "libft.h" + +int +ft_isprint (int c) +{ + return (c >= 32 && c <= 126); +} diff --git a/src/ft_memchr.c b/src/ft_memchr.c new file mode 100644 index 0000000..08d5c3e --- /dev/null +++ b/src/ft_memchr.c @@ -0,0 +1,16 @@ +#include "libft.h" + +void * +ft_memchr (const void *s, int c, size_t n) +{ + const unsigned char *ptr; + + ptr = s; + while (n--) + { + if (*ptr == (unsigned char)c) + return ((void *)ptr); + ptr++; + } + return (NULL); +} diff --git a/src/ft_memcmp.c b/src/ft_memcmp.c new file mode 100644 index 0000000..ce6cc77 --- /dev/null +++ b/src/ft_memcmp.c @@ -0,0 +1,19 @@ +#include "libft.h" + +int +ft_memcmp (const void *s1, const void *s2, size_t n) +{ + const unsigned char *p1; + const unsigned char *p2; + + p1 = s1; + p2 = s2; + while (n--) + { + if (*p1 != *p2) + return (*p1 - *p2); + p1++; + p2++; + } + return (0); +} diff --git a/src/ft_memcpy.c b/src/ft_memcpy.c new file mode 100644 index 0000000..26c4f76 --- /dev/null +++ b/src/ft_memcpy.c @@ -0,0 +1,16 @@ +#include "libft.h" + +void * +ft_memcpy (void *dest, const void *src, size_t n) +{ + unsigned char *dst_bytes; + const unsigned char *src_bytes; + + if (!dest && !src) + return (dest); + dst_bytes = dest; + src_bytes = src; + while (n--) + *dst_bytes++ = *src_bytes++; + return (dest); +} diff --git a/src/ft_memmove.c b/src/ft_memmove.c new file mode 100644 index 0000000..ace0d90 --- /dev/null +++ b/src/ft_memmove.c @@ -0,0 +1,26 @@ +#include "libft.h" + +void * +ft_memmove (void *dest, const void *src, size_t n) +{ + unsigned char *dst_bytes; + const unsigned char *src_bytes; + + if (!dest && !src) + return (dest); + dst_bytes = dest; + src_bytes = src; + if (dst_bytes > src_bytes) + { + dst_bytes += n; + src_bytes += n; + while (n--) + *--dst_bytes = *--src_bytes; + } + else + { + while (n--) + *dst_bytes++ = *src_bytes++; + } + return (dest); +} diff --git a/src/ft_memset.c b/src/ft_memset.c new file mode 100644 index 0000000..5be8fe6 --- /dev/null +++ b/src/ft_memset.c @@ -0,0 +1,12 @@ +#include "libft.h" + +void * +ft_memset (void *s, int c, size_t n) +{ + unsigned char *ptr; + + ptr = s; + while (n--) + *ptr++ = (unsigned char)c; + return (s); +} diff --git a/src/ft_strchr.c b/src/ft_strchr.c new file mode 100644 index 0000000..0952232 --- /dev/null +++ b/src/ft_strchr.c @@ -0,0 +1,7 @@ +#include "libft.h" + +char * +ft_strchr (const char *s, int c) +{ + return (ft_memchr (s, c, ft_strlen (s) + 1)); +} diff --git a/src/ft_strdup.c b/src/ft_strdup.c new file mode 100644 index 0000000..3a6be31 --- /dev/null +++ b/src/ft_strdup.c @@ -0,0 +1,16 @@ +#include "libft.h" +#include + +char * +ft_strdup (const char *s) +{ + size_t len; + char *dup; + + len = ft_strlen (s); + dup = malloc (len + 1); + if (!dup) + return (NULL); + ft_memcpy (dup, s, len + 1); + return (dup); +} diff --git a/src/ft_strlcat.c b/src/ft_strlcat.c new file mode 100644 index 0000000..1274ba5 --- /dev/null +++ b/src/ft_strlcat.c @@ -0,0 +1,23 @@ +#include "libft.h" + +size_t +ft_strlcat (char *dst, const char *src, size_t size) +{ + size_t dst_len; + size_t src_len; + size_t avail; + + dst_len = ft_strlen (dst); + src_len = ft_strlen (src); + if (dst_len >= size) + return (size + src_len); + avail = size - dst_len - 1; + if (src_len < avail) + ft_memcpy (dst + dst_len, src, src_len + 1); + else + { + ft_memcpy (dst + dst_len, src, avail); + dst[size - 1] = '\0'; + } + return (dst_len + src_len); +} diff --git a/src/ft_strlcpy.c b/src/ft_strlcpy.c new file mode 100644 index 0000000..2611041 --- /dev/null +++ b/src/ft_strlcpy.c @@ -0,0 +1,20 @@ +#include "libft.h" + +size_t +ft_strlcpy (char *dst, const char *src, size_t size) +{ + size_t src_len; + + src_len = ft_strlen (src); + if (size > 0) + { + if (src_len < size) + ft_memcpy (dst, src, src_len + 1); + else + { + ft_memcpy (dst, src, size - 1); + dst[size - 1] = '\0'; + } + } + return (src_len); +} diff --git a/src/ft_strlen.c b/src/ft_strlen.c new file mode 100644 index 0000000..06b0aae --- /dev/null +++ b/src/ft_strlen.c @@ -0,0 +1,12 @@ +#include "libft.h" + +size_t +ft_strlen (const char *s) +{ + size_t i; + + i = 0; + while (s[i]) + i++; + return (i); +} diff --git a/src/ft_strncmp.c b/src/ft_strncmp.c new file mode 100644 index 0000000..2fa1099 --- /dev/null +++ b/src/ft_strncmp.c @@ -0,0 +1,16 @@ +#include "libft.h" + +int +ft_strncmp (const char *s1, const char *s2, size_t n) +{ + while (n--) + { + if ((unsigned char)*s1 != (unsigned char)*s2) + return ((unsigned char)*s1 - (unsigned char)*s2); + if (*s1 == '\0') + return (0); + s1++; + s2++; + } + return (0); +} diff --git a/src/ft_strnstr.c b/src/ft_strnstr.c new file mode 100644 index 0000000..23ac891 --- /dev/null +++ b/src/ft_strnstr.c @@ -0,0 +1,19 @@ +#include "libft.h" + +char * +ft_strnstr (const char *big, const char *little, size_t len) +{ + size_t llen; + + if (*little == '\0') + return ((char *)big); + llen = ft_strlen (little); + while (*big && len >= llen) + { + if (ft_memcmp (big, little, llen) == 0) + return ((char *)big); + big++; + len--; + } + return (NULL); +} diff --git a/src/ft_strrchr.c b/src/ft_strrchr.c new file mode 100644 index 0000000..8ec72d1 --- /dev/null +++ b/src/ft_strrchr.c @@ -0,0 +1,18 @@ +#include "libft.h" + +char * +ft_strrchr (const char *s, int c) +{ + size_t len; + + len = ft_strlen (s); + while (len > 0) + { + if (s[len] == (char)c) + return ((char *)s + len); + len--; + } + if (s[0] == (char)c) + return ((char *)s); + return (NULL); +} diff --git a/src/ft_tolower.c b/src/ft_tolower.c new file mode 100644 index 0000000..52fbc94 --- /dev/null +++ b/src/ft_tolower.c @@ -0,0 +1,9 @@ +#include "libft.h" + +int +ft_tolower (int c) +{ + if (c >= 'A' && c <= 'Z') + return (c + ('a' - 'A')); + return (c); +} diff --git a/src/ft_toupper.c b/src/ft_toupper.c new file mode 100644 index 0000000..e52e0fa --- /dev/null +++ b/src/ft_toupper.c @@ -0,0 +1,9 @@ +#include "libft.h" + +int +ft_toupper (int c) +{ + if (c >= 'a' && c <= 'z') + return (c - ('a' - 'A')); + return (c); +} diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..0e64d2c --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,3 @@ +*.o +bin/* +!.gitkeep diff --git a/tests/Makefile b/tests/Makefile index 319fa22..f7f7ed4 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,31 +1,42 @@ CC = cc -CFLAGS = -LIB = ../libft.a +CFLAGS = -I ../inc -I inc + +SRCDIR = src +BINDIR = bin + +LIB = ../lib/libft.a TESTS = test_strlen test_is test_mem test_cmp test_case test_strl test_search \ test_atoi test_alloc -all: $(TESTS) - @for t in $(TESTS); do \ - echo "--- Running $$t ---"; \ +BINS = $(TESTS:%=$(BINDIR)/%) + +all: $(BINS) + @for t in $(BINS); do \ + echo "$$(basename $$t):"; \ ./$$t; \ done -test_%: test_%.c $(LIB) +# Order-only prerequisite (|): create bin/ if missing, but don't +# rebuild binaries just because the directory's mtime changed. +$(BINDIR)/test_%: $(SRCDIR)/test_%.c $(LIB) | $(BINDIR) $(CC) $(CFLAGS) -o $@ $< $(LIB) # Tests comparing against BSD functions (strlcpy, strlcat, strnstr) # need -lbsd since these are not part of glibc by default. -test_strl: test_strl.c $(LIB) +$(BINDIR)/test_strl: $(SRCDIR)/test_strl.c $(LIB) | $(BINDIR) $(CC) $(CFLAGS) -o $@ $< $(LIB) -lbsd -test_search: test_search.c $(LIB) +$(BINDIR)/test_search: $(SRCDIR)/test_search.c $(LIB) | $(BINDIR) $(CC) $(CFLAGS) -o $@ $< $(LIB) -lbsd +$(BINDIR): + mkdir -p $(BINDIR) + $(LIB): $(MAKE) -C .. clean: - rm -f $(TESTS) + rm -f $(BINS) .PHONY: all clean diff --git a/tests/bin/.gitkeep b/tests/bin/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/inc/test_utils.h b/tests/inc/test_utils.h new file mode 100644 index 0000000..0cb6655 --- /dev/null +++ b/tests/inc/test_utils.h @@ -0,0 +1,246 @@ +/** + * @file test_utils.h + * @brief Minimal test harness for libft unit tests. + * + * Header-only: each test_*.c translation unit gets its own copy + * of the counters and helpers via static linkage. + * + * Output is compact: only failures are printed individually. + * Each section gets a one-line summary, and a totals line is + * printed at the end. + */ + +#ifndef TEST_UTILS_H +#define TEST_UTILS_H + +#include +#include +#include +#include +#include +#include + +/* ── global counters ──────────────────────────────────────────────── */ + +static int _s_pass = 0; +static int _s_fail = 0; + +static const char *_s_section_name = NULL; +static int _s_section_pass = 0; +static int _s_section_fail = 0; +static int _s_had_sections = 0; + +/* volatile: prevent dead-store elimination when the return + value of the tested function is never read. */ +static volatile size_t _s_sink; +static volatile int _s_sink_i; + +/* ── sections and assertions ──────────────────────────────────────── */ + +/** Print the current section's summary line and reset its counters. */ +static void +_s_section_end (void) +{ + if (_s_section_name == NULL) + return; + if (_s_section_fail > 0) + printf (" %-16s %d passed, %d failed\n", _s_section_name, _s_section_pass, + _s_section_fail); + else + printf (" %-16s %d passed\n", _s_section_name, _s_section_pass); + _s_section_name = NULL; + _s_section_pass = 0; + _s_section_fail = 0; +} + +/** Close the previous section (if any) and open a new one. */ +static void +_s_section (const char *name) +{ + _s_section_end (); + _s_section_name = name; + _s_had_sections = 1; +} + +/** Record a pass (@p ok true) or print FAIL and record a failure. */ +static void +_s_check (const char *label, int ok) +{ + if (ok) + { + _s_pass++; + _s_section_pass++; + } + else + { + printf (" FAIL %s\n", label); + _s_fail++; + _s_section_fail++; + } +} + +/** Pass if @p got == @p expected; on failure print both values. */ +static void +_s_check_eq (const char *label, size_t got, size_t expected) +{ + if (got == expected) + { + _s_pass++; + _s_section_pass++; + } + else + { + printf (" FAIL %s: got %zu, expected %zu\n", label, got, expected); + _s_fail++; + _s_section_fail++; + } +} + +/** Pass if @p got == @p expected (int variant); print both on failure. */ +static void +_s_check_eq_int (const char *label, int got, int expected) +{ + if (got == expected) + { + _s_pass++; + _s_section_pass++; + } + else + { + printf (" FAIL %s: got %d, expected %d\n", label, got, expected); + _s_fail++; + _s_section_fail++; + } +} + +/* ── crash detection ──────────────────────────────────────────────── */ + +/** Run @p fn in a child process; return 1 if it was killed by a signal. */ +static int +_s_crashes (void (*fn) (void)) +{ + pid_t pid; + int status; + + pid = fork (); + if (pid == 0) + { + fn (); + _exit (0); + } + waitpid (pid, &status, 0); + return (WIFSIGNALED (status)); +} + +static void +_s_check_both_crash (const char *label, void (*ft_fn) (void), + void (*libc_fn) (void)) +{ + int ft_crashed; + int libc_crashed; + + ft_crashed = _s_crashes (ft_fn); + libc_crashed = _s_crashes (libc_fn); + if (ft_crashed == libc_crashed) + { + _s_pass++; + _s_section_pass++; + } + else + { + printf (" FAIL %s: ft_crashed=%d libc_crashed=%d\n", label, + ft_crashed, libc_crashed); + _s_fail++; + _s_section_fail++; + } +} + +/* ── crash-wrapper macros ─────────────────────────────────────────── */ + +/* pointer-returning expression → _s_sink */ +#define _S_CRASH(tag, expr) \ + static void _s_crash_##tag (void) { _s_sink = (size_t)(expr); } + +/* int-returning expression → _s_sink_i */ +#define _S_CRASH_I(tag, expr) \ + static void _s_crash_##tag (void) { _s_sink_i = (expr); } + +/* void expression (e.g. ft_bzero) */ +#define _S_CRASH_V(tag, expr) \ + static void _s_crash_##tag (void) { (expr); } + +/* needs a local char buf[N] before the expression */ +#define _S_CRASH_BUF(tag, bufsz, expr) \ + static void _s_crash_##tag (void) \ + { \ + char buf[bufsz]; \ + (void)buf; \ + (expr); \ + } + +/* ── int-range comparison helper ─────────────────────────────────── */ + +/* Compare ft(i) vs libc(i) for i in [-1..255]. + If normalize is true, compares !!ft(i) == !!libc(i) (for is* funcs). + Otherwise exact comparison (for toupper/tolower). */ +static void +_s_test_int_range (const char *name, int (*ft) (int), int (*libc) (int), + int normalize) +{ + int i; + int ft_r; + int libc_r; + int ok; + + ok = 1; + for (i = -1; i <= 255; i++) + { + if (normalize) + { + ft_r = !!ft (i); + libc_r = !!libc (i); + } + else + { + ft_r = ft (i); + libc_r = libc (i); + } + if (ft_r != libc_r) + { + char label[64]; + snprintf (label, sizeof (label), "%s(%d): ft=%d libc=%d", name, i, + ft_r, libc_r); + _s_check (label, 0); + ok = 0; + } + } + if (ok) + _s_check (name, 1); +} + +/* ── helpers and output ───────────────────────────────────────────── */ + +#define _S_RAND_ITERS 50 + +/** Normalize to -1/0/1 for sign comparison (memcmp, strncmp). */ +static int +_s_sign (int x) +{ + if (x > 0) + return (1); + if (x < 0) + return (-1); + return (0); +} + +static void +_s_print_results (void) +{ + _s_section_end (); + if (_s_fail > 0) + printf (" %d passed, %d failed\n", _s_pass, _s_fail); + else if (!_s_had_sections) + printf (" %d passed\n", _s_pass); +} + +#endif diff --git a/tests/src/test_alloc.c b/tests/src/test_alloc.c new file mode 100644 index 0000000..6441cd5 --- /dev/null +++ b/tests/src/test_alloc.c @@ -0,0 +1,151 @@ +#include "libft.h" +#include "test_utils.h" + +_S_CRASH (ft_strdup_null, ft_strdup (NULL)) +_S_CRASH (libc_strdup_null, strdup (NULL)) + +/* ====================================== + * calloc + * ====================================== */ + +static void +_s_test_calloc (void) +{ + int i; + char label[64]; + + _s_section ("ft_calloc"); + + /* zeroed memory */ + { + char *ft_p = ft_calloc (100, 1); + char *libc_p = calloc (100, 1); + _s_check ("zeroed", ft_p && libc_p && memcmp (ft_p, libc_p, 100) == 0); + free (ft_p); + free (libc_p); + } + + /* nmemb=0 */ + { + void *p = ft_calloc (0, 10); + _s_check ("nmemb=0 not NULL", p != NULL); + free (p); + } + + /* size=0 */ + { + void *p = ft_calloc (10, 0); + _s_check ("size=0 not NULL", p != NULL); + free (p); + } + + /* overflow protection */ + { + void *p = ft_calloc ((size_t)-1, 2); + _s_check ("overflow returns NULL", p == NULL); + } + + /* single byte */ + { + unsigned char *p = ft_calloc (1, 1); + _s_check ("single byte zeroed", p && *p == 0); + free (p); + } + + /* randomized: check all bytes are zero */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + size_t nmemb = rand () % 500 + 1; + size_t size = rand () % 50 + 1; + unsigned char *ft_p = ft_calloc (nmemb, size); + unsigned char *libc_p = calloc (nmemb, size); + int ok = 1; + size_t j; + if (!ft_p || !libc_p) + { + ok = 0; + } + else + { + for (j = 0; j < nmemb * size; j++) + { + if (ft_p[j] != 0) + { + ok = 0; + break; + } + } + } + snprintf (label, sizeof (label), "random nmemb=%zu size=%zu", nmemb, + size); + _s_check (label, ok); + free (ft_p); + free (libc_p); + } +} + +/* ====================================== + * strdup + * ====================================== */ + +static void +_s_test_strdup (void) +{ + int i; + char label[64]; + + _s_section ("ft_strdup"); + + /* NULL */ + _s_check_both_crash ("strdup NULL", _s_crash_ft_strdup_null, + _s_crash_libc_strdup_null); + + /* empty string */ + { + char *p = ft_strdup (""); + _s_check ("empty", p && strcmp (p, "") == 0); + free (p); + } + + /* returns independent copy */ + { + char src[] = "hello"; + char *p = ft_strdup (src); + _s_check ("independent copy", p && p != src && strcmp (p, src) == 0); + src[0] = 'X'; + _s_check ("mutation safe", p[0] == 'h'); + free (p); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int len = rand () % 500 + 1; + char *src = malloc (len + 1); + int j; + char *ft_p; + char *libc_p; + if (!src) + continue; + for (j = 0; j < len; j++) + src[j] = 'A' + rand () % 26; + src[len] = '\0'; + ft_p = ft_strdup (src); + libc_p = strdup (src); + snprintf (label, sizeof (label), "random len=%d", len); + _s_check (label, ft_p && libc_p && strcmp (ft_p, libc_p) == 0); + free (src); + free (ft_p); + free (libc_p); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_calloc (); + _s_test_strdup (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_atoi.c b/tests/src/test_atoi.c new file mode 100644 index 0000000..91e4dc4 --- /dev/null +++ b/tests/src/test_atoi.c @@ -0,0 +1,49 @@ +#include "libft.h" +#include "test_utils.h" +#include + +_S_CRASH_I (ft_atoi_null, ft_atoi (NULL)) +_S_CRASH_I (libc_atoi_null, atoi (NULL)) + +int +main (void) +{ + int i; + char buf[64]; + char label[64]; + + srand (time (NULL)); + _s_section ("ft_atoi"); + _s_check_both_crash ("atoi NULL", _s_crash_ft_atoi_null, + _s_crash_libc_atoi_null); + + /* edge cases */ + _s_check_eq_int ("zero", ft_atoi ("0"), atoi ("0")); + _s_check_eq_int ("INT_MAX", ft_atoi ("2147483647"), atoi ("2147483647")); + _s_check_eq_int ("INT_MIN", ft_atoi ("-2147483648"), atoi ("-2147483648")); + _s_check_eq_int ("negative", ft_atoi ("-42"), atoi ("-42")); + _s_check_eq_int ("explicit +", ft_atoi ("+42"), atoi ("+42")); + _s_check_eq_int ("leading spaces", ft_atoi (" 42"), atoi (" 42")); + _s_check_eq_int ("leading tabs", ft_atoi ("\t\n\v\f\r 42"), + atoi ("\t\n\v\f\r 42")); + _s_check_eq_int ("trailing chars", ft_atoi ("42abc"), atoi ("42abc")); + _s_check_eq_int ("empty string", ft_atoi (""), atoi ("")); + _s_check_eq_int ("only spaces", ft_atoi (" "), atoi (" ")); + _s_check_eq_int ("only sign", ft_atoi ("-"), atoi ("-")); + _s_check_eq_int ("sign then space", ft_atoi ("- 42"), atoi ("- 42")); + _s_check_eq_int ("double sign", ft_atoi ("--42"), atoi ("--42")); + _s_check_eq_int ("space between", ft_atoi ("4 2"), atoi ("4 2")); + _s_check_eq_int ("leading zeros", ft_atoi ("00042"), atoi ("00042")); + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int v = rand () - RAND_MAX / 2; + snprintf (buf, sizeof (buf), "%d", v); + snprintf (label, sizeof (label), "random %s", buf); + _s_check_eq_int (label, ft_atoi (buf), atoi (buf)); + } + + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_case.c b/tests/src/test_case.c new file mode 100644 index 0000000..920dc95 --- /dev/null +++ b/tests/src/test_case.c @@ -0,0 +1,14 @@ +#include "libft.h" +#include "test_utils.h" +#include + +int +main (void) +{ + _s_section ("ft_toupper"); + _s_test_int_range ("ft_toupper", ft_toupper, toupper, 0); + _s_section ("ft_tolower"); + _s_test_int_range ("ft_tolower", ft_tolower, tolower, 0); + _s_print_results (); + return (_s_fail != 0); +} 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); +} diff --git a/tests/src/test_is.c b/tests/src/test_is.c new file mode 100644 index 0000000..c0edfa8 --- /dev/null +++ b/tests/src/test_is.c @@ -0,0 +1,20 @@ +#include "libft.h" +#include "test_utils.h" +#include + +int +main (void) +{ + _s_section ("ft_isalpha"); + _s_test_int_range ("ft_isalpha", ft_isalpha, isalpha, 1); + _s_section ("ft_isdigit"); + _s_test_int_range ("ft_isdigit", ft_isdigit, isdigit, 1); + _s_section ("ft_isalnum"); + _s_test_int_range ("ft_isalnum", ft_isalnum, isalnum, 1); + _s_section ("ft_isascii"); + _s_test_int_range ("ft_isascii", ft_isascii, isascii, 1); + _s_section ("ft_isprint"); + _s_test_int_range ("ft_isprint", ft_isprint, isprint, 1); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_mem.c b/tests/src/test_mem.c new file mode 100644 index 0000000..3653004 --- /dev/null +++ b/tests/src/test_mem.c @@ -0,0 +1,249 @@ +#include "libft.h" +#include "test_utils.h" +#include + +_S_CRASH (ft_memset_null, ft_memset (NULL, 'A', 10)) +_S_CRASH (libc_memset_null, memset (NULL, 'A', 10)) +_S_CRASH_V (ft_bzero_null, ft_bzero (NULL, 10)) +_S_CRASH_V (libc_bzero_null, bzero (NULL, 10)) +_S_CRASH_BUF (ft_memcpy_null_dst, 10, + _s_sink = (size_t)ft_memcpy (NULL, buf, 10)) +_S_CRASH_BUF (libc_memcpy_null_dst, 10, + _s_sink = (size_t)memcpy (NULL, buf, 10)) +_S_CRASH_BUF (ft_memcpy_null_src, 10, + _s_sink = (size_t)ft_memcpy (buf, NULL, 10)) +_S_CRASH_BUF (libc_memcpy_null_src, 10, + _s_sink = (size_t)memcpy (buf, NULL, 10)) +_S_CRASH_BUF (ft_memmove_null_dst, 10, + _s_sink = (size_t)ft_memmove (NULL, buf, 10)) +_S_CRASH_BUF (libc_memmove_null_dst, 10, + _s_sink = (size_t)memmove (NULL, buf, 10)) +_S_CRASH_BUF (ft_memmove_null_src, 10, + _s_sink = (size_t)ft_memmove (buf, NULL, 10)) +_S_CRASH_BUF (libc_memmove_null_src, 10, + _s_sink = (size_t)memmove (buf, NULL, 10)) + +/* ====================================== + * memset + * ====================================== */ + +static void +_s_test_memset (void) +{ + char ft_buf[256]; + char libc_buf[256]; + int i; + int c; + size_t len; + void *ret; + char label[64]; + + _s_section ("ft_memset"); + + /* NULL */ + _s_check_both_crash ("memset NULL", _s_crash_ft_memset_null, + _s_crash_libc_memset_null); + + /* zero length */ + memset (ft_buf, 'X', 256); + memset (libc_buf, 'X', 256); + ft_memset (ft_buf, 'A', 0); + memset (libc_buf, 'A', 0); + _s_check ("n=0", memcmp (ft_buf, libc_buf, 256) == 0); + + /* return value */ + ret = ft_memset (ft_buf, 'B', 10); + _s_check ("return value", ret == ft_buf); + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + c = rand () % 256; + len = rand () % 256; + ft_memset (ft_buf, c, len); + memset (libc_buf, c, len); + snprintf (label, sizeof (label), "random c=%d len=%zu", c, len); + _s_check (label, memcmp (ft_buf, libc_buf, len) == 0); + } +} + +/* ====================================== + * bzero + * ====================================== */ + +static void +_s_test_bzero (void) +{ + char ft_buf[256]; + char libc_buf[256]; + int i; + size_t len; + char label[64]; + + _s_section ("ft_bzero"); + + /* NULL */ + _s_check_both_crash ("bzero NULL", _s_crash_ft_bzero_null, + _s_crash_libc_bzero_null); + + /* zero length */ + memset (ft_buf, 'X', 256); + memset (libc_buf, 'X', 256); + ft_bzero (ft_buf, 0); + bzero (libc_buf, 0); + _s_check ("n=0", memcmp (ft_buf, libc_buf, 256) == 0); + + /* full clear */ + memset (ft_buf, 'X', 256); + memset (libc_buf, 'X', 256); + ft_bzero (ft_buf, 256); + bzero (libc_buf, 256); + _s_check ("n=256", memcmp (ft_buf, libc_buf, 256) == 0); + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + len = rand () % 256; + memset (ft_buf, 'Z', 256); + memset (libc_buf, 'Z', 256); + ft_bzero (ft_buf, len); + bzero (libc_buf, len); + snprintf (label, sizeof (label), "random len=%zu", len); + _s_check (label, memcmp (ft_buf, libc_buf, 256) == 0); + } +} + +/* ====================================== + * memcpy + * ====================================== */ + +static void +_s_test_memcpy (void) +{ + char src[256]; + char ft_dst[256]; + char libc_dst[256]; + int i; + size_t len; + void *ret; + char label[64]; + + _s_section ("ft_memcpy"); + + /* NULL */ + _s_check_both_crash ("memcpy NULL dst", _s_crash_ft_memcpy_null_dst, + _s_crash_libc_memcpy_null_dst); + _s_check_both_crash ("memcpy NULL src", _s_crash_ft_memcpy_null_src, + _s_crash_libc_memcpy_null_src); + + /* fill source with pattern */ + for (i = 0; i < 256; i++) + src[i] = i; + + /* zero length */ + memset (ft_dst, 'X', 256); + memset (libc_dst, 'X', 256); + ft_memcpy (ft_dst, src, 0); + memcpy (libc_dst, src, 0); + _s_check ("n=0", memcmp (ft_dst, libc_dst, 256) == 0); + + /* return value */ + ret = ft_memcpy (ft_dst, src, 10); + _s_check ("return value", ret == ft_dst); + + /* NULL src and dst with n=0 */ + ret = ft_memcpy (NULL, NULL, 0); + _s_check ("NULL,NULL,0", ret == NULL); + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + len = rand () % 256; + memset (ft_dst, 0, 256); + memset (libc_dst, 0, 256); + ft_memcpy (ft_dst, src, len); + memcpy (libc_dst, src, len); + snprintf (label, sizeof (label), "random len=%zu", len); + _s_check (label, memcmp (ft_dst, libc_dst, 256) == 0); + } +} + +/* ====================================== + * memmove + * ====================================== */ + +static void +_s_test_memmove (void) +{ + char ft_buf[256]; + char libc_buf[256]; + int i; + size_t len; + size_t offset; + void *ret; + char label[64]; + + _s_section ("ft_memmove"); + + /* NULL */ + _s_check_both_crash ("memmove NULL dst", _s_crash_ft_memmove_null_dst, + _s_crash_libc_memmove_null_dst); + _s_check_both_crash ("memmove NULL src", _s_crash_ft_memmove_null_src, + _s_crash_libc_memmove_null_src); + + /* return value */ + memset (ft_buf, 'A', 256); + ret = ft_memmove (ft_buf, ft_buf + 10, 10); + _s_check ("return value", ret == ft_buf); + + /* NULL src and dst with n=0 */ + ret = ft_memmove (NULL, NULL, 0); + _s_check ("NULL,NULL,0", ret == NULL); + + /* forward overlap: src before dest */ + for (i = 0; i < 256; i++) + ft_buf[i] = libc_buf[i] = i; + ft_memmove (ft_buf + 10, ft_buf, 100); + memmove (libc_buf + 10, libc_buf, 100); + _s_check ("forward overlap", memcmp (ft_buf, libc_buf, 256) == 0); + + /* backward overlap: dest before src */ + for (i = 0; i < 256; i++) + ft_buf[i] = libc_buf[i] = i; + ft_memmove (ft_buf, ft_buf + 10, 100); + memmove (libc_buf, libc_buf + 10, 100); + _s_check ("backward overlap", memcmp (ft_buf, libc_buf, 256) == 0); + + /* non-overlapping */ + for (i = 0; i < 256; i++) + ft_buf[i] = libc_buf[i] = i; + ft_memmove (ft_buf + 128, ft_buf, 50); + memmove (libc_buf + 128, libc_buf, 50); + _s_check ("non-overlapping", memcmp (ft_buf, libc_buf, 256) == 0); + + /* randomized overlapping copies */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + for (int j = 0; j < 256; j++) + ft_buf[j] = libc_buf[j] = rand () % 256; + len = rand () % 128 + 1; + offset = rand () % 128; + ft_memmove (ft_buf + offset, ft_buf, len); + memmove (libc_buf + offset, libc_buf, len); + snprintf (label, sizeof (label), "random overlap len=%zu off=%zu", len, + offset); + _s_check (label, memcmp (ft_buf, libc_buf, 256) == 0); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_memset (); + _s_test_bzero (); + _s_test_memcpy (); + _s_test_memmove (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_search.c b/tests/src/test_search.c new file mode 100644 index 0000000..be885b2 --- /dev/null +++ b/tests/src/test_search.c @@ -0,0 +1,253 @@ +#include "libft.h" +#include "test_utils.h" +#include + +_S_CRASH (ft_strchr_null, ft_strchr (NULL, 'a')) +_S_CRASH (libc_strchr_null, strchr (NULL, 'a')) +_S_CRASH (ft_strrchr_null, ft_strrchr (NULL, 'a')) +_S_CRASH (libc_strrchr_null, strrchr (NULL, 'a')) +_S_CRASH (ft_strnstr_null_big, ft_strnstr (NULL, "abc", 10)) +_S_CRASH (libc_strnstr_null_big, strnstr (NULL, "abc", 10)) +_S_CRASH (ft_strnstr_null_little, ft_strnstr ("abc", NULL, 10)) +_S_CRASH (libc_strnstr_null_little, strnstr ("abc", NULL, 10)) + +/* ====================================== + * strchr + * ====================================== */ + +static void +_s_test_strchr (void) +{ + char buf[] = "hello world"; + int i; + char label[64]; + + _s_section ("ft_strchr"); + + /* NULL */ + _s_check_both_crash ("strchr NULL", _s_crash_ft_strchr_null, + _s_crash_libc_strchr_null); + + /* find first occurrence */ + _s_check ("find 'l'", ft_strchr (buf, 'l') == strchr (buf, 'l')); + + /* find first char */ + _s_check ("find 'h'", ft_strchr (buf, 'h') == strchr (buf, 'h')); + + /* find last char */ + _s_check ("find 'd'", ft_strchr (buf, 'd') == strchr (buf, 'd')); + + /* not found */ + _s_check ("not found 'z'", ft_strchr (buf, 'z') == strchr (buf, 'z')); + + /* find null terminator */ + _s_check ("find '\\0'", ft_strchr (buf, '\0') == strchr (buf, '\0')); + + /* empty string */ + _s_check ("empty + 'a'", ft_strchr ("", 'a') == strchr ("", 'a')); + _s_check ("empty + '\\0'", ft_strchr ("", '\0') == strchr ("", '\0')); + + /* int truncation to char */ + _s_check ("int truncation", + ft_strchr (buf, 'h' + 256) == strchr (buf, 'h' + 256)); + + /* all printable ASCII */ + for (i = 32; i < 127; i++) + { + snprintf (label, sizeof (label), "char %d in buf", i); + _s_check (label, ft_strchr (buf, i) == strchr (buf, i)); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + char rnd[128]; + int len = rand () % 127 + 1; + int j; + int c; + for (j = 0; j < len; j++) + rnd[j] = 'A' + rand () % 52; + rnd[len] = '\0'; + c = 'A' + rand () % 52; + snprintf (label, sizeof (label), "random len=%d c=%c", len, c); + _s_check (label, ft_strchr (rnd, c) == strchr (rnd, c)); + } +} + +/* ====================================== + * strrchr + * ====================================== */ + +static void +_s_test_strrchr (void) +{ + char buf[] = "hello world"; + int i; + char label[64]; + + _s_section ("ft_strrchr"); + + /* NULL */ + _s_check_both_crash ("strrchr NULL", _s_crash_ft_strrchr_null, + _s_crash_libc_strrchr_null); + + /* find last occurrence */ + _s_check ("find 'l'", ft_strrchr (buf, 'l') == strrchr (buf, 'l')); + + /* only one occurrence */ + _s_check ("find 'w'", ft_strrchr (buf, 'w') == strrchr (buf, 'w')); + + /* find first char */ + _s_check ("find 'h'", ft_strrchr (buf, 'h') == strrchr (buf, 'h')); + + /* find last char */ + _s_check ("find 'd'", ft_strrchr (buf, 'd') == strrchr (buf, 'd')); + + /* not found */ + _s_check ("not found 'z'", ft_strrchr (buf, 'z') == strrchr (buf, 'z')); + + /* find null terminator */ + _s_check ("find '\\0'", ft_strrchr (buf, '\0') == strrchr (buf, '\0')); + + /* empty string */ + _s_check ("empty + 'a'", ft_strrchr ("", 'a') == strrchr ("", 'a')); + _s_check ("empty + '\\0'", ft_strrchr ("", '\0') == strrchr ("", '\0')); + + /* int truncation to char */ + _s_check ("int truncation", + ft_strrchr (buf, 'l' + 256) == strrchr (buf, 'l' + 256)); + + /* multiple occurrences */ + _s_check ("'o' last", + ft_strrchr ("foo bar boo", 'o') == strrchr ("foo bar boo", 'o')); + + /* all printable ASCII */ + for (i = 32; i < 127; i++) + { + snprintf (label, sizeof (label), "char %d in buf", i); + _s_check (label, ft_strrchr (buf, i) == strrchr (buf, i)); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + char rnd[128]; + int len = rand () % 127 + 1; + int j; + int c; + for (j = 0; j < len; j++) + rnd[j] = 'A' + rand () % 52; + rnd[len] = '\0'; + c = 'A' + rand () % 52; + snprintf (label, sizeof (label), "random len=%d c=%c", len, c); + _s_check (label, ft_strrchr (rnd, c) == strrchr (rnd, c)); + } +} + +/* ====================================== + * strnstr + * ====================================== */ + +static void +_s_test_strnstr (void) +{ + char hay[] = "hello world, hello earth"; + + _s_section ("ft_strnstr"); + + /* NULL */ + _s_check_both_crash ("strnstr NULL big", _s_crash_ft_strnstr_null_big, + _s_crash_libc_strnstr_null_big); + _s_check_both_crash ("strnstr NULL little", _s_crash_ft_strnstr_null_little, + _s_crash_libc_strnstr_null_little); + + /* empty needle */ + _s_check ("empty needle", ft_strnstr (hay, "", 24) == strnstr (hay, "", 24)); + + /* empty haystack */ + _s_check ("empty haystack", + ft_strnstr ("", "abc", 0) == strnstr ("", "abc", 0)); + _s_check ("both empty", ft_strnstr ("", "", 0) == strnstr ("", "", 0)); + + /* basic find */ + _s_check ("find 'world'", + ft_strnstr (hay, "world", 24) == strnstr (hay, "world", 24)); + + /* find at start */ + _s_check ("find 'hello'", + ft_strnstr (hay, "hello", 24) == strnstr (hay, "hello", 24)); + + /* find at end */ + _s_check ("find 'earth'", + ft_strnstr (hay, "earth", 24) == strnstr (hay, "earth", 24)); + + /* not found */ + _s_check ("not found 'xyz'", + ft_strnstr (hay, "xyz", 24) == strnstr (hay, "xyz", 24)); + + /* needle longer than len */ + _s_check ("needle beyond len", + ft_strnstr (hay, "world", 8) == strnstr (hay, "world", 8)); + + /* len=0 */ + _s_check ("len=0", + ft_strnstr (hay, "hello", 0) == strnstr (hay, "hello", 0)); + + /* exact match at boundary */ + _s_check ("exact boundary", + ft_strnstr (hay, "world", 11) == strnstr (hay, "world", 11)); + + /* one short of match */ + _s_check ("one short", + ft_strnstr (hay, "world", 10) == strnstr (hay, "world", 10)); + + /* single char needle */ + _s_check ("single char 'w'", + ft_strnstr (hay, "w", 24) == strnstr (hay, "w", 24)); + + /* needle same as haystack */ + _s_check ("needle == haystack", + ft_strnstr ("abc", "abc", 3) == strnstr ("abc", "abc", 3)); + + /* needle longer than haystack */ + _s_check ("needle > haystack", + ft_strnstr ("ab", "abc", 3) == strnstr ("ab", "abc", 3)); + + /* partial match then fail */ + _s_check ("partial match", + ft_strnstr ("aab", "ab", 3) == strnstr ("aab", "ab", 3)); + + /* randomized */ + for (int i = 0; i < _S_RAND_ITERS; i++) + { + char rbig[128]; + char rlittle[16]; + int blen = rand () % 100 + 20; + int llen = rand () % 10 + 1; + size_t n; + int j; + char label[64]; + for (j = 0; j < blen; j++) + rbig[j] = 'A' + rand () % 4; + rbig[blen] = '\0'; + for (j = 0; j < llen; j++) + rlittle[j] = 'A' + rand () % 4; + rlittle[llen] = '\0'; + n = rand () % (blen + 10); + snprintf (label, sizeof (label), "random blen=%d llen=%d n=%zu", blen, + llen, n); + _s_check (label, + ft_strnstr (rbig, rlittle, n) == strnstr (rbig, rlittle, n)); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_strchr (); + _s_test_strrchr (); + _s_test_strnstr (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_strl.c b/tests/src/test_strl.c new file mode 100644 index 0000000..a2caa22 --- /dev/null +++ b/tests/src/test_strl.c @@ -0,0 +1,227 @@ +#include "libft.h" +#include "test_utils.h" +#include + +_S_CRASH (ft_strlcpy_null_dst, ft_strlcpy (NULL, "abc", 10)) +_S_CRASH (libc_strlcpy_null_dst, strlcpy (NULL, "abc", 10)) +_S_CRASH_BUF (ft_strlcpy_null_src, 10, _s_sink = ft_strlcpy (buf, NULL, 10)) +_S_CRASH_BUF (libc_strlcpy_null_src, 10, _s_sink = strlcpy (buf, NULL, 10)) +_S_CRASH (ft_strlcat_null_dst, ft_strlcat (NULL, "abc", 10)) +_S_CRASH (libc_strlcat_null_dst, strlcat (NULL, "abc", 10)) + +/* strlcat NULL src needs an initialized buffer — keep manual */ +static void +_s_crash_ft_strlcat_null_src (void) +{ + char buf[10] = "hi"; + _s_sink = ft_strlcat (buf, NULL, 10); +} +static void +_s_crash_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]; + + _s_section ("ft_strlcpy"); + + /* NULL */ + _s_check_both_crash ("strlcpy NULL dst", _s_crash_ft_strlcpy_null_dst, + _s_crash_libc_strlcpy_null_dst); + _s_check_both_crash ("strlcpy NULL src", _s_crash_ft_strlcpy_null_src, + _s_crash_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 */ + for (i = 0; i < _S_RAND_ITERS; 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]; + + _s_section ("ft_strlcat"); + + /* NULL */ + _s_check_both_crash ("strlcat NULL dst", _s_crash_ft_strlcat_null_dst, + _s_crash_libc_strlcat_null_dst); + _s_check_both_crash ("strlcat NULL src", _s_crash_ft_strlcat_null_src, + _s_crash_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 < _S_RAND_ITERS; 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) +{ + srand (time (NULL)); + _s_test_strlcpy (); + _s_test_strlcat (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_strlen.c b/tests/src/test_strlen.c new file mode 100644 index 0000000..15f317b --- /dev/null +++ b/tests/src/test_strlen.c @@ -0,0 +1,76 @@ +#include "libft.h" +#include "test_utils.h" + +_S_CRASH (ft_strlen_null, ft_strlen (NULL)) +_S_CRASH (strlen_null, strlen (NULL)) + +static void +_s_test_empty (void) +{ + _s_check_eq ("ft_strlen", ft_strlen (""), 0); + _s_check_eq ("libc strlen", strlen (""), 0); +} + +static void +_s_test_null (void) +{ + _s_check_both_crash ("strlen NULL", _s_crash_ft_strlen_null, + _s_crash_strlen_null); +} + +static void +_s_test_random (int n) +{ + int i; + int len; + char *buf; + char label[64]; + + for (i = 0; i < n; i++) + { + len = rand () % 10000; + buf = malloc (len + 1); + if (!buf) + { + _s_check ("malloc", 0); + return; + } + memset (buf, 'A' + (i % 26), len); + buf[len] = '\0'; + snprintf (label, sizeof (label), "random len=%d", len); + _s_check_eq (label, ft_strlen (buf), strlen (buf)); + free (buf); + } +} + +static void +_s_test_large (void) +{ + size_t len; + char *buf; + + len = 100 * 1024 * 1024; + buf = malloc (len + 1); + if (!buf) + { + printf (" SKIP could not allocate %zu bytes\n", len); + return; + } + memset (buf, 'X', len); + buf[len] = '\0'; + _s_check_eq ("100 MB string", ft_strlen (buf), len); + free (buf); +} + +int +main (void) +{ + srand (time (NULL)); + _s_section ("ft_strlen"); + _s_test_empty (); + _s_test_null (); + _s_test_random (100); + _s_test_large (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/test_alloc.c b/tests/test_alloc.c deleted file mode 100644 index 191fbbb..0000000 --- a/tests/test_alloc.c +++ /dev/null @@ -1,159 +0,0 @@ -#include "../libft.h" -#include "test_utils.h" - -static void -_s_ft_strdup_null (void) -{ - _s_sink = (size_t)ft_strdup (NULL); -} -static void -_s_libc_strdup_null (void) -{ - _s_sink = (size_t)strdup (NULL); -} - -/* ====================================== - * calloc - * ====================================== */ - -static void -_s_test_calloc (void) -{ - int i; - char label[64]; - - printf ("-- calloc --\n"); - - /* zeroed memory */ - { - char *ft_p = ft_calloc (100, 1); - char *libc_p = calloc (100, 1); - _s_check ("zeroed", ft_p && libc_p && memcmp (ft_p, libc_p, 100) == 0); - free (ft_p); - free (libc_p); - } - - /* nmemb=0 */ - { - void *p = ft_calloc (0, 10); - _s_check ("nmemb=0 not NULL", p != NULL); - free (p); - } - - /* size=0 */ - { - void *p = ft_calloc (10, 0); - _s_check ("size=0 not NULL", p != NULL); - free (p); - } - - /* overflow protection */ - { - void *p = ft_calloc ((size_t)-1, 2); - _s_check ("overflow returns NULL", p == NULL); - } - - /* single byte */ - { - unsigned char *p = ft_calloc (1, 1); - _s_check ("single byte zeroed", p && *p == 0); - free (p); - } - - /* randomized: check all bytes are zero */ - srand (time (NULL)); - for (i = 0; i < 50; i++) - { - size_t nmemb = rand () % 500 + 1; - size_t size = rand () % 50 + 1; - unsigned char *ft_p = ft_calloc (nmemb, size); - unsigned char *libc_p = calloc (nmemb, size); - int ok = 1; - size_t j; - if (!ft_p || !libc_p) - { - ok = 0; - } - else - { - for (j = 0; j < nmemb * size; j++) - { - if (ft_p[j] != 0) - { - ok = 0; - break; - } - } - } - snprintf (label, sizeof (label), "random nmemb=%zu size=%zu", nmemb, - size); - _s_check (label, ok); - free (ft_p); - free (libc_p); - } -} - -/* ====================================== - * strdup - * ====================================== */ - -static void -_s_test_strdup (void) -{ - int i; - char label[64]; - - printf ("-- strdup --\n"); - - /* NULL */ - _s_check_both_crash ("strdup NULL", _s_ft_strdup_null, _s_libc_strdup_null); - - /* empty string */ - { - char *p = ft_strdup (""); - _s_check ("empty", p && strcmp (p, "") == 0); - free (p); - } - - /* returns independent copy */ - { - char src[] = "hello"; - char *p = ft_strdup (src); - _s_check ("independent copy", p && p != src && strcmp (p, src) == 0); - src[0] = 'X'; - _s_check ("mutation safe", p[0] == 'h'); - free (p); - } - - /* randomized */ - for (i = 0; i < 50; i++) - { - int len = rand () % 500 + 1; - char *src = malloc (len + 1); - int j; - char *ft_p; - char *libc_p; - if (!src) - continue; - for (j = 0; j < len; j++) - src[j] = 'A' + rand () % 26; - src[len] = '\0'; - ft_p = ft_strdup (src); - libc_p = strdup (src); - snprintf (label, sizeof (label), "random len=%d", len); - _s_check (label, ft_p && libc_p && strcmp (ft_p, libc_p) == 0); - free (src); - free (ft_p); - free (libc_p); - } -} - -int -main (void) -{ - printf ("=== alloc functions ===\n"); - _s_test_calloc (); - _s_test_strdup (); - _s_print_results (); - return (_s_fail != 0); -} diff --git a/tests/test_atoi.c b/tests/test_atoi.c deleted file mode 100644 index 196a081..0000000 --- a/tests/test_atoi.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../libft.h" -#include "test_utils.h" -#include - -static void -_s_ft_atoi_null (void) -{ - _s_sink_i = ft_atoi (NULL); -} -static void -_s_libc_atoi_null (void) -{ - _s_sink_i = atoi (NULL); -} - -int -main (void) -{ - int i; - char buf[64]; - char label[64]; - - printf ("=== ft_atoi ===\n"); - - /* NULL */ - _s_check_both_crash ("atoi NULL", _s_ft_atoi_null, _s_libc_atoi_null); - - /* edge cases */ - _s_check_eq_int ("zero", ft_atoi ("0"), atoi ("0")); - _s_check_eq_int ("INT_MAX", ft_atoi ("2147483647"), atoi ("2147483647")); - _s_check_eq_int ("INT_MIN", ft_atoi ("-2147483648"), atoi ("-2147483648")); - _s_check_eq_int ("negative", ft_atoi ("-42"), atoi ("-42")); - _s_check_eq_int ("explicit +", ft_atoi ("+42"), atoi ("+42")); - _s_check_eq_int ("leading spaces", ft_atoi (" 42"), atoi (" 42")); - _s_check_eq_int ("leading tabs", ft_atoi ("\t\n\v\f\r 42"), - atoi ("\t\n\v\f\r 42")); - _s_check_eq_int ("trailing chars", ft_atoi ("42abc"), atoi ("42abc")); - _s_check_eq_int ("empty string", ft_atoi (""), atoi ("")); - _s_check_eq_int ("only spaces", ft_atoi (" "), atoi (" ")); - _s_check_eq_int ("only sign", ft_atoi ("-"), atoi ("-")); - _s_check_eq_int ("sign then space", ft_atoi ("- 42"), atoi ("- 42")); - _s_check_eq_int ("double sign", ft_atoi ("--42"), atoi ("--42")); - _s_check_eq_int ("space between", ft_atoi ("4 2"), atoi ("4 2")); - _s_check_eq_int ("leading zeros", ft_atoi ("00042"), atoi ("00042")); - - /* randomized */ - srand (time (NULL)); - for (i = 0; i < 50; i++) - { - int v = rand () - RAND_MAX / 2; - snprintf (buf, sizeof (buf), "%d", v); - snprintf (label, sizeof (label), "random %s", buf); - _s_check_eq_int (label, ft_atoi (buf), atoi (buf)); - } - - _s_print_results (); - return (_s_fail != 0); -} diff --git a/tests/test_case.c b/tests/test_case.c deleted file mode 100644 index 44b567a..0000000 --- a/tests/test_case.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "../libft.h" -#include "test_utils.h" -#include - -static void -_s_test_func (const char *name, int (*ft) (int), int (*libc) (int)) -{ - int i; - int ok; - - ok = 1; - for (i = -1; i <= 255; i++) - { - if (ft (i) != libc (i)) - { - printf (" FAIL %s(%d): ft=%d libc=%d\n", name, i, ft (i), libc (i)); - _s_fail++; - ok = 0; - } - } - if (ok) - { - printf (" PASS %s (all -1..255)\n", name); - _s_pass++; - } -} - -int -main (void) -{ - printf ("=== case functions ===\n"); - _s_test_func ("ft_toupper", ft_toupper, toupper); - _s_test_func ("ft_tolower", ft_tolower, tolower); - _s_print_results (); - return (_s_fail != 0); -} diff --git a/tests/test_cmp.c b/tests/test_cmp.c deleted file mode 100644 index eea0aea..0000000 --- a/tests/test_cmp.c +++ /dev/null @@ -1,279 +0,0 @@ -#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); -} diff --git a/tests/test_is.c b/tests/test_is.c deleted file mode 100644 index 1af5d40..0000000 --- a/tests/test_is.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "../libft.h" -#include "test_utils.h" -#include - -static void -_s_test_func (const char *name, int (*ft) (int), int (*libc) (int)) -{ - int i; - int ft_r; - int libc_r; - int ok; - - ok = 1; - for (i = -1; i <= 255; i++) - { - ft_r = !!ft (i); - libc_r = !!libc (i); - if (ft_r != libc_r) - { - printf (" FAIL %s(%d): ft=%d libc=%d\n", name, i, ft_r, libc_r); - _s_fail++; - ok = 0; - } - } - if (ok) - { - printf (" PASS %s (all -1..255)\n", name); - _s_pass++; - } -} - -int -main (void) -{ - printf ("=== is* functions ===\n"); - _s_test_func ("ft_isalpha", ft_isalpha, isalpha); - _s_test_func ("ft_isdigit", ft_isdigit, isdigit); - _s_test_func ("ft_isalnum", ft_isalnum, isalnum); - _s_test_func ("ft_isascii", ft_isascii, isascii); - _s_test_func ("ft_isprint", ft_isprint, isprint); - _s_print_results (); - return (_s_fail != 0); -} diff --git a/tests/test_mem.c b/tests/test_mem.c deleted file mode 100644 index adbe12d..0000000 --- a/tests/test_mem.c +++ /dev/null @@ -1,296 +0,0 @@ -#include "../libft.h" -#include "test_utils.h" -#include - -static void -_s_ft_memset_null (void) -{ - _s_sink = (size_t)ft_memset (NULL, 'A', 10); -} -static void -_s_libc_memset_null (void) -{ - _s_sink = (size_t)memset (NULL, 'A', 10); -} -static void -_s_ft_bzero_null (void) -{ - ft_bzero (NULL, 10); -} -static void -_s_libc_bzero_null (void) -{ - bzero (NULL, 10); -} -static void -_s_ft_memcpy_null_dst (void) -{ - char buf[10]; - _s_sink = (size_t)ft_memcpy (NULL, buf, 10); -} -static void -_s_libc_memcpy_null_dst (void) -{ - char buf[10]; - _s_sink = (size_t)memcpy (NULL, buf, 10); -} -static void -_s_ft_memcpy_null_src (void) -{ - char buf[10]; - _s_sink = (size_t)ft_memcpy (buf, NULL, 10); -} -static void -_s_libc_memcpy_null_src (void) -{ - char buf[10]; - _s_sink = (size_t)memcpy (buf, NULL, 10); -} -static void -_s_ft_memmove_null_dst (void) -{ - char buf[10]; - _s_sink = (size_t)ft_memmove (NULL, buf, 10); -} -static void -_s_libc_memmove_null_dst (void) -{ - char buf[10]; - _s_sink = (size_t)memmove (NULL, buf, 10); -} -static void -_s_ft_memmove_null_src (void) -{ - char buf[10]; - _s_sink = (size_t)ft_memmove (buf, NULL, 10); -} -static void -_s_libc_memmove_null_src (void) -{ - char buf[10]; - _s_sink = (size_t)memmove (buf, NULL, 10); -} - -/* ====================================== - * memset - * ====================================== */ - -static void -_s_test_memset (void) -{ - char ft_buf[256]; - char libc_buf[256]; - int i; - int c; - size_t len; - void *ret; - char label[64]; - - printf ("-- memset --\n"); - - /* NULL */ - _s_check_both_crash ("memset NULL", _s_ft_memset_null, _s_libc_memset_null); - - /* zero length */ - memset (ft_buf, 'X', 256); - memset (libc_buf, 'X', 256); - ft_memset (ft_buf, 'A', 0); - memset (libc_buf, 'A', 0); - _s_check ("n=0", memcmp (ft_buf, libc_buf, 256) == 0); - - /* return value */ - ret = ft_memset (ft_buf, 'B', 10); - _s_check ("return value", ret == ft_buf); - - /* randomized */ - srand (time (NULL)); - for (i = 0; i < 50; i++) - { - c = rand () % 256; - len = rand () % 256; - ft_memset (ft_buf, c, len); - memset (libc_buf, c, len); - snprintf (label, sizeof (label), "random c=%d len=%zu", c, len); - _s_check (label, memcmp (ft_buf, libc_buf, len) == 0); - } -} - -/* ====================================== - * bzero - * ====================================== */ - -static void -_s_test_bzero (void) -{ - char ft_buf[256]; - char libc_buf[256]; - int i; - size_t len; - char label[64]; - - printf ("-- bzero --\n"); - - /* NULL */ - _s_check_both_crash ("bzero NULL", _s_ft_bzero_null, _s_libc_bzero_null); - - /* zero length */ - memset (ft_buf, 'X', 256); - memset (libc_buf, 'X', 256); - ft_bzero (ft_buf, 0); - bzero (libc_buf, 0); - _s_check ("n=0", memcmp (ft_buf, libc_buf, 256) == 0); - - /* full clear */ - memset (ft_buf, 'X', 256); - memset (libc_buf, 'X', 256); - ft_bzero (ft_buf, 256); - bzero (libc_buf, 256); - _s_check ("n=256", memcmp (ft_buf, libc_buf, 256) == 0); - - /* randomized */ - for (i = 0; i < 50; i++) - { - len = rand () % 256; - memset (ft_buf, 'Z', 256); - memset (libc_buf, 'Z', 256); - ft_bzero (ft_buf, len); - bzero (libc_buf, len); - snprintf (label, sizeof (label), "random len=%zu", len); - _s_check (label, memcmp (ft_buf, libc_buf, 256) == 0); - } -} - -/* ====================================== - * memcpy - * ====================================== */ - -static void -_s_test_memcpy (void) -{ - char src[256]; - char ft_dst[256]; - char libc_dst[256]; - int i; - size_t len; - void *ret; - char label[64]; - - printf ("-- memcpy --\n"); - - /* NULL */ - _s_check_both_crash ("memcpy NULL dst", _s_ft_memcpy_null_dst, - _s_libc_memcpy_null_dst); - _s_check_both_crash ("memcpy NULL src", _s_ft_memcpy_null_src, - _s_libc_memcpy_null_src); - - /* fill source with pattern */ - for (i = 0; i < 256; i++) - src[i] = i; - - /* zero length */ - memset (ft_dst, 'X', 256); - memset (libc_dst, 'X', 256); - ft_memcpy (ft_dst, src, 0); - memcpy (libc_dst, src, 0); - _s_check ("n=0", memcmp (ft_dst, libc_dst, 256) == 0); - - /* return value */ - ret = ft_memcpy (ft_dst, src, 10); - _s_check ("return value", ret == ft_dst); - - /* NULL src and dst with n=0 */ - ret = ft_memcpy (NULL, NULL, 0); - _s_check ("NULL,NULL,0", ret == NULL); - - /* randomized */ - for (i = 0; i < 50; i++) - { - len = rand () % 256; - memset (ft_dst, 0, 256); - memset (libc_dst, 0, 256); - ft_memcpy (ft_dst, src, len); - memcpy (libc_dst, src, len); - snprintf (label, sizeof (label), "random len=%zu", len); - _s_check (label, memcmp (ft_dst, libc_dst, 256) == 0); - } -} - -/* ====================================== - * memmove - * ====================================== */ - -static void -_s_test_memmove (void) -{ - char ft_buf[256]; - char libc_buf[256]; - int i; - size_t len; - size_t offset; - void *ret; - char label[64]; - - printf ("-- memmove --\n"); - - /* NULL */ - _s_check_both_crash ("memmove NULL dst", _s_ft_memmove_null_dst, - _s_libc_memmove_null_dst); - _s_check_both_crash ("memmove NULL src", _s_ft_memmove_null_src, - _s_libc_memmove_null_src); - - /* return value */ - memset (ft_buf, 'A', 256); - ret = ft_memmove (ft_buf, ft_buf + 10, 10); - _s_check ("return value", ret == ft_buf); - - /* NULL src and dst with n=0 */ - ret = ft_memmove (NULL, NULL, 0); - _s_check ("NULL,NULL,0", ret == NULL); - - /* forward overlap: src before dest */ - for (i = 0; i < 256; i++) - ft_buf[i] = libc_buf[i] = i; - ft_memmove (ft_buf + 10, ft_buf, 100); - memmove (libc_buf + 10, libc_buf, 100); - _s_check ("forward overlap", memcmp (ft_buf, libc_buf, 256) == 0); - - /* backward overlap: dest before src */ - for (i = 0; i < 256; i++) - ft_buf[i] = libc_buf[i] = i; - ft_memmove (ft_buf, ft_buf + 10, 100); - memmove (libc_buf, libc_buf + 10, 100); - _s_check ("backward overlap", memcmp (ft_buf, libc_buf, 256) == 0); - - /* non-overlapping */ - for (i = 0; i < 256; i++) - ft_buf[i] = libc_buf[i] = i; - ft_memmove (ft_buf + 128, ft_buf, 50); - memmove (libc_buf + 128, libc_buf, 50); - _s_check ("non-overlapping", memcmp (ft_buf, libc_buf, 256) == 0); - - /* randomized overlapping copies */ - for (i = 0; i < 50; i++) - { - for (int j = 0; j < 256; j++) - ft_buf[j] = libc_buf[j] = rand () % 256; - len = rand () % 128 + 1; - offset = rand () % 128; - ft_memmove (ft_buf + offset, ft_buf, len); - memmove (libc_buf + offset, libc_buf, len); - snprintf (label, sizeof (label), "random overlap len=%zu off=%zu", len, - offset); - _s_check (label, memcmp (ft_buf, libc_buf, 256) == 0); - } -} - -int -main (void) -{ - printf ("=== mem functions ===\n"); - _s_test_memset (); - _s_test_bzero (); - _s_test_memcpy (); - _s_test_memmove (); - _s_print_results (); - return (_s_fail != 0); -} diff --git a/tests/test_search.c b/tests/test_search.c deleted file mode 100644 index faaaccd..0000000 --- a/tests/test_search.c +++ /dev/null @@ -1,285 +0,0 @@ -#include "../libft.h" -#include "test_utils.h" -#include - -static void -_s_ft_strchr_null (void) -{ - _s_sink = (size_t)ft_strchr (NULL, 'a'); -} -static void -_s_libc_strchr_null (void) -{ - _s_sink = (size_t)strchr (NULL, 'a'); -} -static void -_s_ft_strrchr_null (void) -{ - _s_sink = (size_t)ft_strrchr (NULL, 'a'); -} -static void -_s_libc_strrchr_null (void) -{ - _s_sink = (size_t)strrchr (NULL, 'a'); -} -static void -_s_ft_strnstr_null_big (void) -{ - _s_sink = (size_t)ft_strnstr (NULL, "abc", 10); -} -static void -_s_libc_strnstr_null_big (void) -{ - _s_sink = (size_t)strnstr (NULL, "abc", 10); -} -static void -_s_ft_strnstr_null_little (void) -{ - _s_sink = (size_t)ft_strnstr ("abc", NULL, 10); -} -static void -_s_libc_strnstr_null_little (void) -{ - _s_sink = (size_t)strnstr ("abc", NULL, 10); -} - -/* ====================================== - * strchr - * ====================================== */ - -static void -_s_test_strchr (void) -{ - char buf[] = "hello world"; - int i; - char label[64]; - - printf ("-- strchr --\n"); - - /* NULL */ - _s_check_both_crash ("strchr NULL", _s_ft_strchr_null, _s_libc_strchr_null); - - /* find first occurrence */ - _s_check ("find 'l'", ft_strchr (buf, 'l') == strchr (buf, 'l')); - - /* find first char */ - _s_check ("find 'h'", ft_strchr (buf, 'h') == strchr (buf, 'h')); - - /* find last char */ - _s_check ("find 'd'", ft_strchr (buf, 'd') == strchr (buf, 'd')); - - /* not found */ - _s_check ("not found 'z'", ft_strchr (buf, 'z') == strchr (buf, 'z')); - - /* find null terminator */ - _s_check ("find '\\0'", ft_strchr (buf, '\0') == strchr (buf, '\0')); - - /* empty string */ - _s_check ("empty + 'a'", ft_strchr ("", 'a') == strchr ("", 'a')); - _s_check ("empty + '\\0'", ft_strchr ("", '\0') == strchr ("", '\0')); - - /* int truncation to char */ - _s_check ("int truncation", - ft_strchr (buf, 'h' + 256) == strchr (buf, 'h' + 256)); - - /* all printable ASCII */ - for (i = 32; i < 127; i++) - { - snprintf (label, sizeof (label), "char %d in buf", i); - _s_check (label, ft_strchr (buf, i) == strchr (buf, i)); - } - - /* randomized */ - srand (time (NULL)); - for (i = 0; i < 50; i++) - { - char rnd[128]; - int len = rand () % 127 + 1; - int j; - int c; - for (j = 0; j < len; j++) - rnd[j] = 'A' + rand () % 52; - rnd[len] = '\0'; - c = 'A' + rand () % 52; - snprintf (label, sizeof (label), "random len=%d c=%c", len, c); - _s_check (label, ft_strchr (rnd, c) == strchr (rnd, c)); - } -} - -/* ====================================== - * strrchr - * ====================================== */ - -static void -_s_test_strrchr (void) -{ - char buf[] = "hello world"; - int i; - char label[64]; - - printf ("-- strrchr --\n"); - - /* NULL */ - _s_check_both_crash ("strrchr NULL", _s_ft_strrchr_null, - _s_libc_strrchr_null); - - /* find last occurrence */ - _s_check ("find 'l'", ft_strrchr (buf, 'l') == strrchr (buf, 'l')); - - /* only one occurrence */ - _s_check ("find 'w'", ft_strrchr (buf, 'w') == strrchr (buf, 'w')); - - /* find first char */ - _s_check ("find 'h'", ft_strrchr (buf, 'h') == strrchr (buf, 'h')); - - /* find last char */ - _s_check ("find 'd'", ft_strrchr (buf, 'd') == strrchr (buf, 'd')); - - /* not found */ - _s_check ("not found 'z'", ft_strrchr (buf, 'z') == strrchr (buf, 'z')); - - /* find null terminator */ - _s_check ("find '\\0'", ft_strrchr (buf, '\0') == strrchr (buf, '\0')); - - /* empty string */ - _s_check ("empty + 'a'", ft_strrchr ("", 'a') == strrchr ("", 'a')); - _s_check ("empty + '\\0'", ft_strrchr ("", '\0') == strrchr ("", '\0')); - - /* int truncation to char */ - _s_check ("int truncation", - ft_strrchr (buf, 'l' + 256) == strrchr (buf, 'l' + 256)); - - /* multiple occurrences */ - _s_check ("'o' last", - ft_strrchr ("foo bar boo", 'o') == strrchr ("foo bar boo", 'o')); - - /* all printable ASCII */ - for (i = 32; i < 127; i++) - { - snprintf (label, sizeof (label), "char %d in buf", i); - _s_check (label, ft_strrchr (buf, i) == strrchr (buf, i)); - } - - /* randomized */ - for (i = 0; i < 50; i++) - { - char rnd[128]; - int len = rand () % 127 + 1; - int j; - int c; - for (j = 0; j < len; j++) - rnd[j] = 'A' + rand () % 52; - rnd[len] = '\0'; - c = 'A' + rand () % 52; - snprintf (label, sizeof (label), "random len=%d c=%c", len, c); - _s_check (label, ft_strrchr (rnd, c) == strrchr (rnd, c)); - } -} - -/* ====================================== - * strnstr - * ====================================== */ - -static void -_s_test_strnstr (void) -{ - char hay[] = "hello world, hello earth"; - - printf ("-- strnstr --\n"); - - /* NULL */ - _s_check_both_crash ("strnstr NULL big", _s_ft_strnstr_null_big, - _s_libc_strnstr_null_big); - _s_check_both_crash ("strnstr NULL little", _s_ft_strnstr_null_little, - _s_libc_strnstr_null_little); - - /* empty needle */ - _s_check ("empty needle", ft_strnstr (hay, "", 24) == strnstr (hay, "", 24)); - - /* empty haystack */ - _s_check ("empty haystack", - ft_strnstr ("", "abc", 0) == strnstr ("", "abc", 0)); - _s_check ("both empty", ft_strnstr ("", "", 0) == strnstr ("", "", 0)); - - /* basic find */ - _s_check ("find 'world'", - ft_strnstr (hay, "world", 24) == strnstr (hay, "world", 24)); - - /* find at start */ - _s_check ("find 'hello'", - ft_strnstr (hay, "hello", 24) == strnstr (hay, "hello", 24)); - - /* find at end */ - _s_check ("find 'earth'", - ft_strnstr (hay, "earth", 24) == strnstr (hay, "earth", 24)); - - /* not found */ - _s_check ("not found 'xyz'", - ft_strnstr (hay, "xyz", 24) == strnstr (hay, "xyz", 24)); - - /* needle longer than len */ - _s_check ("needle beyond len", - ft_strnstr (hay, "world", 8) == strnstr (hay, "world", 8)); - - /* len=0 */ - _s_check ("len=0", - ft_strnstr (hay, "hello", 0) == strnstr (hay, "hello", 0)); - - /* exact match at boundary */ - _s_check ("exact boundary", - ft_strnstr (hay, "world", 11) == strnstr (hay, "world", 11)); - - /* one short of match */ - _s_check ("one short", - ft_strnstr (hay, "world", 10) == strnstr (hay, "world", 10)); - - /* single char needle */ - _s_check ("single char 'w'", - ft_strnstr (hay, "w", 24) == strnstr (hay, "w", 24)); - - /* needle same as haystack */ - _s_check ("needle == haystack", - ft_strnstr ("abc", "abc", 3) == strnstr ("abc", "abc", 3)); - - /* needle longer than haystack */ - _s_check ("needle > haystack", - ft_strnstr ("ab", "abc", 3) == strnstr ("ab", "abc", 3)); - - /* partial match then fail */ - _s_check ("partial match", - ft_strnstr ("aab", "ab", 3) == strnstr ("aab", "ab", 3)); - - /* randomized */ - for (int i = 0; i < 50; i++) - { - char rbig[128]; - char rlittle[16]; - int blen = rand () % 100 + 20; - int llen = rand () % 10 + 1; - size_t n; - int j; - char label[64]; - for (j = 0; j < blen; j++) - rbig[j] = 'A' + rand () % 4; - rbig[blen] = '\0'; - for (j = 0; j < llen; j++) - rlittle[j] = 'A' + rand () % 4; - rlittle[llen] = '\0'; - n = rand () % (blen + 10); - snprintf (label, sizeof (label), "random blen=%d llen=%d n=%zu", blen, - llen, n); - _s_check (label, - ft_strnstr (rbig, rlittle, n) == strnstr (rbig, rlittle, n)); - } -} - -int -main (void) -{ - printf ("=== search functions ===\n"); - _s_test_strchr (); - _s_test_strrchr (); - _s_test_strnstr (); - _s_print_results (); - return (_s_fail != 0); -} diff --git a/tests/test_strl.c b/tests/test_strl.c deleted file mode 100644 index 1ef29af..0000000 --- a/tests/test_strl.c +++ /dev/null @@ -1,252 +0,0 @@ -#include "../libft.h" -#include "test_utils.h" -#include - -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); -} diff --git a/tests/test_strlen.c b/tests/test_strlen.c deleted file mode 100644 index ef569ff..0000000 --- a/tests/test_strlen.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "../libft.h" -#include "test_utils.h" - -static void -_s_call_ft_strlen_null (void) -{ - _s_sink = ft_strlen (NULL); -} - -static void -_s_call_strlen_null (void) -{ - _s_sink = strlen (NULL); -} - -static void -_s_test_empty (void) -{ - printf ("-- empty string --\n"); - _s_check_eq ("ft_strlen", ft_strlen (""), 0); - _s_check_eq ("libc strlen", strlen (""), 0); -} - -static void -_s_test_null (void) -{ - int ft_crashed; - int libc_crashed; - - printf ("-- NULL --\n"); - ft_crashed = _s_crashes (_s_call_ft_strlen_null); - libc_crashed = _s_crashes (_s_call_strlen_null); - if (ft_crashed && libc_crashed) - { - printf (" PASS both crash on NULL\n"); - _s_pass++; - } - else if (ft_crashed == libc_crashed) - { - printf (" PASS both behave the same on NULL (no crash)\n"); - _s_pass++; - } - else - { - printf (" FAIL ft_crashed=%d libc_crashed=%d\n", ft_crashed, - libc_crashed); - _s_fail++; - } -} - -static void -_s_test_random (int n) -{ - int i; - int len; - char *buf; - char label[64]; - - printf ("-- %d randomized tests --\n", n); - for (i = 0; i < n; i++) - { - len = rand () % 10000; - buf = malloc (len + 1); - if (!buf) - { - printf (" FAIL malloc\n"); - _s_fail++; - return; - } - memset (buf, 'A' + (i % 26), len); - buf[len] = '\0'; - snprintf (label, sizeof (label), "random len=%d", len); - _s_check_eq (label, ft_strlen (buf), strlen (buf)); - free (buf); - } -} - -static void -_s_test_large (void) -{ - size_t len; - char *buf; - - printf ("-- large string (100 MB) --\n"); - len = 100 * 1024 * 1024; - buf = malloc (len + 1); - if (!buf) - { - printf (" SKIP could not allocate %zu bytes\n", len); - return; - } - memset (buf, 'X', len); - buf[len] = '\0'; - _s_check_eq ("100 MB string", ft_strlen (buf), len); - free (buf); -} - -int -main (void) -{ - srand (time (NULL)); - printf ("=== ft_strlen ===\n"); - _s_test_empty (); - _s_test_null (); - _s_test_random (100); - _s_test_large (); - _s_print_results (); - return (_s_fail != 0); -} -- cgit v1.2.3