commit 42653de246947fe3d5426194d24e7b3257ede6d0 Author: Thomas Rieg Date: Fri Nov 28 19:50:58 2025 +0100 copy on git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..71e4056 --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +CC := cc +CFLAGS := -Wall -Wextra -Werror -fPIC -Iincludes -Ilibft + +ifeq ($(HOSTTYPE),) +HOSTTYPE := $(shell uname -m)_$(shell uname -s) +endif + +NAME := libft_malloc_$(HOSTTYPE).so +LINK := libft_malloc.so + +# --------------------------------------------------------------------------- # +# Sources / objects +# --------------------------------------------------------------------------- # + +SRCS_DIR := srcs +SRCS := $(SRCS_DIR)/ft_malloc.c \ + $(SRCS_DIR)/ft_free.c \ + $(SRCS_DIR)/ft_calloc.c \ + $(SRCS_DIR)/ft_realloc.c \ + $(SRCS_DIR)/init_state.c \ + $(SRCS_DIR)/bonus_utils.c + +OBJS := $(SRCS:.c=.o) + +LIBFT_DIR := libft +LIBFT_A := $(LIBFT_DIR)/libft.a + +# --------------------------------------------------------------------------- # +# Rules +# --------------------------------------------------------------------------- # + +.PHONY: all clean fclean re test + +all: $(NAME) $(LINK) + +# Build the shared library +$(NAME): $(LIBFT_A) $(OBJS) + $(CC) -shared -o $@ $(OBJS) -L$(LIBFT_DIR) -lft -lpthread + +# Symlink libft_malloc.so -> libft_malloc_$HOSTTYPE.so +$(LINK): $(NAME) + ln -sf $(NAME) $(LINK) + +# Build libft first (using its own Makefile) +$(LIBFT_A): + $(MAKE) -C $(LIBFT_DIR) + +# Object files +$(SRCS_DIR)/%.o: $(SRCS_DIR)/%.c + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJS) + $(MAKE) -C $(LIBFT_DIR) clean + +fclean: clean + rm -f $(NAME) $(LINK) + $(MAKE) -C $(LIBFT_DIR) fclean + +re: fclean all + +# Simple helper target to remind how to test with LD_PRELOAD +test: all + @echo "Library built:" + @echo " $(NAME)" + @echo "Symlink:" + @echo " $(LINK) -> $(NAME)" + @echo "" + @echo "Example usage (run any program with your malloc):" + @echo " LD_PRELOAD=./$(LINK) ls" \ No newline at end of file diff --git a/a.out b/a.out new file mode 100755 index 0000000..2ba7b95 Binary files /dev/null and b/a.out differ diff --git a/includes/ft_malloc.h b/includes/ft_malloc.h new file mode 100644 index 0000000..4a756ea --- /dev/null +++ b/includes/ft_malloc.h @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_malloc.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/17 15:06:51 by thrieg #+# #+# */ +/* Updated: 2025/11/28 17:24:33 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_MALLOC_H +#define FT_MALLOC_H + +#include +#include +#include +#include +#include +#include +#include +#include "../libft/ft_hashmap.h" +#include "../libft/ft_vector.h" +#include "ft_malloc_public.h" + +#define TINY_SIZE_MAX 64 +#define SMALL_SIZE_MAX 4096 +#define ALLIGN_BYTES _Alignof(max_align_t) + +typedef enum e_type +{ + E_TINY, + E_SMALL, + E_LARGE +} t_type; + +typedef struct s_zone +{ + t_type type; + size_t size; + struct s_zone *next; // lock g_mut + struct s_zone *prev; // lock g_mut +} t_zone; + +typedef struct s_header +{ + size_t size; // lock zone_mut + bool occupied; // lock zone_mut + t_zone *zone; + char padding[8]; +} t_header; + +typedef struct s_state +{ + t_zone *tiny_zone; // lock g_mut + t_zone *small_zone; // lock g_mut + t_zone *large_zone; // lock g_mut, 1 zone per alloc for large +} t_state; + +extern t_state g_state; +extern pthread_mutex_t g_mut; // never lock this inside a zone mut, only the opposite + +void *add_large(size_t size); +void *add_small(size_t size); +void *add_tiny(size_t size); +void *add_page(t_type type); + +#endif \ No newline at end of file diff --git a/includes/ft_malloc_public.h b/includes/ft_malloc_public.h new file mode 100644 index 0000000..b82a6eb --- /dev/null +++ b/includes/ft_malloc_public.h @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_malloc_public.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/25 12:31:43 by thrieg #+# #+# */ +/* Updated: 2025/11/28 18:26:47 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_MALLOC_PUBLIC_H +#define FT_MALLOC_PUBLIC_H + +#include +#include + +void *malloc(size_t size); +void free(void *ptr); +void *calloc(size_t nmemb, size_t size); +void *realloc(void *ptr, size_t size); +void show_alloc_mem_ex(bool hexdump_free_zones); + +#endif \ No newline at end of file diff --git a/libft/Makefile b/libft/Makefile new file mode 100755 index 0000000..d19126e --- /dev/null +++ b/libft/Makefile @@ -0,0 +1,79 @@ +CC = cc + +CFLAGS = -Wall -Wextra -Werror -O3 -g3 -fPIC + +SRCS = ./ft_isalnum.c ./ft_isalpha.c ./ft_isascii.c ./ft_isdigit.c \ + ./ft_isprint.c ./ft_memset.c ./ft_strlen.c ./ft_bzero.c ./ft_memcpy.c \ + ./ft_memmove.c ./ft_strlcpy.c ./ft_strlcat.c ./ft_toupper.c \ + ./ft_tolower.c ./ft_strchr.c ./ft_strrchr.c ./ft_strncmp.c \ + ./ft_memchr.c ./ft_memcmp.c ./ft_strnstr.c ./ft_atoi.c \ + ./ft_strdup.c ./ft_calloc.c ./ft_substr.c ./ft_strjoin.c \ + ./ft_strtrim.c ./ft_split.c ./ft_itoa.c ./ft_strmapi.c \ + ./ft_striteri.c ./ft_putchar_fd.c ./ft_putstr_fd.c \ + ./ft_putendl_fd.c ./ft_putnbr_fd.c ./ft_int_utils.c \ + ./ft_safe_int_math.c ./ft_split2.c ./ft_long_utils.c \ + ./ft_safe_long_math.c + +SRCSBONUS = ./ft_lstnew_bonus.c ./ft_lstadd_front_bonus.c ./ft_lstsize_bonus.c ./ft_lstlast_bonus.c ./ft_lstadd_back_bonus.c ./ft_lstdelone_bonus.c ./ft_lstclear_bonus.c ./ft_lstiter_bonus.c ./ft_lstmap_bonus.c ./ft_vector.c ./ft_itoa_base.c ./ft_addr_to_str.c ./ft_utoa.c ./ft_strnonchr.c ./ft_utoa_base.c ./ft_strcmp.c ./ft_vecint.c ./ft_power.c + +SRCS_GNL = ./get_next_line/get_next_line.c ./get_next_line/get_next_line_utils.c ./get_next_line/get_next_line_utils_two.c + +FT_PRINTF_PATH = ./ft_printf/ +SRC_PRINTF = ft_printf.c ft_cases_mandatory_one.c ft_cases_mandatory_two.c ft_printf_bonus.c ft_cases_easy_bonus.c ft_case_lowx_bonus.c ft_case_uppx_bonus.c ft_case_u_bonus.c ft_case_s_bonus.c ft_case_p_bonus.c ft_case_d_bonus.c ft_case_d_utils_bonus.c ft_arglist_bonus.c ft_padding_bonus.c +SRCS_PRINTF = $(addprefix $(FT_PRINTF_PATH), $(SRC_PRINTF)) + +FT_HASHMAP_PATH = ./ft_hashmap/ +SRC_HASHMAP = ft_hashmap.c ft_hashmap_utils.c ft_hashmap_utils_two.c ft_hashmap_basic_type_hash.c ft_hashmap_advanced_type_hash.c ft_hashmap_basic_cmp.c +SRCS_HASHMAP = $(addprefix $(FT_HASHMAP_PATH), $(SRC_HASHMAP)) + +FT_PQ_PATH = ./ft_priority_queue/ +SRC_PQ = ft_priority_queue.c ft_priority_queue_utils.c +SRCS_PQ = $(addprefix $(FT_PQ_PATH), $(SRC_PQ)) + +FT_SORTING_PATH = ./sorting/ +SRC_SORTING = ft_radixsort.c ft_sorting.c +SRCS_SORTING = $(addprefix $(FT_SORTING_PATH), $(SRC_SORTING)) + +OBJS = $(SRCS:.c=.o) + +OBJSBONUS = $(SRCSBONUS:.c=.o) + +OBJS_GNL = $(SRCS_GNL:.c=.o) + +OBJS_PRINTF = $(SRCS_PRINTF:.c=.o) + +OBJS_HASHMAP = $(SRCS_HASHMAP:.c=.o) + +OBJS_PQ = $(SRCS_PQ:.c=.o) + +OBJS_SORTING = $(SRCS_SORTING:.c=.o) + +NAME = libft.a + +RED := \033[0;31m +GREEN := \033[0;32m +YELLOW := \033[0;33m +BLUE := \033[0;34m +NC := \033[0m + + +all: $(NAME) + +$(NAME): $(OBJS) $(OBJSBONUS) $(OBJS_GNL) $(OBJS_PRINTF) $(OBJS_HASHMAP) $(OBJS_PQ) $(OBJS_SORTING) + @ar rcs $(NAME) $(OBJS) $(OBJSBONUS) $(OBJS_GNL) $(OBJS_PRINTF) $(OBJS_HASHMAP) $(OBJS_PQ) $(OBJS_SORTING) + @echo "$(GREEN)finished compiling $(NAME)!$(NC)" + +bonus: $(NAME) + +./%.o: ./%.c + @$(CC) $(CFLAGS) -c $< -o $@ + +clean: + @rm -f $(OBJS) $(OBJSBONUS) $(OBJS_GNL) $(OBJS_PRINTF) $(OBJS_HASHMAP) $(OBJS_PQ) $(OBJS_SORTING) + @echo "$(YELLOW)deleted object files from $(NAME)$(NC)" + +fclean: clean + @rm -f $(NAME) + @echo "$(YELLOW)deleted $(NAME)$(NC)" + +re: fclean all diff --git a/libft/ft_addr_to_str.c b/libft/ft_addr_to_str.c new file mode 100755 index 0000000..012271b --- /dev/null +++ b/libft/ft_addr_to_str.c @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_addr_to_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 16:54:09 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:02:50 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include + +void ft_convert_to_hexa(char c, char hex_buff[2]) +{ + hex_buff[1] = c & 0b00001111; + hex_buff[0] = (c >> 4) & 0b00001111; + if (hex_buff[0] <= 9) + hex_buff[0] += '0'; + else + hex_buff[0] += 'a' - 10; + if (hex_buff[1] <= 9) + hex_buff[1] += '0'; + else + hex_buff[1] += 'a' - 10; +} + +//convert the address addr in hexadecimal and returns a standard c string. +//returns NULL if the allocation fails +char *ft_addr_to_strhex(void *addr) +{ + char hex_buff[2]; + int i; + int j; + uintptr_t address; + char *ret; + + ret = malloc((sizeof(char) * sizeof(uintptr_t) * 2) + 1); + if (!ret) + return (NULL); + address = (uintptr_t)addr; + i = (sizeof(uintptr_t) * 8) - 8; + j = 0; + while (i >= 0) + { + ft_convert_to_hexa(((address >> i) & 0xFF), hex_buff); + ret[j++] = hex_buff[0]; + ret[j++] = hex_buff[1]; + i -= 8; + } + ret[j] = '\0'; + return (ret); +} diff --git a/libft/ft_addr_to_str.o b/libft/ft_addr_to_str.o new file mode 100644 index 0000000..171eb3e Binary files /dev/null and b/libft/ft_addr_to_str.o differ diff --git a/libft/ft_atoi.c b/libft/ft_atoi.c new file mode 100755 index 0000000..ed894b7 --- /dev/null +++ b/libft/ft_atoi.c @@ -0,0 +1,71 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_atoi.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 18:37:49 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:02:53 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include + +static int ft_is_space(char c) +{ + if (c == '\t' || c == '\n' || c == '\v' + || c == '\f' || c == '\r' || c == ' ') + return (1); + else + return (0); +} + +static int ft_convert_to_int(const char *str, int sign, int *overflow_flag) +{ + int value; + + value = 0; + while (ft_isdigit(*str)) + { + if (sign == 1) + { + if (value > (INT_MAX - (*str - '0')) / 10) + if (overflow_flag) + *overflow_flag = 1; + value = value * 10 + (*str - '0'); + } + else + { + if (value < (INT_MIN + (*str - '0')) / 10) + if (overflow_flag) + *overflow_flag = 1; + value = value * 10 - (*str - '0'); + } + str++; + } + return (value); +} + +int ft_atoi(const char *nptr, int *overflow_flag) +{ + int sign; + + if (overflow_flag) + *overflow_flag = 0; + while ((*nptr != '\0') && ft_is_space(*nptr)) + { + nptr++; + } + sign = 1; + if ((*nptr != '\0') && (*nptr == '-' || *nptr == '+')) + { + if (*nptr == '-') + sign = -sign; + nptr++; + } + if (!ft_isdigit(*nptr)) + return (0); + return (ft_convert_to_int(nptr, sign, overflow_flag)); +} diff --git a/libft/ft_atoi.o b/libft/ft_atoi.o new file mode 100644 index 0000000..7f2b5fc Binary files /dev/null and b/libft/ft_atoi.o differ diff --git a/libft/ft_bzero.c b/libft/ft_bzero.c new file mode 100755 index 0000000..e1c46d7 --- /dev/null +++ b/libft/ft_bzero.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_bzero.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:50:09 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:30 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_bzero(void *s, size_t n) +{ + ft_memset(s, '\0', n); +} diff --git a/libft/ft_bzero.o b/libft/ft_bzero.o new file mode 100644 index 0000000..f4be140 Binary files /dev/null and b/libft/ft_bzero.o differ diff --git a/libft/ft_calloc.c b/libft/ft_calloc.c new file mode 100755 index 0000000..4fb1e1f --- /dev/null +++ b/libft/ft_calloc.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_calloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 19:42:05 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:37 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_calloc(size_t nmemb, size_t size) +{ + void *ret; + + if ((size == 0) || (nmemb == 0)) + { + return (malloc(0)); + } + if (nmemb > __SIZE_MAX__ / size) + return (NULL); + ret = malloc(nmemb * size); + if (!ret) + return (NULL); + ft_bzero(ret, (nmemb * size)); + return (ret); +} diff --git a/libft/ft_calloc.o b/libft/ft_calloc.o new file mode 100644 index 0000000..8705130 Binary files /dev/null and b/libft/ft_calloc.o differ diff --git a/libft/ft_hashmap.h b/libft/ft_hashmap.h new file mode 100755 index 0000000..900598e --- /dev/null +++ b/libft/ft_hashmap.h @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 12:14:47 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:02 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_HASHMAP_H +# define FT_HASHMAP_H + +# include "libft.h" +# include "ft_vector.h" + +# define HASHMAP_FILL_PERCENT_MAX 200 +# define HASHMAP_RESIZE_FACTOR 2 +# define HASHMAP_MINIMUM_SIZE 16 +# define HASHMAP_FILL_PERCENT_BEFORE_SHRINK 50 +# define HASHMAP_SHRINK_FACTOR 2 + +typedef struct s_hashmap +{ + t_list **table; + size_t hashmap_size; + size_t nb_elems; + void (*free_key)(void *key); + void (*free_value)(void *value); + int (*cmp)(void *key, void *key_to_compare); +} t_hashmap; + +size_t ft_hash_int(int value); +size_t ft_hash_uint(unsigned int value); +size_t ft_hash_char(char value); +size_t ft_hash_string(const char *str); +size_t ft_hash_size_t(size_t value); +size_t ft_hash_address(const void *key); +size_t ft_hash_list(const t_list *list); +size_t ft_hash_hashmap(const t_hashmap *hashmap); +size_t ft_hash_vector(const t_vector *vec); +// Comparison function for integers +int int_cmp(void *key1, void *key2); +// Comparison function for strings +int cmp_str(void *key1, void *key2); +// Comparison function for unsigned chars +int cmp_uchar(void *key1, void *key2); +// Comparison function for unsigned integers +int uint_cmp(void *key1, void *key2); +// Comparison function for size_t +int sizet_cmp(void *key1, void *key2); + +//returns 0 without doing anything if the allocation of the new table fails +//in that case the old table is still valid! +//returns 1 if the resize is a success +int ft_resize_hashmap(t_hashmap *map); + +//returns 0 without doing anything if the allocation of the new table fails +//or if the table is too little in that case the old table is still valid! +//returns 1 if the shrink is a success +int ft_shrink_hashmap(t_hashmap *map); + +//applies functions free_key and free_value on the element if they are not NULL +//returns 1 if the element has been deleted +//returns 0 if the element has not been found +int ft_delete_hashmap_element(t_hashmap *map, void *key, size_t hash); + +//returns a pointer to the value of key, or a NULL pointer if not found +void *ft_lookup_hashmap_element(t_hashmap *map, void *key, size_t hash); + +//frees the entire hashmap and then returns NULL once done +void *ft_free_hashmap(t_hashmap *map); + +// Inserts a key-value pair into the hashmap, +//returns 0 for an error, 1 for remplaced value for a key and 2 for new key +int ft_hashmap_insert_element( + t_hashmap *map, + void *key, + void *value, + size_t hash); + +//allocates an array of initial_size, and sets nb_elems/hashmap_size to 0 +//cmp is a function that returns 0 if both keys are the same +//returns NULL if any allocation fails +t_hashmap *ft_create_hashmap( + size_t initial_size, + void (*free_key)(void *), + void (*free_value)(void *), + int (*cmp)(void *key, void *key_to_compare)); + +#endif diff --git a/libft/ft_hashmap/ft_hashmap.c b/libft/ft_hashmap/ft_hashmap.c new file mode 100755 index 0000000..46d451e --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap.c @@ -0,0 +1,156 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 12:14:50 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:34 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" + +//allocates an array of initial_size, and sets nb_elems/hashmap_size to 0 +//cmp is a function that returns 0 if both keys are the same +//returns NULL if any allocation fails +t_hashmap *ft_create_hashmap( +size_t initial_size, +void (*free_key)(void *), +void (*free_value)(void *), +int (*cmp)(void *key, void *key_to_compare)) +{ + t_hashmap *map; + + if (initial_size == 0) + return (NULL); + map = malloc(sizeof(t_hashmap)); + if (!map) + return (NULL); + map->nb_elems = 0; + map->hashmap_size = initial_size; + map->cmp = cmp; + map->free_key = free_key; + map->free_value = free_value; + map->table = ft_calloc((initial_size), sizeof(t_list *)); + if (!(map->table)) + return (free(map), NULL); + return (map); +} + +// Inserts a key-value pair into the hashmap, +//returns 0 for an error, 1 for remplaced value for a key and 2 for new key +int ft_hashmap_insert_element( +t_hashmap *map, +void *key, +void *value, +size_t hash) +{ + size_t index; + t_list *current; + t_hash_element *element; + + if (!map || !key) + return (0); + if ((map->nb_elems * 100) > map->hashmap_size * HASHMAP_FILL_PERCENT_MAX) + ft_resize_hashmap(map); + index = hash % map->hashmap_size; + current = map->table[index]; + while (current) + { + if (map->cmp(((t_hash_element *)(current->content))->key, key) == 0) + { + map->free_value(((t_hash_element *)(current->content))->value); + return (((t_hash_element *)(current->content))->value = value, 1); + } + current = current->next; + } + element = ft_create_hash_element(key, value, hash); + if (!element) + return (0); + if (!ft_add_hashmap_element(index, map, element)) + return (ft_free_hash_element(element, map), 0); + return (2); +} + +//returns 1 if the element has been deleted +//returns 0 if the element has not been found +int ft_delete_hashmap_element(t_hashmap *map, void *key, size_t hash) +{ + size_t index; + t_list *curr; + t_list *prev; + t_hash_element *elem; + + if (!map || !key || map->hashmap_size == 0) + return (0); + if (((map->nb_elems * 100) / map->hashmap_size) + <= HASHMAP_FILL_PERCENT_BEFORE_SHRINK) + ft_shrink_hashmap(map); + index = hash % map->hashmap_size; + curr = map->table[index]; + prev = NULL; + while (curr) + { + elem = (t_hash_element *)curr->content; + if (map->cmp(elem->key, key) == 0) + { + return (ft_delete_hashmap_list_node(curr, prev, index, map), 1); + } + prev = curr; + curr = curr->next; + } + return (0); +} + +//returns a pointer to the value of key, or a NULL pointer if not found +void *ft_lookup_hashmap_element(t_hashmap *map, void *key, size_t hash) +{ + size_t index; + t_list *curr; + t_hash_element *elem; + + if (!map || !key || map->hashmap_size == 0) + return (NULL); + index = hash % map->hashmap_size; + curr = map->table[index]; + while (curr) + { + elem = (t_hash_element *)curr->content; + if (map->cmp(elem->key, key) == 0) + return (elem->value); + curr = curr->next; + } + return (NULL); +} + +//frees the entire hashmap and then returns NULL once done +void *ft_free_hashmap(t_hashmap *map) +{ + size_t index; + t_list *curr; + t_list *next; + t_hash_element *elem; + + if (!map) + return (NULL); + if (!map->table) + return (free(map), NULL); + index = 0; + while (index < map->hashmap_size) + { + curr = map->table[index]; + while (curr) + { + next = curr->next; + elem = (t_hash_element *)curr->content; + ft_free_hash_element(elem, map); + free(curr); + curr = next; + } + index++; + } + free(map->table); + return (free(map), NULL); +} diff --git a/libft/ft_hashmap/ft_hashmap.o b/libft/ft_hashmap/ft_hashmap.o new file mode 100644 index 0000000..1516cb5 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap.o differ diff --git a/libft/ft_hashmap/ft_hashmap_advanced_type_hash.c b/libft/ft_hashmap/ft_hashmap_advanced_type_hash.c new file mode 100755 index 0000000..f93cb16 --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_advanced_type_hash.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_advanced_type_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 12:47:23 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:26 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" +#include + +//hash function for an address, returns a size_t between 0 and size_t max +size_t ft_hash_address(const void *key) +{ + uintptr_t address; + + address = (uintptr_t)key; + return ((size_t)address >> 3); +} + +// Hash function for a t_list, returns a size_t between 0 and size_t max +//takes the function to hash a single element +size_t ft_hash_list(const t_list *list) +{ + return (ft_hash_address(list)); +} + +// Hash function for a t_hashmap, returns a size_t between 0 and size_t max +size_t ft_hash_hashmap(const t_hashmap *hashmap) +{ + return (ft_hash_address(hashmap)); +} + +// Hash function for a t_vector, returns a size_t between 0 and size_t max +size_t ft_hash_vector(const t_vector *vec) +{ + size_t i; + int c; + size_t index; + size_t hash; + char *str; + + hash = 5381; + index = vec->index; + str = vec->buffer; + i = 0; + while (i < index) + { + c = str[i++]; + hash = ((hash << 5) + hash) + c; + } + return (hash); +} diff --git a/libft/ft_hashmap/ft_hashmap_advanced_type_hash.o b/libft/ft_hashmap/ft_hashmap_advanced_type_hash.o new file mode 100644 index 0000000..c489238 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_advanced_type_hash.o differ diff --git a/libft/ft_hashmap/ft_hashmap_basic_cmp.c b/libft/ft_hashmap/ft_hashmap_basic_cmp.c new file mode 100755 index 0000000..4ffb8db --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_basic_cmp.c @@ -0,0 +1,79 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_basic_cmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/08 13:18:52 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:27 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" +#include + +// Comparison function for integers +int int_cmp(void *key1, void *key2) +{ + int a; + int b; + + a = *(int *)key1; + b = *(int *)key2; + if (a < b) + return (-1); + else if (a > b) + return (1); + else + return (0); +} + +// Comparison function for strings +int cmp_str(void *key1, void *key2) +{ + return (ft_strcmp((char *)key1, (char *)key2)); +} + +// Comparison function for unsigned chars +int cmp_uchar(void *key1, void *key2) +{ + unsigned char *c1; + unsigned char *c2; + + c1 = (unsigned char *)key1; + c2 = (unsigned char *)key2; + return (*c1 - *c2); +} + +// Comparison function for unsigned integers +int uint_cmp(void *key1, void *key2) +{ + unsigned int a; + unsigned int b; + + a = *(unsigned int *)key1; + b = *(unsigned int *)key2; + if (a < b) + return (-1); + else if (a > b) + return (1); + else + return (0); +} + +// Comparison function for size_t +int sizet_cmp(void *key1, void *key2) +{ + size_t a; + size_t b; + + a = *(size_t *)key1; + b = *(size_t *)key2; + if (a < b) + return (-1); + else if (a > b) + return (1); + else + return (0); +} diff --git a/libft/ft_hashmap/ft_hashmap_basic_cmp.o b/libft/ft_hashmap/ft_hashmap_basic_cmp.o new file mode 100644 index 0000000..19492c4 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_basic_cmp.o differ diff --git a/libft/ft_hashmap/ft_hashmap_basic_type_hash.c b/libft/ft_hashmap/ft_hashmap_basic_type_hash.c new file mode 100755 index 0000000..2f58485 --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_basic_type_hash.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_basic_type_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 12:34:20 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:29 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" + +// Integer hash function, returns a size_t between 0 and size_t max +size_t ft_hash_int(int value) +{ + return ((size_t)(value * 2654435761u)); +} + +// Unsigned integer hash function, returns a size_t between 0 and size_t max +size_t ft_hash_uint(unsigned int value) +{ + return ((size_t)(value * 2654435761u)); +} + +// Character hash function, returns a size_t between 0 and size_t max +size_t ft_hash_char(char value) +{ + return ((size_t)(value * 31)); +} + +// String hash function (DJB2), returns a size_t between 0 and size_t max +size_t ft_hash_string(const char *str) +{ + int c; + size_t hash; + + hash = 5381; + while (*str) + { + c = *str++; + hash = ((hash << 5) + hash) + c; + } + return (hash); +} + +// size_t hash function, returns a size_t between 0 and size_t max +size_t ft_hash_size_t(size_t value) +{ + value ^= value >> 33; + value *= 0xff51afd7ed558ccd; + value ^= value >> 33; + value *= 0xc4ceb9fe1a85ec53; + value ^= value >> 33; + return (value); +} diff --git a/libft/ft_hashmap/ft_hashmap_basic_type_hash.o b/libft/ft_hashmap/ft_hashmap_basic_type_hash.o new file mode 100644 index 0000000..5747da2 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_basic_type_hash.o differ diff --git a/libft/ft_hashmap/ft_hashmap_private.h b/libft/ft_hashmap/ft_hashmap_private.h new file mode 100755 index 0000000..d61db25 --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_private.h @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_private.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 13:49:11 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:30 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_HASHMAP_PRIVATE_H +# define FT_HASHMAP_PRIVATE_H + +# include "../ft_hashmap.h" + +typedef struct s_hash_element +{ + void *key; + void *value; + size_t hash; +} t_hash_element; + +t_hash_element *ft_create_hash_element(void *key, void *value, size_t hash); +void ft_free_hash_element(t_hash_element *elem, t_hashmap *map); +int ft_add_hashmap_element( + size_t index, + t_hashmap *map, + t_hash_element *elem); +int ft_add_hashmap_element( + size_t index, + t_hashmap *map, + t_hash_element *elem); +void ft_copy_hashmap_table( + t_list **new_table, + t_list **old_table, + size_t new_size, + size_t old_size); +void ft_delete_hashmap_list_node( + t_list *curr, + t_list *prev, + size_t index, + t_hashmap *map); + +#endif \ No newline at end of file diff --git a/libft/ft_hashmap/ft_hashmap_utils.c b/libft/ft_hashmap/ft_hashmap_utils.c new file mode 100755 index 0000000..688e91c --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_utils.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 13:51:48 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:32 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" + +void ft_free_hash_element(t_hash_element *elem, t_hashmap *map) +{ + if (map->free_key) + map->free_key(elem->key); + if (map->free_value) + map->free_value(elem->value); + free(elem); +} + +// Helper function to create a new hash element +t_hash_element *ft_create_hash_element(void *key, void *value, size_t hash) +{ + t_hash_element *new_element; + + new_element = malloc(sizeof(t_hash_element)); + if (!new_element) + return (NULL); + new_element->key = key; + new_element->value = value; + new_element->hash = hash; + return (new_element); +} + +//returns 0 for allocation fail without allocating or freeing anything +int ft_add_hashmap_element(size_t index, t_hashmap *map, t_hash_element *elem) +{ + t_list *new_node; + + new_node = malloc(sizeof(t_list)); + if (!new_node) + return (0); + new_node->content = elem; + new_node->next = map->table[index]; + map->table[index] = new_node; + map->nb_elems++; + return (1); +} + +//returns 0 without doing anything if the allocation of the new table fails +//in that case the old table is still valid! +//returns 1 if the resize is a success +int ft_resize_hashmap(t_hashmap *map) +{ + size_t new_size; + t_list **new_table; + + new_size = map->hashmap_size * HASHMAP_RESIZE_FACTOR; + new_table = ft_calloc(new_size, sizeof(t_list *)); + if (!new_table) + return (0); + ft_copy_hashmap_table(new_table, map->table, new_size, map->hashmap_size); + free(map->table); + map->table = new_table; + map->hashmap_size = new_size; + return (1); +} diff --git a/libft/ft_hashmap/ft_hashmap_utils.o b/libft/ft_hashmap/ft_hashmap_utils.o new file mode 100644 index 0000000..c23f249 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_utils.o differ diff --git a/libft/ft_hashmap/ft_hashmap_utils_two.c b/libft/ft_hashmap/ft_hashmap_utils_two.c new file mode 100755 index 0000000..2a37c43 --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_utils_two.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_utils_two.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 16:04:36 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:31 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" + +//doesn't allocate anything no error possible +void ft_copy_hashmap_table( +t_list **new_table, +t_list **old_table, +size_t new_size, +size_t old_size) +{ + t_list *curr; + t_list *next; + t_hash_element *elem; + size_t i; + size_t new_index; + + i = 0; + while (i < old_size) + { + curr = old_table[i]; + while (curr) + { + next = curr->next; + elem = (t_hash_element *)curr->content; + new_index = elem->hash % new_size; + curr->next = new_table[new_index]; + new_table[new_index] = curr; + curr = next; + } + i++; + } +} + +//helper function for delete_hashmap_element to delete the node once found +void ft_delete_hashmap_list_node( +t_list *curr, +t_list *prev, +size_t index, +t_hashmap *map) +{ + t_hash_element *elem; + + elem = (t_hash_element *)curr->content; + if (prev) + prev->next = curr->next; + else + map->table[index] = curr->next; + ft_free_hash_element(elem, map); + free(curr); + map->nb_elems--; +} + +//returns 0 without doing anything if the allocation of the new table fails +//or if the table is too little in that case the old table is still valid! +//returns 1 if the shrink is a success +int ft_shrink_hashmap(t_hashmap *map) +{ + size_t new_size; + t_list **new_table; + + if (map->hashmap_size == HASHMAP_MINIMUM_SIZE) + return (0); + new_size = map->hashmap_size / HASHMAP_SHRINK_FACTOR; + if (new_size < HASHMAP_MINIMUM_SIZE) + new_size = HASHMAP_MINIMUM_SIZE; + new_table = ft_calloc(new_size, sizeof(t_list *)); + if (!new_table) + return (0); + ft_copy_hashmap_table(new_table, map->table, new_size, map->hashmap_size); + free(map->table); + map->table = new_table; + map->hashmap_size = new_size; + return (1); +} diff --git a/libft/ft_hashmap/ft_hashmap_utils_two.o b/libft/ft_hashmap/ft_hashmap_utils_two.o new file mode 100644 index 0000000..9607796 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_utils_two.o differ diff --git a/libft/ft_int_utils.c b/libft/ft_int_utils.c new file mode 100644 index 0000000..605d680 --- /dev/null +++ b/libft/ft_int_utils.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_int_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/30 10:11:17 by alier #+# #+# */ +/* Updated: 2025/02/16 19:03:36 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include "libft.h" + +size_t i_drep_len(int n) +{ + size_t len; + + len = 0; + if (n < 0) + len++; + while (1) + { + len++; + n /= 10; + if (n == 0) + break ; + } + return (len); +} + +/* + * Reimplementation of libc atoi() but sets `errno` to `ERANGE` if an + * domain error is encountered (overflow, underflow) or `EINVAL` if + * no digits characters or invalid characters at end). + */ +int ft_atoie(const char *nptr) +{ + int n; + int mult; + + n = 0; + mult = -1; + while (ft_isspace(*nptr)) + nptr++; + if (*nptr == '+' || *nptr == '-') + { + if (*nptr == '-') + mult = 1; + nptr++; + } + if (!ft_isdigit(*nptr)) + errno = EINVAL; + while (ft_isdigit(*nptr)) + { + n = safe_int_sub(safe_int_mul(n, 10), *nptr - '0'); + nptr++; + } + if (*nptr != '\0') + errno = EINVAL; + return (safe_int_mul(n, mult)); +} + +unsigned int ft_max_uint(size_t len, unsigned int a[len]) +{ + size_t i; + unsigned int max; + + i = 0; + max = 0; + while (i < len) + { + if (a[i] > max) + max = a[i]; + i++; + } + return (max); +} diff --git a/libft/ft_int_utils.o b/libft/ft_int_utils.o new file mode 100644 index 0000000..3372703 Binary files /dev/null and b/libft/ft_int_utils.o differ diff --git a/libft/ft_isalnum.c b/libft/ft_isalnum.c new file mode 100755 index 0000000..f3c9bec --- /dev/null +++ b/libft/ft_isalnum.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isalnum.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 12:44:53 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:40 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_isalnum(int c) +{ + if (ft_isalpha(c) | ft_isdigit(c)) + return (1); + return (0); +} diff --git a/libft/ft_isalnum.o b/libft/ft_isalnum.o new file mode 100644 index 0000000..b3d2091 Binary files /dev/null and b/libft/ft_isalnum.o differ diff --git a/libft/ft_isalpha.c b/libft/ft_isalpha.c new file mode 100755 index 0000000..bee9f1e --- /dev/null +++ b/libft/ft_isalpha.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isalpha.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/06 12:44:45 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:42 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_isalpha(int c) +{ + if (c < 65 || c > 122 || (c > 90 && c < 97)) + return (0); + else + return (1); +} + +int ft_isspace(char c) +{ + return (c == ' ' || c == '\f' || c == '\n' || c == '\r' + || c == '\t' || c == '\v'); +} + +int ft_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + return (c + ('a' - 'A')); + return (c); +} + +int ft_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + return (c - ('a' - 'A')); + return (c); +} diff --git a/libft/ft_isalpha.o b/libft/ft_isalpha.o new file mode 100644 index 0000000..ed31452 Binary files /dev/null and b/libft/ft_isalpha.o differ diff --git a/libft/ft_isascii.c b/libft/ft_isascii.c new file mode 100755 index 0000000..f02c1b6 --- /dev/null +++ b/libft/ft_isascii.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isascii.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:10:04 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:43 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_isascii(int c) +{ + if (c >= 0 && c < 128) + return (1); + return (0); +} diff --git a/libft/ft_isascii.o b/libft/ft_isascii.o new file mode 100644 index 0000000..58f2fb9 Binary files /dev/null and b/libft/ft_isascii.o differ diff --git a/libft/ft_isdigit.c b/libft/ft_isdigit.c new file mode 100755 index 0000000..e47bbd5 --- /dev/null +++ b/libft/ft_isdigit.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isdigit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/08 12:57:11 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:45 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_isdigit(int c) +{ + if (c < '0' || c > '9') + return (0); + return (1); +} diff --git a/libft/ft_isdigit.o b/libft/ft_isdigit.o new file mode 100644 index 0000000..620afc9 Binary files /dev/null and b/libft/ft_isdigit.o differ diff --git a/libft/ft_isprint.c b/libft/ft_isprint.c new file mode 100755 index 0000000..383b8c1 --- /dev/null +++ b/libft/ft_isprint.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isprint.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:14:35 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:47 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_isprint(int c) +{ + if (c < 32 || c > 126) + return (0); + return (1); +} diff --git a/libft/ft_isprint.o b/libft/ft_isprint.o new file mode 100644 index 0000000..701285b Binary files /dev/null and b/libft/ft_isprint.o differ diff --git a/libft/ft_itoa.c b/libft/ft_itoa.c new file mode 100755 index 0000000..7ec2d70 --- /dev/null +++ b/libft/ft_itoa.c @@ -0,0 +1,83 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_itoa.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 15:29:15 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:49 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static void ft_swap(char *a, char *b) +{ + char c; + + c = *a; + *a = *b; + *b = c; +} + +static void ft_reverse_buff(char buff[11], size_t(len)) +{ + size_t index; + + if (buff[0] == '-') + { + index = 1; + while ((len / 2) >= index) + { + ft_swap(&buff[index], &buff[len - index]); + index++; + } + } + else + { + index = 0; + while (((len - 1) / 2) >= index) + { + ft_swap(&buff[index], &buff[len - index - 1]); + index++; + } + } +} + +static char *subfunction(char *ret, char buff[11], size_t buff_len) +{ + ft_reverse_buff(buff, buff_len); + ft_memcpy(ret, (const void *)buff, buff_len); + ret[buff_len] = '\0'; + return (ret); +} + +//only works if an int is 32 bits, I'll maybe change it later for the bonuses +char *ft_itoa(int n) +{ + char *ret; + char buff[11]; + size_t buff_len; + + if (n <= -2147483648) + return (ft_strdup("-2147483648")); + if (n == 0) + return (ft_strdup("0")); + buff_len = 0; + if (n < 0) + { + buff[0] = '-'; + buff_len++; + n *= -1; + } + while (n > 0) + { + buff[buff_len++] = (n % 10) + '0'; + n /= 10; + } + ret = malloc(sizeof(char) * (buff_len) + 1); + if (!ret) + return (NULL); + return (subfunction(ret, buff, buff_len)); +} diff --git a/libft/ft_itoa.o b/libft/ft_itoa.o new file mode 100644 index 0000000..ac4552b Binary files /dev/null and b/libft/ft_itoa.o differ diff --git a/libft/ft_itoa_base.c b/libft/ft_itoa_base.c new file mode 100755 index 0000000..18fe48e --- /dev/null +++ b/libft/ft_itoa_base.c @@ -0,0 +1,120 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_itoa_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/11 11:50:53 by thrieg #+# #+# */ +/* Updated: 2025/11/17 17:14:48 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "ft_vector.h" + +static int ft_is_sign(char c) +{ + if (c == '-' || c == '+') + return (1); + else + return (0); +} + +//converts nbr into a known to be valid base, then append it to vec +//returns 0 if the concatenation fails, or 1 if everything goes well +static int ft_put_ok_base( +unsigned int nbr, +char *base, +size_t base_lenght, +t_vector *vec) +{ + char buffer[32]; + int i; + + i = 31; + if (nbr == 0) + if (!ft_vector_pushback(vec, base[0])) + return (0); + while (nbr > 0) + { + buffer[i] = base[nbr % base_lenght]; + nbr /= base_lenght; + i--; + } + if (!ft_vector_concat(vec, (buffer + i + 1), (31 - i))) + return (0); + return (1); +} + +//converts nbr into an unsigned int, +//append a minus sign in vec if nbr is negative +//sets flag_pushback_failed to 1 if ft_vector_pushback returns NULL +static unsigned int ft_transform_int_to_unsigned( +int nbr, +t_vector *vec, +int *flag_pushback_failed) +{ + if (nbr < 0) + { + if (!ft_vector_pushback(vec, '-')) + *flag_pushback_failed = 1; + if (nbr == -2147483648) + return (2147483648); + else + return ((unsigned int) -nbr); + } + else + return ((unsigned int) nbr); +} + +//returns 1 if the base is valid, and 0 if it's not +static int ft_is_ok_base(char *base) +{ + char used_characters[128]; + size_t i; + + i = 0; + ft_bzero(used_characters, 128); + while (base[i] != '\0') + { + if (used_characters[(int) base[i]] == 0) + used_characters[(int) base[i]]++; + else + return (0); + if (ft_is_sign(base[i])) + return (0); + i++; + } + if (i < 2) + return (0); + return (1); +} + +//returns a standard C string of nbr converted in the "base" base +//base have to only cointain ascii characters +//returns NULL if the base is invalid or if an allocation failed +char *ft_itoa_base(int nbr, char *base) +{ + unsigned int unsigned_nbr; + t_vector *ret; + char *ret_str; + int flag; + + ret = ft_create_vector(2); + if (!ret) + return (NULL); + flag = 0; + if (!ft_is_ok_base(base)) + return (ft_free_vector(&ret), NULL); + unsigned_nbr = ft_transform_int_to_unsigned(nbr, ret, &flag); + if (flag) + return (ft_free_vector(&ret), NULL); + if (!ft_put_ok_base(unsigned_nbr, base, ft_strlen(base), ret)) + return (ft_free_vector(&ret), NULL); + ret_str = ft_vtoc(ret); + ft_free_vector(&ret); + if (!ret_str) + return (NULL); + return (ret_str); +} diff --git a/libft/ft_itoa_base.o b/libft/ft_itoa_base.o new file mode 100644 index 0000000..4b3cb94 Binary files /dev/null and b/libft/ft_itoa_base.o differ diff --git a/libft/ft_long_utils.c b/libft/ft_long_utils.c new file mode 100644 index 0000000..fadbdf1 --- /dev/null +++ b/libft/ft_long_utils.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_long_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/30 10:11:17 by alier #+# #+# */ +/* Updated: 2025/02/16 19:03:51 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include "libft.h" + +/* + * Reimplementation of libc atol() but sets `errno` to `ERANGE` if an + * domain error is encountered (overflow, underflow) or `EINVAL` if + * no digits characters or invalid characters at end). + */ +long ft_atole(const char *nptr) +{ + long n; + long mult; + + n = 0; + mult = -1; + while (ft_isspace(*nptr)) + nptr++; + if (*nptr == '+' || *nptr == '-') + { + if (*nptr == '-') + mult = 1; + nptr++; + } + if (!ft_isdigit(*nptr)) + errno = EINVAL; + while (ft_isdigit(*nptr)) + { + n = safe_long_sub(safe_long_mul(n, 10), *nptr - '0'); + nptr++; + } + if (*nptr != '\0') + errno = EINVAL; + return (safe_long_mul(n, mult)); +} diff --git a/libft/ft_long_utils.o b/libft/ft_long_utils.o new file mode 100644 index 0000000..6ec619b Binary files /dev/null and b/libft/ft_long_utils.o differ diff --git a/libft/ft_lstadd_back_bonus.c b/libft/ft_lstadd_back_bonus.c new file mode 100755 index 0000000..91de5f3 --- /dev/null +++ b/libft/ft_lstadd_back_bonus.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstadd_back_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:41:51 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:52 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or new is NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstadd_back(t_list **lst, t_list *new) +{ + if (!lst || !new) + return ; + if (*lst == NULL) + *lst = new; + else + ft_lstlast(*lst)->next = new; +} diff --git a/libft/ft_lstadd_back_bonus.o b/libft/ft_lstadd_back_bonus.o new file mode 100644 index 0000000..20a117a Binary files /dev/null and b/libft/ft_lstadd_back_bonus.o differ diff --git a/libft/ft_lstadd_front_bonus.c b/libft/ft_lstadd_front_bonus.c new file mode 100755 index 0000000..3f2c52b --- /dev/null +++ b/libft/ft_lstadd_front_bonus.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstadd_front_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:04:47 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:53 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or new are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstadd_front(t_list **lst, t_list *new) +{ + if (!new || !lst) + return ; + new->next = *lst; + *lst = new; +} diff --git a/libft/ft_lstadd_front_bonus.o b/libft/ft_lstadd_front_bonus.o new file mode 100644 index 0000000..d802309 Binary files /dev/null and b/libft/ft_lstadd_front_bonus.o differ diff --git a/libft/ft_lstclear_bonus.c b/libft/ft_lstclear_bonus.c new file mode 100755 index 0000000..db7312c --- /dev/null +++ b/libft/ft_lstclear_bonus.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstclear_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 13:00:50 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:54 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or del are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstclear(t_list **lst, void (*del)(void *)) +{ + t_list *next; + + if (!lst || !del) + return ; + while (*lst) + { + next = (*lst)->next; + del((*lst)->content); + free(*lst); + *lst = next; + } +} diff --git a/libft/ft_lstclear_bonus.o b/libft/ft_lstclear_bonus.o new file mode 100644 index 0000000..33a483d Binary files /dev/null and b/libft/ft_lstclear_bonus.o differ diff --git a/libft/ft_lstdelone_bonus.c b/libft/ft_lstdelone_bonus.c new file mode 100755 index 0000000..f611101 --- /dev/null +++ b/libft/ft_lstdelone_bonus.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstdelone_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:53:23 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:55 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or del are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstdelone(t_list *lst, void (*del)(void *)) +{ + if (!lst || !del) + return ; + del(lst->content); + free(lst); +} diff --git a/libft/ft_lstdelone_bonus.o b/libft/ft_lstdelone_bonus.o new file mode 100644 index 0000000..57fa2be Binary files /dev/null and b/libft/ft_lstdelone_bonus.o differ diff --git a/libft/ft_lstiter_bonus.c b/libft/ft_lstiter_bonus.c new file mode 100755 index 0000000..bdd0af4 --- /dev/null +++ b/libft/ft_lstiter_bonus.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstiter_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 13:11:26 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:57 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or f are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstiter(t_list *lst, void (*f)(void *)) +{ + if (!lst || !f) + return ; + while (lst->next) + { + f(lst->content); + lst = lst->next; + } + f(lst->content); +} diff --git a/libft/ft_lstiter_bonus.o b/libft/ft_lstiter_bonus.o new file mode 100644 index 0000000..b560c0d Binary files /dev/null and b/libft/ft_lstiter_bonus.o differ diff --git a/libft/ft_lstlast_bonus.c b/libft/ft_lstlast_bonus.c new file mode 100755 index 0000000..5c1ecf3 --- /dev/null +++ b/libft/ft_lstlast_bonus.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstlast_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:21:13 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:00 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns NULL if lst is NULL +t_list *ft_lstlast(t_list *lst) +{ + if (!lst) + return (NULL); + while (lst->next) + lst = lst->next; + return (lst); +} + +/* + * @return the element of `lst` at position `i`, NULL if doesn't exist. + * `ft_lstat(lst, 0)` returns `lst`. + */ +t_list *ft_lstat(t_list *lst, size_t i) +{ + size_t j; + + if (lst == NULL) + return (lst); + j = 0; + while (lst->next != NULL && j < i) + { + lst = lst->next; + j++; + } + if (j != i) + return (NULL); + return (lst); +} diff --git a/libft/ft_lstlast_bonus.o b/libft/ft_lstlast_bonus.o new file mode 100644 index 0000000..9d954a1 Binary files /dev/null and b/libft/ft_lstlast_bonus.o differ diff --git a/libft/ft_lstmap_bonus.c b/libft/ft_lstmap_bonus.c new file mode 100755 index 0000000..4cdb53d --- /dev/null +++ b/libft/ft_lstmap_bonus.c @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstmap_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 13:22:26 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:01 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static t_list *ft_safe_create( +void *(*f)(void *), +void (*del)(void *), +void *content) +{ + void *temp; + t_list *ret; + + temp = f(content); + if (!temp) + return (NULL); + ret = ft_lstnew(temp); + if (!ret) + { + del(temp); + return (NULL); + } + return (ret); +} + +//returns NULL without doing anything else if any argument is NULL +//returns NULL if any allocation fails +t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *)) +{ + t_list *new_list; + t_list *new_node; + t_list *temp; + + if (!lst || !f || !del) + return (NULL); + new_node = ft_safe_create(f, del, lst->content); + if (!new_node) + return (NULL); + new_list = new_node; + lst = lst->next; + while (lst) + { + temp = ft_safe_create(f, del, lst->content); + if (!temp) + { + ft_lstclear(&new_list, del); + return (NULL); + } + new_node->next = temp; + new_node = new_node->next; + lst = lst->next; + } + return (new_list); +} diff --git a/libft/ft_lstmap_bonus.o b/libft/ft_lstmap_bonus.o new file mode 100644 index 0000000..2f5f000 Binary files /dev/null and b/libft/ft_lstmap_bonus.o differ diff --git a/libft/ft_lstnew_bonus.c b/libft/ft_lstnew_bonus.c new file mode 100755 index 0000000..d06f4b6 --- /dev/null +++ b/libft/ft_lstnew_bonus.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstnew_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 11:54:17 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:02 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns NULL if any allocation fails +t_list *ft_lstnew(void *content) +{ + t_list *ret; + + ret = malloc(sizeof(t_list)); + if (!ret) + return (NULL); + ret->content = content; + ret->next = NULL; + return (ret); +} diff --git a/libft/ft_lstnew_bonus.o b/libft/ft_lstnew_bonus.o new file mode 100644 index 0000000..531718f Binary files /dev/null and b/libft/ft_lstnew_bonus.o differ diff --git a/libft/ft_lstsize_bonus.c b/libft/ft_lstsize_bonus.c new file mode 100755 index 0000000..b680bd9 --- /dev/null +++ b/libft/ft_lstsize_bonus.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstsize_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:13:44 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:03 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns 0 if lst is NULL +int ft_lstsize(t_list *lst) +{ + int i; + + if (!lst) + return (0); + i = 1; + while (lst->next) + { + i++; + lst = lst->next; + } + return (i); +} diff --git a/libft/ft_lstsize_bonus.o b/libft/ft_lstsize_bonus.o new file mode 100644 index 0000000..1a8a1f3 Binary files /dev/null and b/libft/ft_lstsize_bonus.o differ diff --git a/libft/ft_memchr.c b/libft/ft_memchr.c new file mode 100755 index 0000000..e2afec0 --- /dev/null +++ b/libft/ft_memchr.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:19:34 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:05 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memchr(const void *s, int c, size_t n) +{ + const char *str; + + str = (const char *)s; + while (n--) + { + if (*str == (char)c) + return ((void *)str); + str++; + } + return (NULL); +} diff --git a/libft/ft_memchr.o b/libft/ft_memchr.o new file mode 100644 index 0000000..6f09b78 Binary files /dev/null and b/libft/ft_memchr.o differ diff --git a/libft/ft_memcmp.c b/libft/ft_memcmp.c new file mode 100755 index 0000000..5c63833 --- /dev/null +++ b/libft/ft_memcmp.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memcmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:39:59 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:06 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_memcmp(const void *s1, const void *s2, size_t n) +{ + const unsigned char *st1; + const unsigned char *st2; + + st1 = (const unsigned char *)s1; + st2 = (const unsigned char *)s2; + while (n && (*st1 == *st2)) + { + st1++; + st2++; + n--; + } + if (n == 0) + return (0); + return (*st1 - *st2); +} diff --git a/libft/ft_memcmp.o b/libft/ft_memcmp.o new file mode 100644 index 0000000..b0c9e05 Binary files /dev/null and b/libft/ft_memcmp.o differ diff --git a/libft/ft_memcpy.c b/libft/ft_memcpy.c new file mode 100755 index 0000000..41f71dc --- /dev/null +++ b/libft/ft_memcpy.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:52:40 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:07 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memcpy(void *dest, const void *src, size_t n) +{ + char *str; + unsigned long long *str_packed; + char *str_src; + unsigned long long *str_src_packed; + + str_packed = (unsigned long long *)dest; + str_src_packed = (unsigned long long *)src; + while (n >= sizeof(unsigned long long)) + { + *str_packed++ = *str_src_packed++; + n -= sizeof(unsigned long long); + } + str = (char *)str_packed; + str_src = (char *)str_src_packed; + while (n > 0) + { + *str++ = *str_src++; + n--; + } + return (dest); +} diff --git a/libft/ft_memcpy.o b/libft/ft_memcpy.o new file mode 100644 index 0000000..9700482 Binary files /dev/null and b/libft/ft_memcpy.o differ diff --git a/libft/ft_memmove.c b/libft/ft_memmove.c new file mode 100755 index 0000000..a2b7492 --- /dev/null +++ b/libft/ft_memmove.c @@ -0,0 +1,61 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memmove.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:00:16 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:08 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static void *ft_optimised_revcpy(void *dest, const void *src, size_t n) +{ + char *str; + unsigned long long *str_packed; + char *str_src; + unsigned long long *str_src_packed; + + str = (char *)dest; + str_src = (char *)src; + while (n % sizeof(unsigned long long)) + { + n--; + str[n] = str_src[n]; + } + n /= sizeof(unsigned long long); + str_packed = (unsigned long long *)dest; + str_src_packed = (unsigned long long *)src; + while (n > 0) + { + n--; + str_packed[n] = str_src_packed[n]; + } + return (dest); +} + +void *ft_memmove(void *dest, const void *src, size_t n) +{ + char *str; + const char *str_src; + + if (!dest && !src) + return (NULL); + str = (char *)dest; + str_src = (const char *)src; + if (str > str_src) + { + if ((str + sizeof(unsigned long long)) > str_src) + return (ft_optimised_revcpy(dest, src, n)); + while (n-- > 0) + str[n] = str_src[n]; + } + else + { + ft_memcpy(dest, src, n); + } + return (dest); +} diff --git a/libft/ft_memmove.o b/libft/ft_memmove.o new file mode 100644 index 0000000..57bbabc Binary files /dev/null and b/libft/ft_memmove.o differ diff --git a/libft/ft_memset.c b/libft/ft_memset.c new file mode 100755 index 0000000..e181a44 --- /dev/null +++ b/libft/ft_memset.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:40:57 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:13 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memset(void *s, int c, size_t n) +{ + char *str; + unsigned long long *str_packed; + unsigned long long cccccccc; + size_t i; + + str = (char *)s; + while (n % sizeof(unsigned long long)) + { + *str++ = (unsigned char)c; + n--; + } + str_packed = (unsigned long long *)str; + cccccccc = 0; + i = 0; + while (i < sizeof(unsigned long long)) + { + cccccccc |= ((unsigned long long)(unsigned char)c) << (i * 8); + i++; + } + while (n >= sizeof(unsigned long long)) + { + *str_packed++ = cccccccc; + n -= sizeof(unsigned long long); + } + return (s); +} diff --git a/libft/ft_memset.o b/libft/ft_memset.o new file mode 100644 index 0000000..dcfddd6 Binary files /dev/null and b/libft/ft_memset.o differ diff --git a/libft/ft_power.c b/libft/ft_power.c new file mode 100644 index 0000000..a3c7e2a --- /dev/null +++ b/libft/ft_power.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_power.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/07 14:57:23 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:15 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +ssize_t ft_power(ssize_t nb, ssize_t power) +{ + ssize_t answer; + ssize_t i; + + if (power < 0) + return (0); + if (power == 0) + return (1); + if (power % 2 == 0) + return (ft_power(nb * nb, power / 2)); + answer = nb; + i = 1; + while (i < power) + { + if ((power - i) % 2 == 0) + { + return (answer * ft_power(nb, (power - i))); + } + answer *= nb; + i++; + } + return (answer); +} diff --git a/libft/ft_power.o b/libft/ft_power.o new file mode 100644 index 0000000..8285f43 Binary files /dev/null and b/libft/ft_power.o differ diff --git a/libft/ft_printf/ft_arglist_bonus.c b/libft/ft_printf/ft_arglist_bonus.c new file mode 100755 index 0000000..c5b95a7 --- /dev/null +++ b/libft/ft_printf/ft_arglist_bonus.c @@ -0,0 +1,104 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_arglist_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/27 17:04:47 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:39 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +static void ft_set_default_flag_values(t_arglist *arglist) +{ + arglist->width_mini = 0; + arglist->precision = -1; + arglist->flag_hashtag = 0; + arglist->flag_zero = 0; + arglist->flag_justified_left = 0; + arglist->flag_space = 0; + arglist->flag_plus = 0; +} + +static void ft_handle_overriding_arguments(t_arglist *arglist) +{ + if ((arglist->precision >= 0) || arglist->flag_justified_left) + arglist->flag_zero = 0; + if (arglist->flag_plus) + arglist->flag_space = 0; +} + +static void ft_handle_width_precision( +t_arglist *arglist, +int *i, +const char *str, +va_list *args) +{ + if (ft_isdigit(str[*i])) + { + arglist->width_mini = ft_atoi(&str[*i], NULL); + while (ft_isdigit(str[*i])) + (*i)++; + } + else if (str[*i] == '*') + { + arglist->width_mini = va_arg(*args, int); + (*i)++; + } + if (str[*i] == '.') + { + (*i)++; + if (str[*i] == '*') + { + arglist->precision = va_arg(*args, int); + (*i)++; + } + else + arglist->precision = ft_atoi(&str[*i], NULL); + while (ft_isdigit(str[*i])) + (*i)++; + } +} + +static void ft_handle_flags(t_arglist *arglist, int *i, const char *str) +{ + while (str[*i] == '#' || str[*i] == '0' || str[*i] == '-' + || str[*i] == ' ' || str[*i] == '+') + { + if (str[*i] == '#') + arglist->flag_hashtag = 1; + if (str[*i] == '0') + arglist->flag_zero = 1; + if (str[*i] == '-') + arglist->flag_justified_left = 1; + if (str[*i] == ' ') + arglist->flag_space = 1; + if (str[*i] == '+') + arglist->flag_plus = 1; + (*i)++; + } +} + +t_arglist *ft_create_arglist(const char *str, va_list *args) +{ + t_arglist *arglist; + int i; + + arglist = malloc(sizeof(t_arglist)); + if (!arglist) + return (NULL); + ft_set_default_flag_values(arglist); + i = 0; + if (str[i] == '%') + i++; + ft_handle_flags(arglist, &i, str); + ft_handle_width_precision(arglist, &i, str, args); + arglist->size_of_argument_string = i; + ft_handle_overriding_arguments(arglist); + return (arglist); +} diff --git a/libft/ft_printf/ft_arglist_bonus.o b/libft/ft_printf/ft_arglist_bonus.o new file mode 100644 index 0000000..baffe29 Binary files /dev/null and b/libft/ft_printf/ft_arglist_bonus.o differ diff --git a/libft/ft_printf/ft_case_d_bonus.c b/libft/ft_printf/ft_case_d_bonus.c new file mode 100755 index 0000000..2f20550 --- /dev/null +++ b/libft/ft_printf/ft_case_d_bonus.c @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_d_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:12:38 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:44 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +char *init_str_to_cat(t_arglist *arglist, unsigned int nbr); +void convert_precision_if_flag_zero(t_arglist *arglist, int nbr); +int ft_handle_if_precision( + t_arglist *arglist, + int nbr, + t_vector *vec, + int *size); +int ft_handle_if_not_precision( + t_arglist *arglist, + int nbr, + t_vector *vec, + int *size); +int ft_handle_concat_and_padding( + t_arglist *arglist, + char *str_to_cat, + t_vector *vec, + int size); + +//flags to handle: zero, space, plus, precision, justified left... hard mode +//flag zero padding without precision behaves just like a precision +//(zeroes after the sign) and when it's spaces they're before the sign +int ft_case_d_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + int nbr; + int size; + + nbr = va_arg(*args, int); + str_to_cat = init_str_to_cat(arglist, nbr); + if (!str_to_cat) + return (0); + convert_precision_if_flag_zero(arglist, nbr); + size = (int)ft_strlen(str_to_cat); + if (nbr < 0) + size--; + if ((size < arglist->precision) && (arglist->precision >= 0)) + { + if (!ft_handle_if_precision(arglist, nbr, vec, &size)) + return (free(str_to_cat), 0); + } + else + { + if (!ft_handle_if_not_precision(arglist, nbr, vec, &size)) + return (free(str_to_cat), 0); + } + if (!ft_handle_concat_and_padding(arglist, str_to_cat, vec, size)) + return (free(str_to_cat), 0); + return (free(str_to_cat), 1); +} diff --git a/libft/ft_printf/ft_case_d_bonus.o b/libft/ft_printf/ft_case_d_bonus.o new file mode 100644 index 0000000..f9e6b31 Binary files /dev/null and b/libft/ft_printf/ft_case_d_bonus.o differ diff --git a/libft/ft_printf/ft_case_d_utils_bonus.c b/libft/ft_printf/ft_case_d_utils_bonus.c new file mode 100755 index 0000000..2183a54 --- /dev/null +++ b/libft/ft_printf/ft_case_d_utils_bonus.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_d_utils_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/27 15:59:04 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:45 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +char *init_str_to_cat(t_arglist *arglist, unsigned int nbr) +{ + if (nbr == 0 && arglist->precision == 0) + return (ft_strdup("")); + return (ft_itoa(nbr)); +} + +void convert_precision_if_flag_zero(t_arglist *arglist, int nbr) +{ + if ((arglist->precision < 0) && !(arglist->flag_justified_left) + && arglist->flag_zero) + { + arglist->precision = arglist->width_mini; + arglist->width_mini = 0; + if (nbr < 0 || arglist->flag_plus || arglist->flag_space) + arglist->precision--; + } +} + +int ft_handle_if_precision( +t_arglist *arglist, +int nbr, +t_vector *vec, +int *size) +{ + if (nbr < 0 || arglist->flag_plus || arglist->flag_space) + { + if (padding_if_needed_before(arglist, 'd', + arglist->precision + 1, vec) < 0) + return (0); + } + else + if (padding_if_needed_before(arglist, 'd', arglist->precision, vec) < 0) + return (0); + if (arglist->flag_plus && (nbr >= 0) && !ft_vector_pushback(vec, '+')) + return (0); + if (arglist->flag_space && (nbr >= 0) && !(arglist->flag_plus) && nbr >= 0) + if (!ft_vector_pushback(vec, ' ')) + return (0); + if (nbr < 0 && !ft_vector_pushback(vec, '-')) + return (0); + while ((*size) < arglist->precision) + { + if (!ft_vector_pushback(vec, '0')) + return (0); + (*size)++; + } + if (nbr < 0 || arglist->flag_plus || arglist->flag_space) + (*size)++; + return (1); +} + +int ft_handle_if_not_precision( +t_arglist *arglist, +int nbr, +t_vector *vec, +int *size) +{ + if (nbr < 0 || arglist->flag_space || arglist->flag_plus) + (*size)++; + if (padding_if_needed_before(arglist, 'd', (*size), vec) < 0) + return (0); + if (arglist->flag_plus && (nbr >= 0)) + if (!ft_vector_pushback(vec, '+')) + return (0); + if (arglist->flag_space && (nbr >= 0) && !(arglist->flag_plus)) + if (nbr >= 0) + if (!ft_vector_pushback(vec, ' ')) + return (0); + if (nbr < 0) + if (!ft_vector_pushback(vec, '-')) + return (0); + return (1); +} + +int ft_handle_concat_and_padding( +t_arglist *arglist, +char *str_to_cat, +t_vector *vec, +int size) +{ + if (!ft_vector_concat(vec, str_to_cat + ft_strnonchr(str_to_cat, '-'), + ft_strlen(str_to_cat) - ft_strnonchr(str_to_cat, '-'))) + return (0); + if (padding_if_needed_after(arglist, 'd', size, vec) < 0) + return (0); + return (1); +} diff --git a/libft/ft_printf/ft_case_d_utils_bonus.o b/libft/ft_printf/ft_case_d_utils_bonus.o new file mode 100644 index 0000000..6f41dfe Binary files /dev/null and b/libft/ft_printf/ft_case_d_utils_bonus.o differ diff --git a/libft/ft_printf/ft_case_lowx_bonus.c b/libft/ft_printf/ft_case_lowx_bonus.c new file mode 100644 index 0000000..319b480 --- /dev/null +++ b/libft/ft_printf/ft_case_lowx_bonus.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_lowx_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:09:37 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:46 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +static int handle_hashtag_prefix( +t_vector *vec, +t_arglist *arglist, +unsigned int nbr, +int flag_zero) +{ + if (arglist->flag_hashtag && !flag_zero && nbr != 0) + { + if (!ft_vector_concat(vec, "0x", 2)) + return (0); + } + return (1); +} + +static int apply_precision_padding(t_vector *vec, size_t *size, int precision) +{ + while ((int)(*size)++ < precision) + { + if (!ft_vector_pushback(vec, '0')) + return (0); + } + (*size)--; + return (1); +} + +static char *init_str_to_cat(t_arglist *arglist, unsigned int nbr) +{ + if (nbr == 0 && arglist->precision == 0) + return (ft_strdup("")); + return (ft_utoa_base(nbr, "0123456789abcdef")); +} + +static int handle_padding_and_prefix( +t_vector *vec, +t_arglist *arglist, +size_t size, +unsigned int nbr) +{ + if (arglist->flag_hashtag && arglist->flag_zero && nbr != 0) + { + if (!ft_vector_concat(vec, "0x", 2)) + return (0); + } + if (((int)size < arglist->precision) && (arglist->precision >= 0)) + { + if (padding_if_needed_before(arglist, 'x', arglist->precision + + (arglist->flag_hashtag * 2 * (nbr != 0)), vec) < 0) + return (0); + if (!handle_hashtag_prefix(vec, arglist, nbr, arglist->flag_zero)) + return (0); + } + else + { + if (arglist->flag_hashtag && nbr != 0) + size += 2; + if (padding_if_needed_before(arglist, 'x', size, vec) < 0) + return (0); + if (!handle_hashtag_prefix(vec, arglist, nbr, arglist->flag_zero)) + return (0); + } + return (1); +} + +int ft_case_x_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + size_t size; + unsigned int nbr; + + nbr = va_arg(*args, unsigned int); + str_to_cat = init_str_to_cat(arglist, nbr); + if (!str_to_cat) + return (0); + size = ft_strlen(str_to_cat); + if (!handle_padding_and_prefix(vec, arglist, size, nbr)) + return (free(str_to_cat), 0); + if (((int)size < arglist->precision) && (arglist->precision >= 0)) + { + if (!apply_precision_padding(vec, &size, arglist->precision)) + return (free(str_to_cat), 0); + } + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + if (padding_if_needed_after(arglist, 'x', size, vec) < 0) + return (0); + return (1); +} diff --git a/libft/ft_printf/ft_case_lowx_bonus.o b/libft/ft_printf/ft_case_lowx_bonus.o new file mode 100644 index 0000000..28104aa Binary files /dev/null and b/libft/ft_printf/ft_case_lowx_bonus.o differ diff --git a/libft/ft_printf/ft_case_p_bonus.c b/libft/ft_printf/ft_case_p_bonus.c new file mode 100755 index 0000000..65beaeb --- /dev/null +++ b/libft/ft_printf/ft_case_p_bonus.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_p_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 16:22:40 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:47 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +//zero and precision flags have undefined behavior here +int ft_case_p_bonus_utils(t_vector *vec, char *str_to_cat, t_arglist *arglist) +{ + size_t index; + size_t size; + + index = ft_strnonchr(str_to_cat, '0'); + size = ft_strlen(str_to_cat + index); + if (padding_if_needed_before(arglist, 'p', (size + 2), vec) < 0) + return (0); + if (!ft_vector_concat(vec, "0x", 2)) + return (0); + if (!ft_vector_concat(vec, (str_to_cat + index), size)) + return (0); + if (padding_if_needed_after(arglist, 'p', (size + 2), vec) < 0) + return (0); + return (1); +} + +//zero and precision flags have undefined behavior here +int ft_case_p_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + void *arg; + int ret; + + arg = va_arg(*args, void *); + if (!arg) + { + if (padding_if_needed_before(arglist, 'p', 5, vec) < 0) + return (0); + if (!ft_vector_concat(vec, "(nil)", 5)) + return (0); + if (padding_if_needed_after(arglist, 'p', 5, vec) < 0) + return (0); + return (1); + } + str_to_cat = ft_addr_to_strhex(arg); + if (!str_to_cat) + return (0); + ret = ft_case_p_bonus_utils(vec, str_to_cat, arglist); + return (free(str_to_cat), ret); +} diff --git a/libft/ft_printf/ft_case_p_bonus.o b/libft/ft_printf/ft_case_p_bonus.o new file mode 100644 index 0000000..8e641c0 Binary files /dev/null and b/libft/ft_printf/ft_case_p_bonus.o differ diff --git a/libft/ft_printf/ft_case_s_bonus.c b/libft/ft_printf/ft_case_s_bonus.c new file mode 100755 index 0000000..964a6a0 --- /dev/null +++ b/libft/ft_printf/ft_case_s_bonus.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_s_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:03:40 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:48 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +static int ft_s_sub_bonus(t_vector *vec, char *str_to_cat, t_arglist *arglist) +{ + size_t size; + + if (!str_to_cat) + { + size = 6; + if ((int)size > arglist->precision && (arglist->precision >= 0)) + size = 0; + if (padding_if_needed_before(arglist, 's', size, vec) < 0) + return (0); + if (!ft_vector_concat(vec, "(null)", size)) + return (0); + } + else + { + size = ft_strlen(str_to_cat); + if ((int)size > arglist->precision && (arglist->precision >= 0)) + size = arglist->precision; + if (padding_if_needed_before(arglist, 's', size, vec) < 0) + return (0); + if (!ft_vector_concat(vec, str_to_cat, size)) + return (0); + } + if (padding_if_needed_after(arglist, 's', size, vec) < 0) + return (0); + return (1); +} + +//flag 0 has undefined behavior with c so the minimum width has to be spaces +int ft_case_s_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + + str_to_cat = va_arg(*args, char *); + return (ft_s_sub_bonus(vec, str_to_cat, arglist)); +} diff --git a/libft/ft_printf/ft_case_s_bonus.o b/libft/ft_printf/ft_case_s_bonus.o new file mode 100644 index 0000000..05c9bd0 Binary files /dev/null and b/libft/ft_printf/ft_case_s_bonus.o differ diff --git a/libft/ft_printf/ft_case_u_bonus.c b/libft/ft_printf/ft_case_u_bonus.c new file mode 100755 index 0000000..2e6ce15 --- /dev/null +++ b/libft/ft_printf/ft_case_u_bonus.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_u_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:07:14 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:49 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +static int ft_handle_padding_precision_bonus( +t_vector *vec, +size_t size, +t_arglist *arglist, +int padding_length) +{ + if (padding_if_needed_before(arglist, 'u', padding_length, vec) < 0) + return (0); + while ((int)size++ < arglist->precision) + { + if (!ft_vector_pushback(vec, '0')) + return (0); + } + size--; + return (1); +} + +// Plus and space flags have undefined behavior here +int ft_case_u_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + int size; + unsigned int nbr; + int padding_length; + + nbr = va_arg(*args, unsigned int); + if (nbr == 0 && arglist->precision == 0) + str_to_cat = ft_strdup(""); + else + str_to_cat = ft_utoa(nbr); + if (!str_to_cat) + return (0); + size = (int)ft_strlen(str_to_cat); + if (size < arglist->precision) + padding_length = arglist->precision; + else + padding_length = size; + if (!ft_handle_padding_precision_bonus(vec, size, arglist, padding_length)) + return (free(str_to_cat), 0); + if (!ft_vector_concat(vec, str_to_cat, size)) + return (free(str_to_cat), 0); + if (padding_if_needed_after(arglist, 'u', padding_length, vec) < 0) + return (free(str_to_cat), 0); + return (free(str_to_cat), 1); +} diff --git a/libft/ft_printf/ft_case_u_bonus.o b/libft/ft_printf/ft_case_u_bonus.o new file mode 100644 index 0000000..55caefb Binary files /dev/null and b/libft/ft_printf/ft_case_u_bonus.o differ diff --git a/libft/ft_printf/ft_case_uppx_bonus.c b/libft/ft_printf/ft_case_uppx_bonus.c new file mode 100644 index 0000000..51f1101 --- /dev/null +++ b/libft/ft_printf/ft_case_uppx_bonus.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_uppx_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:11:07 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:50 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +static int handle_hashtag_prefix( +t_vector *vec, +t_arglist *arglist, +unsigned int nbr, +int flag_zero) +{ + if (arglist->flag_hashtag && !flag_zero && nbr != 0) + { + if (!ft_vector_concat(vec, "0X", 2)) + return (0); + } + return (1); +} + +static int apply_precision_padding(t_vector *vec, size_t *size, int precision) +{ + while ((int)(*size)++ < precision) + { + if (!ft_vector_pushback(vec, '0')) + return (0); + } + (*size)--; + return (1); +} + +static char *init_str_to_cat(t_arglist *arglist, unsigned int nbr) +{ + if (nbr == 0 && arglist->precision == 0) + return (ft_strdup("")); + return (ft_utoa_base(nbr, "0123456789ABCDEF")); +} + +static int handle_padding_and_prefix( +t_vector *vec, +t_arglist *arglist, +size_t size, +unsigned int nbr) +{ + if (arglist->flag_hashtag && arglist->flag_zero && nbr != 0) + { + if (!ft_vector_concat(vec, "0X", 2)) + return (0); + } + if (((int)size < arglist->precision) && (arglist->precision >= 0)) + { + if (padding_if_needed_before(arglist, 'X', arglist->precision + + (arglist->flag_hashtag * 2 * (nbr != 0)), vec) < 0) + return (0); + if (!handle_hashtag_prefix(vec, arglist, nbr, arglist->flag_zero)) + return (0); + } + else + { + if (arglist->flag_hashtag && nbr != 0) + size += 2; + if (padding_if_needed_before(arglist, 'X', size, vec) < 0) + return (0); + if (!handle_hashtag_prefix(vec, arglist, nbr, arglist->flag_zero)) + return (0); + } + return (1); +} + +int ft_case_upperx_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + size_t size; + unsigned int nbr; + + nbr = va_arg(*args, unsigned int); + str_to_cat = init_str_to_cat(arglist, nbr); + if (!str_to_cat) + return (0); + size = ft_strlen(str_to_cat); + if (!handle_padding_and_prefix(vec, arglist, size, nbr)) + return (free(str_to_cat), 0); + if (((int)size < arglist->precision) && (arglist->precision >= 0)) + { + if (!apply_precision_padding(vec, &size, arglist->precision)) + return (free(str_to_cat), 0); + } + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + if (padding_if_needed_after(arglist, 'X', size, vec) < 0) + return (0); + return (1); +} diff --git a/libft/ft_printf/ft_case_uppx_bonus.o b/libft/ft_printf/ft_case_uppx_bonus.o new file mode 100644 index 0000000..a649e62 Binary files /dev/null and b/libft/ft_printf/ft_case_uppx_bonus.o differ diff --git a/libft/ft_printf/ft_cases_easy_bonus.c b/libft/ft_printf/ft_cases_easy_bonus.c new file mode 100755 index 0000000..aa05aa1 --- /dev/null +++ b/libft/ft_printf/ft_cases_easy_bonus.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_cases_easy_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 13:03:05 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:51 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +//flag 0 has undefined behavior with c so the minimum width has to be spaces +int ft_case_c_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + if (padding_if_needed_before(arglist, 'c', 1, vec) < 0) + return (0); + if (!ft_vector_pushback(vec, (char)va_arg(*args, int))) + return (0); + if (padding_if_needed_after(arglist, 'c', 1, vec) < 0) + return (0); + return (1); +} + +int ft_case_percent_bonus(t_vector *vec) +{ + if (!ft_vector_pushback(vec, '%')) + return (0); + return (1); +} + +int ft_case_d_bonus(t_vector *vec, va_list *args, t_arglist *arglist); + +int ft_case_i_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + return (ft_case_d_bonus(vec, args, arglist)); +} diff --git a/libft/ft_printf/ft_cases_easy_bonus.o b/libft/ft_printf/ft_cases_easy_bonus.o new file mode 100644 index 0000000..921ecdb Binary files /dev/null and b/libft/ft_printf/ft_cases_easy_bonus.o differ diff --git a/libft/ft_printf/ft_cases_mandatory_one.c b/libft/ft_printf/ft_cases_mandatory_one.c new file mode 100755 index 0000000..ec16fb3 --- /dev/null +++ b/libft/ft_printf/ft_cases_mandatory_one.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_cases_mandatory_one.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 18:52:37 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:52 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" + +int ft_case_c(t_vector *vec, va_list *args) +{ + if (!ft_vector_pushback(vec, (char)va_arg(*args, int))) + return (0); + return (1); +} + +int ft_case_percent(t_vector *vec) +{ + if (!ft_vector_pushback(vec, '%')) + return (0); + return (1); +} + +int ft_case_s(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = va_arg(*args, char *); + if (!str_to_cat) + { + if (!ft_vector_concat(vec, "(null)", 6)) + return (free(str_to_cat), 0); + } + else + { + str_to_cat = ft_strdup(str_to_cat); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + } + return (1); +} + +int ft_case_p(t_vector *vec, va_list *args) +{ + char *str_to_cat; + void *arg; + size_t index; + + arg = va_arg(*args, void *); + if (!arg) + { + if (!ft_vector_concat(vec, "(nil)", 5)) + return (0); + return (1); + } + if (!ft_vector_concat(vec, "0x", 2)) + return (0); + str_to_cat = ft_addr_to_strhex(arg); + if (!str_to_cat) + return (0); + index = ft_strnonchr(str_to_cat, '0'); + if (!ft_vector_concat(vec, str_to_cat + index, + ft_strlen(str_to_cat) - index)) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} + +int ft_case_u(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_utoa(va_arg(*args, unsigned int)); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} diff --git a/libft/ft_printf/ft_cases_mandatory_one.o b/libft/ft_printf/ft_cases_mandatory_one.o new file mode 100644 index 0000000..fdcfbff Binary files /dev/null and b/libft/ft_printf/ft_cases_mandatory_one.o differ diff --git a/libft/ft_printf/ft_cases_mandatory_two.c b/libft/ft_printf/ft_cases_mandatory_two.c new file mode 100755 index 0000000..927e96d --- /dev/null +++ b/libft/ft_printf/ft_cases_mandatory_two.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_cases_mandatory_two.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 18:52:33 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:58 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" + +int ft_case_x(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_utoa_base(va_arg(*args, unsigned int), "0123456789abcdef"); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} + +int ft_case_upperx(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_utoa_base(va_arg(*args, unsigned int), "0123456789ABCDEF"); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} + +int ft_case_d(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_itoa(va_arg(*args, int)); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} + +int ft_case_i(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_itoa(va_arg(*args, int)); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} diff --git a/libft/ft_printf/ft_cases_mandatory_two.o b/libft/ft_printf/ft_cases_mandatory_two.o new file mode 100644 index 0000000..d32c333 Binary files /dev/null and b/libft/ft_printf/ft_cases_mandatory_two.o differ diff --git a/libft/ft_printf/ft_padding_bonus.c b/libft/ft_printf/ft_padding_bonus.c new file mode 100755 index 0000000..073593b --- /dev/null +++ b/libft/ft_printf/ft_padding_bonus.c @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_padding_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/27 16:54:14 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:59 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +//len is the len of what's already printed +//returns the number of characters writen or -1 if an error occurs. +int padding_if_needed_before(t_arglist *arglist, +char caller, +size_t len, +t_vector *vec) +{ + char padding_char; + int i; + int padding_len; + + padding_len = arglist->width_mini - (int)len; + if (padding_len <= 0) + return (0); + if (arglist->flag_justified_left) + return (0); + if ((arglist->flag_zero == 1) && caller != 'c' && caller != 's' + && caller != 'p' && (arglist->precision < 0)) + padding_char = '0'; + else + padding_char = ' '; + i = 0; + while (i++ < padding_len) + if (!ft_vector_pushback(vec, padding_char)) + return (-1); + return (padding_len); +} + +//len is the len of what's already printed +//returns the number of characters writen or -1 if an error occurs. +int padding_if_needed_after(t_arglist *arglist, +char caller, +size_t len, +t_vector *vec) +{ + int i; + int padding_len; + + (void)caller; + padding_len = arglist->width_mini - (int)len; + if (padding_len <= 0) + return (0); + if (!(arglist->flag_justified_left)) + return (0); + i = 0; + while (i++ < padding_len) + if (!ft_vector_pushback(vec, ' ')) + return (-1); + return (padding_len); +} diff --git a/libft/ft_printf/ft_padding_bonus.o b/libft/ft_printf/ft_padding_bonus.o new file mode 100644 index 0000000..37e9b2d Binary files /dev/null and b/libft/ft_printf/ft_padding_bonus.o differ diff --git a/libft/ft_printf/ft_printf.c b/libft/ft_printf/ft_printf.c new file mode 100755 index 0000000..f7dc765 --- /dev/null +++ b/libft/ft_printf/ft_printf.c @@ -0,0 +1,126 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/21 18:24:04 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:03 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" + +int ft_case_c(t_vector *vec, va_list *args); +int ft_case_percent(t_vector *vec); +int ft_case_s(t_vector *vec, va_list *args); +int ft_case_p(t_vector *vec, va_list *args); +int ft_case_u(t_vector *vec, va_list *args); +int ft_case_x(t_vector *vec, va_list *args); +int ft_case_upperx(t_vector *vec, va_list *args); +int ft_case_d(t_vector *vec, va_list *args); +int ft_case_i(t_vector *vec, va_list *args); +int handle_percent_bonus(const char *str, t_vector *vec, va_list *args); + +//properly frees the vector and return string +void ft_cleanup(t_vector **vec, va_list *args) +{ + ft_free_vector(vec); + va_end(*args); +} + +//returns the number of characters to skip after the % sign +//or 0 if something goes wrong +int handle_percent(const char *str, t_vector *vec, va_list *args) +{ + if (str[0] == '%' && str[1] == 'c') + return (ft_case_c(vec, args)); + if (str[0] == '%' && str[1] == '%') + return (ft_case_percent(vec)); + if (str[0] == '%' && str[1] == 's') + return (ft_case_s(vec, args)); + if (str[0] == '%' && str[1] == 'p') + return (ft_case_p(vec, args)); + if (str[0] == '%' && str[1] == 'u') + return (ft_case_u(vec, args)); + if (str[0] == '%' && str[1] == 'x') + return (ft_case_x(vec, args)); + if (str[0] == '%' && str[1] == 'X') + return (ft_case_upperx(vec, args)); + if (str[0] == '%' && (str[1] == 'd')) + return (ft_case_d(vec, args)); + if (str[0] == '%' && (str[1] == 'i')) + return (ft_case_i(vec, args)); + return (handle_percent_bonus(str, vec, args)); +} + +static int ft_parsing_loop( +t_vector *return_vector, +const char *str, +va_list *args +) +{ + char *next_percent; + int nb_character; + + while (*str) + { + next_percent = ft_strchr(str, '%'); + if (!next_percent) + { + next_percent = ft_strchr(str, '\0'); + if (!ft_vector_concat(return_vector, str, (next_percent - str))) + return (0); + return (1); + } + if (!ft_vector_concat(return_vector, str, (next_percent - str))) + return (0); + str = next_percent; + nb_character = handle_percent(str, return_vector, args); + if (!nb_character) + return (0); + str += nb_character; + str++; + } + return (1); +} + +//returns the number of characters written or -1 on errors +int ft_printf(const char *str, ...) +{ + int nb_character; + t_vector *return_vector; + va_list args; + + if (!str) + return (-1); + va_start(args, str); + return_vector = ft_create_vector(2); + if (!return_vector) + return (-1); + if (!ft_parsing_loop(return_vector, str, &args)) + return (ft_cleanup(&return_vector, &args), -1); + nb_character = write(1, return_vector->buffer, return_vector->index); + return (ft_cleanup(&return_vector, &args), nb_character); +} + +//returns the number of characters written or -1 on errors +int ft_dprintf(int fd, const char *str, ...) +{ + int nb_character; + t_vector *return_vector; + va_list args; + + if (!str) + return (-1); + va_start(args, str); + return_vector = ft_create_vector(2); + if (!return_vector) + return (-1); + if (!ft_parsing_loop(return_vector, str, &args)) + return (ft_cleanup(&return_vector, &args), -1); + nb_character = write(fd, return_vector->buffer, return_vector->index); + return (ft_cleanup(&return_vector, &args), nb_character); +} diff --git a/libft/ft_printf/ft_printf.h b/libft/ft_printf/ft_printf.h new file mode 100755 index 0000000..9928f16 --- /dev/null +++ b/libft/ft_printf/ft_printf.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 12:38:59 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:20 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRINTF_H +# define FT_PRINTF_H + +# include +# include "../ft_vector.h" + +int ft_printf(const char *format, ...); +int ft_dprintf(int fd, const char *format, ...); + +#endif diff --git a/libft/ft_printf/ft_printf.o b/libft/ft_printf/ft_printf.o new file mode 100644 index 0000000..2211147 Binary files /dev/null and b/libft/ft_printf/ft_printf.o differ diff --git a/libft/ft_printf/ft_printf_bonus.c b/libft/ft_printf/ft_printf_bonus.c new file mode 100755 index 0000000..f48dee4 --- /dev/null +++ b/libft/ft_printf/ft_printf_bonus.c @@ -0,0 +1,139 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 12:55:41 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:00 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int ft_case_c_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_percent_bonus(t_vector *vec); +int ft_case_s_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_p_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_u_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_x_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_upperx_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_d_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_i_bonus(t_vector *vec, va_list *args, t_arglist *arglist); + +static int ft_handle_percent_bonus_i( +const char *str, +t_vector *vec, +va_list *args, +t_arglist *arglist) +{ + int offset; + + offset = arglist->size_of_argument_string; + if (str[0] == 'i') + { + if (ft_case_i_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + return (free(arglist), 0); +} + +static int ft_handle_percent_bonus_xd( +const char *str, +t_vector *vec, +va_list *args, +t_arglist *arglist) +{ + int offset; + + offset = arglist->size_of_argument_string; + if (str[0] == 'x') + { + if (ft_case_x_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == 'X') + { + if (ft_case_upperx_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == 'd') + { + if (ft_case_d_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + return (ft_handle_percent_bonus_i(str, vec, args, arglist)); +} + +static int ft_handle_percent_bonus_spu( +const char *str, +t_vector *vec, +va_list *args, +t_arglist *arglist) +{ + int offset; + + offset = arglist->size_of_argument_string; + if (str[0] == 's') + { + if (ft_case_s_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == 'p') + { + if (ft_case_p_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == 'u') + { + if (ft_case_u_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + return (ft_handle_percent_bonus_xd(str, vec, args, arglist)); +} + +//returns the number of characters to skip after the % sign +//or 0 if something goes wrong +int handle_percent_bonus(const char *str, t_vector *vec, va_list *args) +{ + t_arglist *arglist; + int offset; + + arglist = ft_create_arglist(str, args); + if (!arglist) + return (0); + offset = arglist->size_of_argument_string; + str += offset; + if (str[0] == 'c') + { + if (ft_case_c_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == '%') + { + if (ft_case_percent_bonus(vec)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + return (ft_handle_percent_bonus_spu(str, vec, args, arglist)); +} diff --git a/libft/ft_printf/ft_printf_bonus.h b/libft/ft_printf/ft_printf_bonus.h new file mode 100755 index 0000000..a041aec --- /dev/null +++ b/libft/ft_printf/ft_printf_bonus.h @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf_bonus.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 13:04:14 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:01 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRINTF_BONUS_H +# define FT_PRINTF_BONUS_H + +typedef struct s_arglist +{ + int width_mini; + int precision; + int flag_hashtag; + int flag_zero; + int flag_justified_left; + int flag_space; + int flag_plus; + int size_of_argument_string; +} t_arglist; + +t_arglist *ft_create_arglist(const char *str, va_list *args); + +#endif \ No newline at end of file diff --git a/libft/ft_printf/ft_printf_bonus.o b/libft/ft_printf/ft_printf_bonus.o new file mode 100644 index 0000000..b73bc52 Binary files /dev/null and b/libft/ft_printf/ft_printf_bonus.o differ diff --git a/libft/ft_printf/libft.h b/libft/ft_printf/libft.h new file mode 100755 index 0000000..7805aa4 --- /dev/null +++ b/libft/ft_printf/libft.h @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* libft.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 12:38:59 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:22 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LIBFT_H +# define LIBFT_H + +# include +# include +# include + +int ft_isalpha(int c); +int ft_isdigit(int c); +int ft_isalnum(int c); +int ft_isascii(int c); +int ft_isprint(int c); +size_t ft_strlen(const char *s); +void *ft_memset(void *s, int c, size_t n); +void ft_bzero(void *s, size_t n); +void *ft_memcpy(void *dest, const void *src, size_t n); +void *ft_memmove(void *dest, const void *src, size_t n); +size_t ft_strlcpy(char *dst, const char *src, size_t size); +size_t ft_strlcat(char *dst, const char *src, size_t size); +int ft_toupper(int c); +int ft_tolower(int c); +char *ft_strchr(const char *s, int c); +char *ft_strrchr(const char *s, int c); +int ft_strncmp(const char *s1, const char *s2, size_t n); +void *ft_memchr(const void *s, int c, size_t n); +int ft_memcmp(const void *s1, const void *s2, size_t n); +char *ft_strnstr(const char *big, const char *little, size_t len); +int ft_atoi(const char *nptr); +char *ft_strdup(const char *s); +char *ft_itoa(int n); +char *ft_itoa_base(int nbr, char *base); +char *ft_addr_to_strhex(void *addr); +char *ft_utoa(unsigned int n); +char *ft_utoa_base(unsigned int nbr, char *base); +size_t ft_strnonchr(char *str, char c); + +#endif \ No newline at end of file diff --git a/libft/ft_priority_queue.h b/libft/ft_priority_queue.h new file mode 100755 index 0000000..9b7047b --- /dev/null +++ b/libft/ft_priority_queue.h @@ -0,0 +1,47 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_priority_queue.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 14:51:31 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:58 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRIORITY_QUEUE_H +# define FT_PRIORITY_QUEUE_H + +# include "libft.h" + +typedef struct s_priority_queue_node +{ + void *data; + size_t priority; +} t_priority_queue_node; + +typedef struct s_priority_queue +{ + t_priority_queue_node *nodes; + size_t size; + size_t capacity; + int (*compare)(void *, void *); +} t_priority_queue; + +void ft_insert_pq( + t_priority_queue *pq, + void *data, + size_t priority); + +t_priority_queue *create_priority_queue( + int capacity, + int (*compare)(void *, void *)); + +void *peek(t_priority_queue *pq); + +void *dequeue(t_priority_queue *pq); + +void free_pq(t_priority_queue *pq); + +#endif \ No newline at end of file diff --git a/libft/ft_priority_queue/ft_priority_queue.c b/libft/ft_priority_queue/ft_priority_queue.c new file mode 100755 index 0000000..97b2f54 --- /dev/null +++ b/libft/ft_priority_queue/ft_priority_queue.c @@ -0,0 +1,71 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_priority_queue.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 14:51:23 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:06 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_priority_queue_private.h" + +void ft_insert_pq(t_priority_queue *pq, void *data, size_t priority) +{ + t_priority_queue_node new_node; + + if (pq->size >= pq->capacity) + ft_resize_pq(pq); + new_node.data = data; + new_node.priority = priority; + pq->nodes[pq->size] = new_node; + pq->size++; + heapify_up(pq, pq->size - 1); +} + +t_priority_queue *create_priority_queue( +int capacity, +int (*compare)(void *, void *)) +{ + t_priority_queue *pq; + + pq = malloc(sizeof(t_priority_queue)); + if (!pq) + return (NULL); + pq->nodes = malloc(capacity * sizeof(t_priority_queue_node)); + if (!pq->nodes) + return (free(pq), NULL); + pq->size = 0; + pq->capacity = capacity; + pq->compare = compare; + return (pq); +} + +void *peek(t_priority_queue *pq) +{ + if (pq->size == 0) + return (NULL); + return (pq->nodes[0].data); +} + +void *dequeue(t_priority_queue *pq) +{ + void *ret; + + if (pq->size == 0) + return (NULL); + ret = pq->nodes[0].data; + pq->nodes[0] = pq->nodes[pq->size - 1]; + pq->size--; + heapify_down(pq, 0); + ft_shrink_pq(pq); + return (ret); +} + +void free_pq(t_priority_queue *pq) +{ + free(pq->nodes); + free(pq); +} diff --git a/libft/ft_priority_queue/ft_priority_queue.o b/libft/ft_priority_queue/ft_priority_queue.o new file mode 100644 index 0000000..3fc001f Binary files /dev/null and b/libft/ft_priority_queue/ft_priority_queue.o differ diff --git a/libft/ft_priority_queue/ft_priority_queue_private.h b/libft/ft_priority_queue/ft_priority_queue_private.h new file mode 100755 index 0000000..122495e --- /dev/null +++ b/libft/ft_priority_queue/ft_priority_queue_private.h @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_priority_queue_private.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 16:41:11 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:08 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRIORITY_QUEUE_PRIVATE_H +# define FT_PRIORITY_QUEUE_PRIVATE_H + +# include "../ft_priority_queue.h" + +void heapify_up(t_priority_queue *pq, size_t index); + +void heapify_down(t_priority_queue *pq, size_t index); + +void ft_resize_pq(t_priority_queue *pq); + +void ft_shrink_pq(t_priority_queue *pq); + +#endif \ No newline at end of file diff --git a/libft/ft_priority_queue/ft_priority_queue_utils.c b/libft/ft_priority_queue/ft_priority_queue_utils.c new file mode 100755 index 0000000..c51e00f --- /dev/null +++ b/libft/ft_priority_queue/ft_priority_queue_utils.c @@ -0,0 +1,118 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_priority_queue_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 16:00:58 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:01 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_priority_queue_private.h" +#include "../ft_printf/ft_printf.h" + +static inline void pq_swap(t_priority_queue_node *a, t_priority_queue_node *b) +{ + t_priority_queue_node temp; + + temp = *a; + *a = *b; + *b = temp; +} + +void heapify_up(t_priority_queue *pq, size_t index) +{ + size_t parent; + + while (index > 0) + { + parent = (index - 1) / 2; + if (pq->nodes[index].priority < pq->nodes[parent].priority) + { + pq_swap(&pq->nodes[index], &pq->nodes[parent]); + index = parent; + } + else if (pq->nodes[index].priority == pq->nodes[parent].priority + && pq->compare(pq->nodes[index].data, pq->nodes[parent].data) < 0) + { + pq_swap(&pq->nodes[index], &pq->nodes[parent]); + index = parent; + } + else + { + break ; + } + } +} + +void heapify_down(t_priority_queue *pq, size_t index) +{ + size_t smallest; + size_t left; + size_t right; + + smallest = index; + left = 2 * index + 1; + right = 2 * index + 2; + if (left < pq->size + && ((pq->nodes[left].priority < pq->nodes[smallest].priority) + || (pq->compare(pq->nodes[left].data, + pq->nodes[smallest].data) < 0))) + smallest = left; + if (right < pq->size + && ((pq->nodes[right].priority < pq->nodes[smallest].priority) + || (pq->compare(pq->nodes[right].data, + pq->nodes[smallest].data) < 0))) + smallest = right; + if (smallest != index) + { + pq_swap(&pq->nodes[index], &pq->nodes[smallest]); + heapify_down(pq, smallest); + } +} + +void ft_resize_pq(t_priority_queue *pq) +{ + size_t new_capacity; + t_priority_queue_node *new_nodes; + size_t i; + + new_capacity = pq->capacity * 2; + new_nodes = malloc(new_capacity * sizeof(t_priority_queue_node)); + if (!new_nodes) + return ; + i = 0; + while (i < pq->size) + { + new_nodes[i] = pq->nodes[i]; + i++; + } + free(pq->nodes); + pq->nodes = new_nodes; + pq->capacity = new_capacity; +} + +void ft_shrink_pq(t_priority_queue *pq) +{ + size_t new_capacity; + t_priority_queue_node *new_nodes; + size_t i; + + if (pq->size >= pq->capacity / 4 || pq->capacity <= 4) + return ; + new_capacity = pq->capacity / 2; + new_nodes = malloc(new_capacity * sizeof(t_priority_queue_node)); + if (!new_nodes) + return ; + i = 0; + while (i < pq->size) + { + new_nodes[i] = pq->nodes[i]; + i++; + } + free(pq->nodes); + pq->nodes = new_nodes; + pq->capacity = new_capacity; +} diff --git a/libft/ft_priority_queue/ft_priority_queue_utils.o b/libft/ft_priority_queue/ft_priority_queue_utils.o new file mode 100644 index 0000000..8e7d69e Binary files /dev/null and b/libft/ft_priority_queue/ft_priority_queue_utils.o differ diff --git a/libft/ft_putchar_fd.c b/libft/ft_putchar_fd.c new file mode 100755 index 0000000..7f3b443 --- /dev/null +++ b/libft/ft_putchar_fd.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putchar_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 17:16:09 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:19 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_putchar_fd(char c, int fd) +{ + write(fd, &c, 1); +} diff --git a/libft/ft_putchar_fd.o b/libft/ft_putchar_fd.o new file mode 100644 index 0000000..07b07b6 Binary files /dev/null and b/libft/ft_putchar_fd.o differ diff --git a/libft/ft_putendl_fd.c b/libft/ft_putendl_fd.c new file mode 100755 index 0000000..a7cf3d6 --- /dev/null +++ b/libft/ft_putendl_fd.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putendl_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 17:37:39 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:21 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_putendl_fd(char *s, int fd) +{ + ft_putstr_fd(s, fd); + ft_putchar_fd('\n', fd); +} diff --git a/libft/ft_putendl_fd.o b/libft/ft_putendl_fd.o new file mode 100644 index 0000000..ac9620b Binary files /dev/null and b/libft/ft_putendl_fd.o differ diff --git a/libft/ft_putnbr_fd.c b/libft/ft_putnbr_fd.c new file mode 100755 index 0000000..1e843ef --- /dev/null +++ b/libft/ft_putnbr_fd.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putnbr_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 17:44:20 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:23 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static unsigned int ft_abs(int a) +{ + if (a < 0) + return (-a); + return (a); +} + +void ft_putnbr_fd(int n, int fd) +{ + if (n < 0) + ft_putchar_fd('-', fd); + if (ft_abs(n) < 10) + ft_putchar_fd(ft_abs(n) + '0', fd); + else + { + ft_putnbr_fd(ft_abs(n / 10), fd); + ft_putnbr_fd(ft_abs(n % 10), fd); + } +} diff --git a/libft/ft_putnbr_fd.o b/libft/ft_putnbr_fd.o new file mode 100644 index 0000000..41a714c Binary files /dev/null and b/libft/ft_putnbr_fd.o differ diff --git a/libft/ft_putstr_fd.c b/libft/ft_putstr_fd.c new file mode 100755 index 0000000..b2861d5 --- /dev/null +++ b/libft/ft_putstr_fd.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putstr_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 17:31:53 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:24 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or new are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_putstr_fd(char *s, int fd) +{ + size_t len; + + if (!s) + return ; + len = ft_strlen(s); + write(fd, s, len); +} diff --git a/libft/ft_putstr_fd.o b/libft/ft_putstr_fd.o new file mode 100644 index 0000000..8018e8e Binary files /dev/null and b/libft/ft_putstr_fd.o differ diff --git a/libft/ft_safe_int_math.c b/libft/ft_safe_int_math.c new file mode 100644 index 0000000..454bb63 --- /dev/null +++ b/libft/ft_safe_int_math.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_safe_int_math.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/08 11:11:17 by alier #+# #+# */ +/* Updated: 2025/02/16 19:04:25 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +int safe_int_add(int a, int b) +{ + if (b >= 0 && a > INT_MAX - b) + { + errno = ERANGE; + return (INT_MAX); + } + else if (b < 0 && a < INT_MIN - b) + { + errno = ERANGE; + return (INT_MIN); + } + return (a + b); +} + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +int safe_int_sub(int a, int b) +{ + if (b >= 0 && a < INT_MIN + b) + { + errno = ERANGE; + return (INT_MIN); + } + else if (b < 0 && a > INT_MAX + b) + { + errno = ERANGE; + return (INT_MAX); + } + return (a - b); +} + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +int safe_int_mul(int a, int b) +{ + if (b > 0) + { + if (a > 0 && a > INT_MAX / b) + return (errno = ERANGE, INT_MAX); + else if (a < 0 && a < INT_MIN / b) + return (errno = ERANGE, INT_MIN); + } + else if (b < 0) + { + if (a < 0 && a < INT_MAX / b) + return (errno = ERANGE, INT_MAX); + else if ((-INT_MAX > INT_MIN && b < -1) && a > INT_MIN / b) + return (errno = ERANGE, INT_MIN); + } + return (a * b); +} diff --git a/libft/ft_safe_int_math.o b/libft/ft_safe_int_math.o new file mode 100644 index 0000000..6b5a803 Binary files /dev/null and b/libft/ft_safe_int_math.o differ diff --git a/libft/ft_safe_long_math.c b/libft/ft_safe_long_math.c new file mode 100644 index 0000000..159085f --- /dev/null +++ b/libft/ft_safe_long_math.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_safe_long_math.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/08 11:11:17 by alier #+# #+# */ +/* Updated: 2025/02/16 19:04:26 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +long safe_long_add(long a, long b) +{ + if (b >= 0 && a > LONG_MAX - b) + { + errno = ERANGE; + return (LONG_MAX); + } + else if (b < 0 && a < LONG_MIN - b) + { + errno = ERANGE; + return (LONG_MIN); + } + return (a + b); +} + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +long safe_long_sub(long a, long b) +{ + if (b >= 0 && a < LONG_MIN + b) + { + errno = ERANGE; + return (LONG_MIN); + } + else if (b < 0 && a > LONG_MAX + b) + { + errno = ERANGE; + return (LONG_MAX); + } + return (a - b); +} + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +long safe_long_mul(long a, long b) +{ + if (b > 0) + { + if (a > 0 && a > LONG_MAX / b) + return (errno = ERANGE, LONG_MAX); + else if (a < 0 && a < LONG_MIN / b) + return (errno = ERANGE, LONG_MIN); + } + else if (b < 0) + { + if (a < 0 && a < LONG_MAX / b) + return (errno = ERANGE, LONG_MAX); + else if ((-LONG_MAX > LONG_MIN && b < -1) && a > LONG_MIN / b) + return (errno = ERANGE, LONG_MIN); + } + return (a * b); +} diff --git a/libft/ft_safe_long_math.o b/libft/ft_safe_long_math.o new file mode 100644 index 0000000..a9d8a47 Binary files /dev/null and b/libft/ft_safe_long_math.o differ diff --git a/libft/ft_split.c b/libft/ft_split.c new file mode 100755 index 0000000..e8316f9 --- /dev/null +++ b/libft/ft_split.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_split.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 14:22:44 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:27 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static int free_if_failed(char **split, int index) +{ + int i; + + if (index < 0) + return (0); + if (!split) + return (1); + if (split[index]) + return (0); + i = 0; + while (split[i]) + { + free(split[i]); + i++; + } + free(split); + return (1); +} + +static int ft_count_str(const char *str, char c) +{ + int count; + int i; + int sub_str_start; + + i = 0; + count = 0; + sub_str_start = 0; + while (str[i]) + { + while (str[i] && (str[i] == c)) + i++; + sub_str_start = i; + while (str[i] && (str[i] != c)) + i++; + if (sub_str_start < i) + count++; + } + return (count); +} + +static char *ft_str_dup_range(const char *str, int start_index, int end_index) +{ + char *dup; + int i; + + dup = malloc(sizeof(char) * (end_index - start_index + 1)); + if (!dup) + return (0); + i = 0; + while (i < (end_index - start_index)) + { + dup[i] = str[start_index + i]; + i++; + } + dup[i] = '\0'; + return (dup); +} + +static void init_to_zero(int *sub_str_start, int *index_str, int *i) +{ + *sub_str_start = 0; + *index_str = 0; + *i = 0; +} + +//returns NULL if s is NULL or if any allocation fails +char **ft_split(char const *s, char c) +{ + char **tab; + int sub_str_start; + int index_str; + int i; + + if (!s) + return (NULL); + init_to_zero(&sub_str_start, &index_str, &i); + tab = malloc(sizeof(char *) * (ft_count_str(s, c) + 1)); + if (!tab) + return (NULL); + while (s[i]) + { + while (s[i] && (s[i] == c)) + i++; + sub_str_start = i; + while (s[i] && (s[i] != c)) + i++; + if (sub_str_start < i) + tab[index_str++] = ft_str_dup_range(s, sub_str_start, i); + if (free_if_failed(tab, index_str - 1)) + return (NULL); + } + tab[index_str] = 0; + return (tab); +} diff --git a/libft/ft_split.o b/libft/ft_split.o new file mode 100644 index 0000000..c3a43d3 Binary files /dev/null and b/libft/ft_split.o differ diff --git a/libft/ft_split2.c b/libft/ft_split2.c new file mode 100644 index 0000000..be33c1f --- /dev/null +++ b/libft/ft_split2.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_split2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/12/09 15:37:07 by alier #+# #+# */ +/* Updated: 2025/02/16 19:04:33 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include + +/* + * Free all strings duplicated by split and the pointer array itself. + * Does nothing if strs is NULL. + */ +void ft_free_split(char **strs) +{ + size_t i; + + if (strs == NULL) + return ; + i = 0; + while (strs[i] != NULL) + { + free(strs[i]); + i++; + } + free(strs); +} + +size_t ft_split_size(char **strs) +{ + size_t i; + + i = 0; + while (strs[i] != NULL) + i++; + return (i); +} diff --git a/libft/ft_split2.o b/libft/ft_split2.o new file mode 100644 index 0000000..27c56ba Binary files /dev/null and b/libft/ft_split2.o differ diff --git a/libft/ft_strchr.c b/libft/ft_strchr.c new file mode 100755 index 0000000..1ef18dd --- /dev/null +++ b/libft/ft_strchr.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:59:05 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:40 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns the index of the first character c of the string +// /!\SEGFAULT if str is NULL +//returns ft_strlen(s) if c is \0 +char *ft_strchr(const char *s, int c) +{ + if ((char)c == '\0') + return ((char *)(s + ft_strlen(s))); + while (*s) + { + if (*s == (char)c) + return ((char *) s); + s++; + } + return (NULL); +} diff --git a/libft/ft_strchr.o b/libft/ft_strchr.o new file mode 100644 index 0000000..cb455a6 Binary files /dev/null and b/libft/ft_strchr.o differ diff --git a/libft/ft_strcmp.c b/libft/ft_strcmp.c new file mode 100755 index 0000000..52be37f --- /dev/null +++ b/libft/ft_strcmp.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strcmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/08 13:50:48 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:42 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strcmp(const char *s1, const char *s2) +{ + while (*s1 && (*s1 == *s2)) + { + s1++; + s2++; + } + return ((const unsigned char)*s1 - (const unsigned char)*s2); +} diff --git a/libft/ft_strcmp.o b/libft/ft_strcmp.o new file mode 100644 index 0000000..be2f475 Binary files /dev/null and b/libft/ft_strcmp.o differ diff --git a/libft/ft_strdup.c b/libft/ft_strdup.c new file mode 100755 index 0000000..cac2557 --- /dev/null +++ b/libft/ft_strdup.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strdup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 18:57:34 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:44 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strdup(const char *s) +{ + char *dup_str; + size_t size; + + if (!s) + return (NULL); + size = (ft_strlen(s) + 1); + dup_str = malloc(sizeof(char) * size); + if (!dup_str) + return (0); + return (ft_memcpy(dup_str, s, size)); +} diff --git a/libft/ft_strdup.o b/libft/ft_strdup.o new file mode 100644 index 0000000..bf06f4d Binary files /dev/null and b/libft/ft_strdup.o differ diff --git a/libft/ft_striteri.c b/libft/ft_striteri.c new file mode 100755 index 0000000..73ca44b --- /dev/null +++ b/libft/ft_striteri.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_striteri.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 16:56:31 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:45 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if s or f are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_striteri(char *s, void (*f)(unsigned int, char*)) +{ + unsigned int i; + + if (!s || !f) + return ; + i = 0; + while (s[i]) + { + f(i, &s[i]); + i++; + } +} diff --git a/libft/ft_striteri.o b/libft/ft_striteri.o new file mode 100644 index 0000000..87a31f2 Binary files /dev/null and b/libft/ft_striteri.o differ diff --git a/libft/ft_strjoin.c b/libft/ft_strjoin.c new file mode 100755 index 0000000..972f6f2 --- /dev/null +++ b/libft/ft_strjoin.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strjoin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 12:14:45 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:47 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns NULL if any argument is null or if an allocation fails +char *ft_strjoin(char const *s1, char const *s2) +{ + char *ret; + int i; + int j; + + if (!s1 || !s2) + return (NULL); + ret = malloc(sizeof(char) * (ft_strlen(s1) + ft_strlen(s2) + 1)); + if (!ret) + return (NULL); + i = 0; + while (s1[i]) + { + ret[i] = s1[i]; + i++; + } + j = 0; + while (s2[j]) + { + ret[i] = s2[j]; + i++; + j++; + } + ret[i] = '\0'; + return (ret); +} diff --git a/libft/ft_strjoin.o b/libft/ft_strjoin.o new file mode 100644 index 0000000..28d80c0 Binary files /dev/null and b/libft/ft_strjoin.o differ diff --git a/libft/ft_strlcat.c b/libft/ft_strlcat.c new file mode 100755 index 0000000..908e023 --- /dev/null +++ b/libft/ft_strlcat.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlcat.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:24:30 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:48 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlcat(char *dst, const char *src, size_t size) +{ + size_t dest_len; + size_t src_len; + + dest_len = ft_strlen(dst); + src_len = ft_strlen(src); + if (size <= dest_len) + return (size + src_len); + ft_strlcpy(&dst[dest_len], src, (size - dest_len)); + return (dest_len + src_len); +} diff --git a/libft/ft_strlcat.o b/libft/ft_strlcat.o new file mode 100644 index 0000000..d2c8c20 Binary files /dev/null and b/libft/ft_strlcat.o differ diff --git a/libft/ft_strlcpy.c b/libft/ft_strlcpy.c new file mode 100755 index 0000000..ab4245f --- /dev/null +++ b/libft/ft_strlcpy.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:13:17 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:51 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlcpy(char *dst, const char *src, size_t size) +{ + size_t i; + + i = 0; + if (size == 0) + return (ft_strlen(src)); + while ((*src != '\0') && (i < size - 1)) + { + *dst = *src; + i++; + dst++; + src++; + } + while (*src != '\0') + { + i++; + src++; + } + *dst = '\0'; + return (i); +} diff --git a/libft/ft_strlcpy.o b/libft/ft_strlcpy.o new file mode 100644 index 0000000..6fbd8c4 Binary files /dev/null and b/libft/ft_strlcpy.o differ diff --git a/libft/ft_strlen.c b/libft/ft_strlen.c new file mode 100755 index 0000000..36ca40d --- /dev/null +++ b/libft/ft_strlen.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:19:29 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:52 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlen(const char *s) +{ + size_t i; + + i = 0; + while (s[i]) + i++; + return (i); +} diff --git a/libft/ft_strlen.o b/libft/ft_strlen.o new file mode 100644 index 0000000..7822701 Binary files /dev/null and b/libft/ft_strlen.o differ diff --git a/libft/ft_strmapi.c b/libft/ft_strmapi.c new file mode 100755 index 0000000..36bb825 --- /dev/null +++ b/libft/ft_strmapi.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strmapi.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 16:38:47 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:54 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//I don't know if I have to apply the function to the ending null char... +//return NULL if any argument is NULL or if any allocation fails +char *ft_strmapi(char const *s, char (*f)(unsigned int, char)) +{ + char *ret; + unsigned int i; + + if (!s || !f) + return (NULL); + ret = malloc(sizeof(char) * (ft_strlen(s) + 1)); + if (!ret) + return (NULL); + i = 0; + while (s[i]) + { + ret[i] = f(i, s[i]); + i++; + } + ret[i] = '\0'; + return (ret); +} diff --git a/libft/ft_strmapi.o b/libft/ft_strmapi.o new file mode 100644 index 0000000..9b3580f Binary files /dev/null and b/libft/ft_strmapi.o differ diff --git a/libft/ft_strncmp.c b/libft/ft_strncmp.c new file mode 100755 index 0000000..9ffd1b4 --- /dev/null +++ b/libft/ft_strncmp.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strncmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:12:52 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:55 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strncmp(const char *s1, const char *s2, size_t n) +{ + while (n && *s1 && (*s1 == *s2)) + { + s1++; + s2++; + n--; + } + if (n == 0) + return (0); + return ((const unsigned char)*s1 - (const unsigned char)*s2); +} diff --git a/libft/ft_strncmp.o b/libft/ft_strncmp.o new file mode 100644 index 0000000..0e082da Binary files /dev/null and b/libft/ft_strncmp.o differ diff --git a/libft/ft_strnonchr.c b/libft/ft_strnonchr.c new file mode 100755 index 0000000..9c9abdb --- /dev/null +++ b/libft/ft_strnonchr.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strnonchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 18:39:17 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:56 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns the index of the first character that ISN'T c +// /!\SEGFAULT if str is NULL +//returns 0 if c is \0 +size_t ft_strnonchr(char *str, char c) +{ + size_t i; + + i = 0; + if (c == '\0') + return (0); + while (str[i] == c) + i++; + return (i); +} diff --git a/libft/ft_strnonchr.o b/libft/ft_strnonchr.o new file mode 100644 index 0000000..6f1bc8b Binary files /dev/null and b/libft/ft_strnonchr.o differ diff --git a/libft/ft_strnstr.c b/libft/ft_strnstr.c new file mode 100755 index 0000000..50bc7ec --- /dev/null +++ b/libft/ft_strnstr.c @@ -0,0 +1,91 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strnstr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:50:28 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:13 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strnstr(const char *big, const char *little, size_t len) +{ + size_t i; + size_t j; + + if (*little == '\0') + return ((char *)big); + i = 0; + while (big[i] != '\0' && i < len) + { + j = 0; + while (little[j] != '\0' && big[i + j] == little[j] && (i + j) < len) + j++; + if (little[j] == '\0') + return ((char *)big + i); + i++; + } + return (NULL); +} + +int ft_strhassuffix(const char *s, const char *suffix) +{ + size_t i; + size_t j; + + i = ft_strlen(s); + j = ft_strlen(suffix); + if (i == 0 || j == 0) + return (0); + i--; + j--; + while (i > 0 && j > 0) + { + if (s[i] != suffix[j]) + return (0); + i--; + j--; + } + return (1); +} + +/* + * Same as ft_strcmp() but ignores eventual `\n` in the + * comparison. + */ +int ft_linecmp(const char *s1, const char *s2) +{ + size_t i; + const unsigned char *a; + const unsigned char *b; + + i = 0; + a = (const unsigned char *) s1; + b = (const unsigned char *) s2; + while (1) + { + if ((a[i] == '\n' && b[i] == '\0') + || (a[i] == '\0' && b[i] == '\n')) + break ; + if (a[i] != b[i]) + return (a[i] - b[i]); + if (a[i] == '\0') + break ; + i++; + } + return (0); +} + +size_t ft_linelen(const char *line) +{ + size_t i; + + i = 0; + while (line[i] != '\0' && line[i] != '\n') + i++; + return (i); +} diff --git a/libft/ft_strnstr.o b/libft/ft_strnstr.o new file mode 100644 index 0000000..9a10919 Binary files /dev/null and b/libft/ft_strnstr.o differ diff --git a/libft/ft_strrchr.c b/libft/ft_strrchr.c new file mode 100755 index 0000000..9c293ad --- /dev/null +++ b/libft/ft_strrchr.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strrchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:05:03 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:17 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strrchr(const char *s, int c) +{ + char *last_occurence; + + if ((char)c == '\0') + return ((char *)(s + ft_strlen(s))); + last_occurence = NULL; + while (*s) + { + if (*s == (char)c) + last_occurence = (char *)s; + s++; + } + return (last_occurence); +} diff --git a/libft/ft_strrchr.o b/libft/ft_strrchr.o new file mode 100644 index 0000000..8d3e977 Binary files /dev/null and b/libft/ft_strrchr.o differ diff --git a/libft/ft_strtrim.c b/libft/ft_strtrim.c new file mode 100755 index 0000000..31d5002 --- /dev/null +++ b/libft/ft_strtrim.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strtrim.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 12:44:26 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:20 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static size_t ft_str_size(char const *s1, char usedchar[256]) +{ + size_t size; + size_t index; + + size = 0; + index = 0; + while (*s1) + { + while (usedchar[((int)*s1) + 128]) + { + s1++; + index++; + } + if (*s1) + { + s1++; + index++; + size = index; + } + } + return (size); +} + +//returns NULL if any argument is null or if an allocation fails +char *ft_strtrim(char const *s1, char const *set) +{ + char *ret; + char usedchar[256]; + int start_index; + size_t size; + + if (!set || !s1) + return (NULL); + if (!*set) + return (ft_strdup(s1)); + ft_bzero(usedchar, 256); + while (*set) + usedchar[((int)*set++) + 128] = 1; + start_index = 0; + while (usedchar[((int)s1[start_index]) + 128]) + start_index++; + if (!s1[start_index]) + return (ft_strdup("")); + size = ft_str_size(&s1[start_index], usedchar); + ret = malloc(sizeof(char) * (size + 1)); + if (!ret) + return (NULL); + ft_strlcpy(ret, &s1[start_index], (size + 1)); + return (ret); +} diff --git a/libft/ft_strtrim.o b/libft/ft_strtrim.o new file mode 100644 index 0000000..e3e0f2d Binary files /dev/null and b/libft/ft_strtrim.o differ diff --git a/libft/ft_substr.c b/libft/ft_substr.c new file mode 100755 index 0000000..acb9dd3 --- /dev/null +++ b/libft/ft_substr.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_substr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 11:27:50 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:22 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static void ft_memcpy_with_nullchar(char *substring, char const *s, size_t len) +{ + ft_memcpy(substring, s, len); + substring[len] = '\0'; +} + +//check for out of bound access and return NULL if s is NULL or allocation fails +//len 0 or out of bound start just returns a null character +char *ft_substr(char const *s, unsigned int start, size_t len) +{ + char *substring; + size_t slen; + + if (!s) + return (NULL); + slen = ft_strlen(s); + if (slen <= start) + return (ft_strdup("")); + s = &s[start]; + slen -= start; + if (slen > len) + substring = malloc(sizeof(char) * (len + 1)); + else + substring = malloc(sizeof(char) * (slen + 1)); + if (!substring) + return (NULL); + if (slen > len) + ft_memcpy_with_nullchar(substring, s, len); + else + ft_memcpy_with_nullchar(substring, s, slen); + return (substring); +} diff --git a/libft/ft_substr.o b/libft/ft_substr.o new file mode 100644 index 0000000..da5d69b Binary files /dev/null and b/libft/ft_substr.o differ diff --git a/libft/ft_tolower.c b/libft/ft_tolower.c new file mode 100755 index 0000000..1958947 --- /dev/null +++ b/libft/ft_tolower.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_tolower.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:44:42 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:25 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + return (c + 32); + return (c); +} diff --git a/libft/ft_tolower.o b/libft/ft_tolower.o new file mode 100644 index 0000000..c2fbbaa Binary files /dev/null and b/libft/ft_tolower.o differ diff --git a/libft/ft_toupper.c b/libft/ft_toupper.c new file mode 100755 index 0000000..a1417dd --- /dev/null +++ b/libft/ft_toupper.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_toupper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:43:04 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:27 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + return (c - 32); + return (c); +} diff --git a/libft/ft_toupper.o b/libft/ft_toupper.o new file mode 100644 index 0000000..e74e84a Binary files /dev/null and b/libft/ft_toupper.o differ diff --git a/libft/ft_utoa.c b/libft/ft_utoa.c new file mode 100755 index 0000000..83397b5 --- /dev/null +++ b/libft/ft_utoa.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_utoa.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 17:36:09 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:38 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static size_t nb_digits(unsigned int n) +{ + size_t i; + + i = 0; + while (n > 0) + { + i++; + n /= 10; + } + return (i); +} + +static void recursive_utoa(unsigned int n, char *ret, size_t *index) +{ + if (n > 9) + recursive_utoa(n / 10, ret, index); + ret[(*index)++] = (n % 10) + '0'; +} + +//converts an unsigned int to a string, returns NULL if an allocation fails +//works for any size of unsigned int (future-proof) +char *ft_utoa(unsigned int n) +{ + char *ret; + size_t index; + + if (n == 0) + return (ft_strdup("0")); + ret = malloc(sizeof(char) * (nb_digits(n) + 1)); + if (!ret) + return (NULL); + index = 0; + recursive_utoa(n, ret, &index); + ret[index] = '\0'; + return (ret); +} diff --git a/libft/ft_utoa.o b/libft/ft_utoa.o new file mode 100644 index 0000000..0b696eb Binary files /dev/null and b/libft/ft_utoa.o differ diff --git a/libft/ft_utoa_base.c b/libft/ft_utoa_base.c new file mode 100755 index 0000000..def8dd4 --- /dev/null +++ b/libft/ft_utoa_base.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_utoa_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 13:59:32 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:36 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "ft_vector.h" + +static int ft_is_sign(char c) +{ + if (c == '-' || c == '+') + return (1); + else + return (0); +} + +//converts nbr into a known to be valid base, then append it to vec +//returns 0 if the concatenation fails, or 1 if everything goes well +static int ft_put_ok_base( +unsigned int nbr, +char *base, +size_t base_lenght, +t_vector *vec) +{ + char buffer[32]; + int i; + + i = 31; + if (nbr == 0) + if (!ft_vector_pushback(vec, base[0])) + return (0); + while (nbr > 0) + { + buffer[i] = base[nbr % base_lenght]; + nbr /= base_lenght; + i--; + } + if (!ft_vector_concat(vec, (buffer + i + 1), (31 - i))) + return (0); + return (1); +} + +//returns 1 if the base is valid, and 0 if it's not +static int ft_is_ok_base(char *base) +{ + char used_characters[128]; + size_t i; + + i = 0; + ft_bzero(used_characters, 128); + while (base[i] != '\0') + { + if (used_characters[(int) base[i]] == 0) + used_characters[(int) base[i]]++; + else + return (0); + if (ft_is_sign(base[i])) + return (0); + i++; + } + if (i < 2) + return (0); + return (1); +} + +//returns a standard C string of nbr converted in the "base" base +//base have to only cointain ascii characters +//returns NULL if the base is invalid or if an allocation failed +char *ft_utoa_base(unsigned int unsigned_nbr, char *base) +{ + t_vector *ret; + char *ret_str; + + ret = ft_create_vector(2); + if (!ret) + return (NULL); + if (!ft_is_ok_base(base)) + return (ft_free_vector(&ret), NULL); + if (!ft_put_ok_base(unsigned_nbr, base, ft_strlen(base), ret)) + return (ft_free_vector(&ret), NULL); + ret_str = ft_vtoc(ret); + ft_free_vector(&ret); + if (!ret_str) + return (NULL); + return (ret_str); +} diff --git a/libft/ft_utoa_base.o b/libft/ft_utoa_base.o new file mode 100644 index 0000000..054f9cd Binary files /dev/null and b/libft/ft_utoa_base.o differ diff --git a/libft/ft_vecint.c b/libft/ft_vecint.c new file mode 100755 index 0000000..53c0df5 --- /dev/null +++ b/libft/ft_vecint.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vecint.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/18 11:14:16 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:45 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_vecint.h" +#include "libft.h" + +//creates a vector of initial size size +//returns its address, or NULL if any allocations fails +t_vecint *ft_create_vecint(size_t size) +{ + t_vecint *ret; + + ret = malloc(sizeof(t_vecint)); + if (!ret) + return (NULL); + ret->buffer = malloc(sizeof(int) * size); + if (!ret->buffer) + { + free(ret); + return (NULL); + } + ret->index = 0; + ret->size = size; + ret->finished = 0; + return (ret); +} + +//append c to the vector dest +//returns NULL if the allocation fail and the adress of dest if all goes well +t_vecint *ft_vecint_pushback(t_vecint *dest, int c) +{ + int *buff; + + if (dest->index >= dest->size) + { + buff = malloc(sizeof(int) * ((dest->size + 1) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, (dest->index * sizeof(int))); + dest->size = (dest->size + 1) * 2; + free(dest->buffer); + dest->buffer = buff; + } + dest->buffer[dest->index] = c; + dest->index++; + return (dest); +} + +//append size ints (NOT BYTES) at src to the vector dest +//returns NULL if the allocation fail and the adress of dest if all goes well +//returns NULL if dest or src is NULL without doing anything +t_vecint *ft_vecint_concat(t_vecint *dest, const void *src, size_t size) +{ + int *buff; + + if (!dest || !src) + return (NULL); + if ((dest->index + size) >= dest->size) + { + buff = malloc(sizeof(int) * ((dest->size + size) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, (dest->index * sizeof(int))); + dest->size = (dest->size + size) * 2; + free(dest->buffer); + dest->buffer = buff; + } + ft_memcpy(dest->buffer + dest->index, src, (size * sizeof(int))); + dest->index += size; + return (dest); +} + +//frees vec and all its members, sets vec to NULL and returns NULL +void ft_free_vecint(t_vecint **vec) +{ + if (!vec) + return ; + if (!(*vec)) + return ; + if ((*vec)->buffer) + free((*vec)->buffer); + free(*vec); + *vec = NULL; +} diff --git a/libft/ft_vecint.h b/libft/ft_vecint.h new file mode 100755 index 0000000..6873dde --- /dev/null +++ b/libft/ft_vecint.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vecint.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/18 11:12:31 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:48 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_VECINT_H +# define FT_VECINT_H + +# include + +typedef struct s_vecint +{ + int *buffer; + size_t index; + size_t size; + char finished; +} t_vecint; + +t_vecint *ft_vecint_concat(t_vecint *dest, const void *src, size_t size); +t_vecint *ft_create_vecint(size_t size); +void ft_free_vecint(t_vecint **vec); +t_vecint *ft_vecint_pushback(t_vecint *dest, int c); + +#endif \ No newline at end of file diff --git a/libft/ft_vecint.o b/libft/ft_vecint.o new file mode 100644 index 0000000..cd91b8f Binary files /dev/null and b/libft/ft_vecint.o differ diff --git a/libft/ft_vector.c b/libft/ft_vector.c new file mode 100755 index 0000000..a6a9ef1 --- /dev/null +++ b/libft/ft_vector.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vector.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/21 17:45:12 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:42 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_vector.h" +#include "libft.h" + +//creates a vector of initial size size +//returns its address, or NULL if any allocations fails +t_vector *ft_create_vector(size_t size) +{ + t_vector *ret; + + ret = malloc(sizeof(t_vector)); + if (!ret) + return (NULL); + ret->buffer = malloc(sizeof(char) * size); + if (!ret->buffer) + { + free(ret); + return (NULL); + } + ret->index = 0; + ret->size = size; + ret->finished = 0; + return (ret); +} + +//append c to the vector dest +//returns NULL if the allocation fail and the adress of dest if all goes well +t_vector *ft_vector_pushback(t_vector *dest, char c) +{ + char *buff; + + if (dest->index >= dest->size) + { + buff = malloc(sizeof(char) * ((dest->size + 1) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, dest->index); + dest->size = (dest->size + 1) * 2; + free(dest->buffer); + dest->buffer = buff; + } + dest->buffer[dest->index] = c; + dest->index++; + return (dest); +} + +//append size bytes at src to the vector dest +//returns NULL if the allocation fail and the adress of dest if all goes well +//returns NULL if dest or src is NULL without doing anything +t_vector *ft_vector_concat(t_vector *dest, const void *src, size_t size) +{ + char *buff; + + if (!dest || !src) + return (NULL); + if ((dest->index + size) >= dest->size) + { + buff = malloc(sizeof(char) * ((dest->size + size) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, dest->index); + dest->size = (dest->size + size) * 2; + free(dest->buffer); + dest->buffer = buff; + } + ft_memcpy(dest->buffer + dest->index, src, size); + dest->index += size; + return (dest); +} + +//duplicates the content of a vector into an appropriately sized string +//returns NULL if allocation fails or if vec or vec->buffer is NULL +char *ft_vtoc(t_vector *vec) +{ + char *ret; + + if (!vec) + return (NULL); + if (!vec->buffer) + return (NULL); + ret = malloc(sizeof(char) * (vec->index + 1)); + if (!ret) + return (NULL); + ft_memcpy(ret, vec->buffer, vec->index); + ret[vec->index] = '\0'; + return (ret); +} + +//frees vec and all its members, sets vec to NULL and returns NULL +void ft_free_vector(t_vector **vec) +{ + if (!vec) + return ; + if (!(*vec)) + return ; + if ((*vec)->buffer) + free((*vec)->buffer); + free(*vec); + *vec = NULL; +} diff --git a/libft/ft_vector.h b/libft/ft_vector.h new file mode 100755 index 0000000..142d684 --- /dev/null +++ b/libft/ft_vector.h @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vector.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/21 17:45:45 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:50 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_VECTOR_H +# define FT_VECTOR_H + +# include + +typedef struct s_vector +{ + char *buffer; + size_t index; + size_t size; + char finished; +} t_vector; + +t_vector *ft_vector_concat(t_vector *dest, const void *src, size_t size); +char *ft_vtoc(t_vector *vec); +t_vector *ft_create_vector(size_t size); +void ft_free_vector(t_vector **vec); +t_vector *ft_vector_pushback(t_vector *dest, char c); + +#endif diff --git a/libft/ft_vector.o b/libft/ft_vector.o new file mode 100644 index 0000000..8e2e270 Binary files /dev/null and b/libft/ft_vector.o differ diff --git a/libft/get_next_line/get_next_line.c b/libft/get_next_line/get_next_line.c new file mode 100755 index 0000000..e65b9e6 --- /dev/null +++ b/libft/get_next_line/get_next_line.c @@ -0,0 +1,186 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/17 16:43:41 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:56 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +char *ft_read( + int fd, + t_gnl_list *node, + t_gnl_vector *vec, + t_gnl_list **node_before); +t_gnl_vector *ft_read_buffer(t_gnl_list *node, t_gnl_vector *ret); +char *ft_read_return( + t_gnl_vector *vec, + t_gnl_list *node_to_free, + t_gnl_list **node_before, + int return_null_flag); +t_gnl_list *ft_gnl_create_bufflist(int fd); +void *ft_gnl_free_list(t_gnl_list **buff_list); +t_gnl_vector *ft_gnl_create_vector(size_t size); +char *ft_gnl_vtoc(t_gnl_vector *vec); +t_gnl_vector *ft_gnl_vector_concat( + t_gnl_vector *dest, + void *src, + size_t size); + +t_gnl_vector *ft_read_buffer(t_gnl_list *node, t_gnl_vector *ret) +{ + t_gnl_vector *temp; + size_t initial_index; + + if (!ret) + ret = ft_gnl_create_vector(2); + if (!ret) + return (NULL); + initial_index = node->index; + while ((node->index < (size_t)node->nb_chars) + && (node->buffer[node->index] != '\n')) + node->index++; + if (node->index < (size_t)node->nb_chars) + { + node->index++; + ret->finished = 1; + } + temp = ft_gnl_vector_concat(ret, &node->buffer[initial_index], + (node->index - initial_index)); + if (!temp) + { + if (ret->buffer) + free(ret->buffer); + free(ret); + } + return (temp); +} + +char *ft_read_return( +t_gnl_vector *vec, +t_gnl_list *node_to_free, +t_gnl_list **node_before, +int return_null_flag) +{ + char *ret; + t_gnl_list *next_node; + + ret = NULL; + if (!return_null_flag) + ret = ft_gnl_vtoc(vec); + if (vec) + { + if (vec->buffer) + free(vec->buffer); + free(vec); + } + if (node_to_free) + { + next_node = node_to_free->next; + if (*node_before != node_to_free) + (*node_before)->next = next_node; + if (node_to_free->buffer) + free(node_to_free->buffer); + free(node_to_free); + if (*node_before == node_to_free) + *node_before = next_node; + } + return (ret); +} + +//vec must be initialized to NULL or it will cause a segfault +char *ft_read( +int fd, +t_gnl_list *node, +t_gnl_vector *vec, +t_gnl_list **node_before) +{ + if (node->index < (size_t)node->nb_chars) + { + vec = ft_read_buffer(node, vec); + if (!vec) + return (ft_read_return(vec, node, node_before, 1)); + if (vec->finished == 1) + return (ft_read_return(vec, NULL, NULL, 0)); + } + while (node->index >= (size_t)node->nb_chars) + { + node->index = 0; + node->nb_chars = read(fd, node->buffer, BUFFER_SIZE); + if (node->nb_chars == 0) + return (ft_read_return(vec, node, node_before, 0)); + if (node->nb_chars < 0) + return (ft_read_return(vec, node, node_before, 1)); + vec = ft_read_buffer(node, vec); + if (!vec) + return (ft_read_return(vec, node, node_before, 1)); + if (vec->finished == 1) + return (ft_read_return(vec, NULL, NULL, 0)); + } + return (ft_read_return(vec, NULL, NULL, 0)); +} + +//returns the node having fd as its fd member +//node_before set to the previous node +//if no node is found, the last node is returned +//if we return the first node, flag is set and node_before = current_node +t_gnl_list *ft_get_current_node( +t_gnl_list *start_node, +int fd, +int *first_node_flag, +t_gnl_list **node_before) +{ + t_gnl_list *current_node; + + current_node = start_node; + *first_node_flag = 1; + *node_before = current_node; + while (current_node->next) + { + if (current_node->fd == fd) + break ; + *first_node_flag = 0; + *node_before = current_node; + current_node = current_node->next; + } + if (current_node->fd != fd) + { + current_node->next = ft_gnl_create_bufflist(fd); + if (!(current_node->next)) + return (NULL); + *first_node_flag = 0; + *node_before = current_node; + current_node = current_node->next; + } + return (current_node); +} + +char *get_next_line(int fd) +{ + static t_gnl_list *buff_list = NULL; + t_gnl_list *current_node; + t_gnl_list *previous_node; + t_gnl_vector *vec; + int flag; + + if (fd < 0) + return (NULL); + if (!buff_list) + buff_list = ft_gnl_create_bufflist(fd); + if (!buff_list) + return (NULL); + flag = 0; + current_node = ft_get_current_node(buff_list, fd, &flag, &previous_node); + if (!current_node) + return (NULL); + vec = NULL; + if (flag) + return (ft_read(fd, current_node, vec, &buff_list)); + else + return (ft_read(fd, current_node, vec, &previous_node)); +} diff --git a/libft/get_next_line/get_next_line.h b/libft/get_next_line/get_next_line.h new file mode 100755 index 0000000..8029200 --- /dev/null +++ b/libft/get_next_line/get_next_line.h @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/17 16:43:34 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:58 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H + +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 512 +# endif + +# include +# include + +typedef struct s_gnl_list +{ + char *buffer; + size_t index; + ssize_t nb_chars; + int fd; + struct s_gnl_list *next; +} t_gnl_list; + +typedef struct s_gnl_vector +{ + char *buffer; + size_t index; + size_t size; + char finished; +} t_gnl_vector; + +char *get_next_line(int fd); +void gnl_cleanup_fd(int fd); + +#endif diff --git a/libft/get_next_line/get_next_line.o b/libft/get_next_line/get_next_line.o new file mode 100644 index 0000000..8bebbab Binary files /dev/null and b/libft/get_next_line/get_next_line.o differ diff --git a/libft/get_next_line/get_next_line_utils.c b/libft/get_next_line/get_next_line_utils.c new file mode 100755 index 0000000..c5d934f --- /dev/null +++ b/libft/get_next_line/get_next_line_utils.c @@ -0,0 +1,97 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/17 16:43:37 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:55 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" +#include "../libft.h" + +//allocates and returns a new t_list node, setting next as NULL, allocates +//BUFFER_SIZE bytes for the buffer. returns NULL if any allocation fails +//index is set to BUFFER_SIZE and nb_chars to 0 +t_gnl_list *ft_gnl_create_bufflist(int fd) +{ + t_gnl_list *list; + + list = malloc(sizeof(t_gnl_list)); + if (!list) + return (NULL); + list->buffer = malloc(sizeof(char) * BUFFER_SIZE); + if (!list->buffer) + return (free(list), NULL); + list->fd = fd; + list->index = BUFFER_SIZE; + list->nb_chars = 0; + list->next = NULL; + return (list); +} + +t_gnl_vector *ft_gnl_create_vector(size_t size) +{ + t_gnl_vector *ret; + + ret = malloc(sizeof(t_gnl_vector)); + if (!ret) + return (NULL); + ret->buffer = malloc(sizeof(char) * size); + if (!ret->buffer) + { + free(ret); + return (NULL); + } + ret->index = 0; + ret->size = size; + ret->finished = 0; + return (ret); +} + +//append size bytes at src to the vector dest +//returns NULL if the allocation fail or dest otherwise +t_gnl_vector *ft_gnl_vector_concat( +t_gnl_vector *dest, +void *src, +size_t size) +{ + char *buff; + + if (!dest || !src) + return (NULL); + if ((dest->index + size) >= dest->size) + { + buff = malloc(sizeof(char) * ((dest->size + size) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, dest->index); + dest->size = (dest->size + size) * 2; + free(dest->buffer); + dest->buffer = buff; + } + ft_memcpy(dest->buffer + dest->index, src, size); + dest->index += size; + return (dest); +} + +//duplicates the content of a vector into an appropriately sized string +//returns NULL if allocation fails or vec is NULL, or vec->buffer is NULL +char *ft_gnl_vtoc(t_gnl_vector *vec) +{ + char *ret; + + if (!vec) + return (NULL); + if (!vec->buffer) + return (NULL); + ret = malloc(sizeof(char) * (vec->index + 1)); + if (!ret) + return (NULL); + ft_memcpy(ret, vec->buffer, vec->index); + ret[vec->index] = '\0'; + return (ret); +} diff --git a/libft/get_next_line/get_next_line_utils.o b/libft/get_next_line/get_next_line_utils.o new file mode 100644 index 0000000..b510e2f Binary files /dev/null and b/libft/get_next_line/get_next_line_utils.o differ diff --git a/libft/get_next_line/get_next_line_utils_two.c b/libft/get_next_line/get_next_line_utils_two.c new file mode 100644 index 0000000..8d21018 --- /dev/null +++ b/libft/get_next_line/get_next_line_utils_two.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils_two.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/12/05 13:19:35 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:52 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +void gnl_cleanup_fd(int fd) +{ + char *wtf; + + close(fd); + wtf = get_next_line(fd); + while (wtf) + { + free(wtf); + wtf = get_next_line(fd); + } +} diff --git a/libft/get_next_line/get_next_line_utils_two.o b/libft/get_next_line/get_next_line_utils_two.o new file mode 100644 index 0000000..002903d Binary files /dev/null and b/libft/get_next_line/get_next_line_utils_two.o differ diff --git a/libft/libft.a b/libft/libft.a new file mode 100644 index 0000000..2d811e5 Binary files /dev/null and b/libft/libft.a differ diff --git a/libft/libft.h b/libft/libft.h new file mode 100755 index 0000000..3ccf46e --- /dev/null +++ b/libft/libft.h @@ -0,0 +1,108 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* libft.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 12:38:59 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:53 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LIBFT_H +# define LIBFT_H + +# include +# include +# include + +int ft_isalpha(int c); +int ft_isdigit(int c); +int ft_isalnum(int c); +int ft_isascii(int c); +int ft_isprint(int c); +size_t ft_strlen(const char *s); +void *ft_memset(void *s, int c, size_t n); +void ft_bzero(void *s, size_t n); +void *ft_memcpy(void *dest, const void *src, size_t n); +void *ft_memmove(void *dest, const void *src, size_t n); +size_t ft_strlcpy(char *dst, const char *src, size_t size); +size_t ft_strlcat(char *dst, const char *src, size_t size); +int ft_toupper(int c); +int ft_tolower(int c); +char *ft_strchr(const char *s, int c); +char *ft_strrchr(const char *s, int c); +int ft_strncmp(const char *s1, const char *s2, size_t n); +void *ft_memchr(const void *s, int c, size_t n); +int ft_memcmp(const void *s1, const void *s2, size_t n); +char *ft_strnstr(const char *big, const char *little, size_t len); +//sets the flag_overflow flag if an overflow happened +//acts just like atoi otherwise (put NULL to ignore the flag) +int ft_atoi(const char *nptr, int *flag_overflow); +char *ft_strdup(const char *s); +void *ft_calloc(size_t nmemb, size_t size); +char *ft_substr(char const *s, unsigned int start, size_t len); +char *ft_strjoin(char const *s1, char const *s2); +char *ft_strtrim(char const *s1, char const *set); + +char **ft_split(char const *s, char c); +void ft_free_split(char **strs); +size_t ft_split_size(char **strs); + +char *ft_itoa(int n); +char *ft_strmapi(char const *s, char (*f)(unsigned int, char)); +void ft_striteri(char *s, void (*f)(unsigned int, char*)); +void ft_putchar_fd(char c, int fd); +void ft_putstr_fd(char *s, int fd); +void ft_putendl_fd(char *s, int fd); +void ft_putnbr_fd(int n, int fd); +char *ft_itoa_base(int nbr, char *base); +char *ft_addr_to_strhex(void *addr); +char *ft_utoa(unsigned int n); +char *ft_utoa_base(unsigned int nbr, char *base); +size_t ft_strnonchr(char *str, char c); +int ft_strcmp(const char *s1, const char *s2); + +typedef struct s_list +{ + void *content; + struct s_list *next; +} t_list; + +t_list *ft_lstnew(void *content); +void ft_lstadd_front(t_list **lst, t_list *new); +int ft_lstsize(t_list *lst); +t_list *ft_lstlast(t_list *lst); +void ft_lstadd_back(t_list **lst, t_list *new); +void ft_lstdelone(t_list *lst, void (*del)(void *)); +void ft_lstclear(t_list **lst, void (*del)(void *)); +void ft_lstiter(t_list *lst, void (*f)(void *)); +t_list *ft_lstmap( + t_list *lst, + void *(*f)(void *), + void (*del)(void *)); + +int ft_isspace(char c); +int ft_toupper(int c); +int ft_tolower(int c); +int ft_atoie(const char *nptr); +long ft_atole(const char *nptr); +size_t i_drep_len(int n); +unsigned int ft_max_uint(size_t len, unsigned int a[len]); +t_list *ft_lstat(t_list *lst, size_t i); + +int safe_int_add(int a, int b); +int safe_int_sub(int a, int b); +int safe_int_mul(int a, int b); +ssize_t ft_power(ssize_t nb, ssize_t power); + +long safe_long_add(long a, long b); +long safe_long_sub(long a, long b); +long safe_long_mul(long a, long b); + +int ft_strhassuffix(const char *s, const char *suffix); +int ft_linecmp(const char *s1, const char *s2); +size_t ft_linelen(const char *line); + +#endif diff --git a/libft/sorting/ft_radixsort.c b/libft/sorting/ft_radixsort.c new file mode 100644 index 0000000..f9e33e7 --- /dev/null +++ b/libft/sorting/ft_radixsort.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_radixsort.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/18 14:18:55 by alier #+# #+# */ +/* Updated: 2025/02/16 19:06:42 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include "ft_sorting.h" + +static void ft_naive_countsort2(struct s_countsort cs) +{ + size_t i; + + i = cs.size - 1; + while (true) + { + cs.tmp[cs.count[(cs.a[i] / cs.exp) % 10] - 1] = cs.a[i]; + cs.count[(cs.a[i] / cs.exp) % 10]--; + if (i == 0) + break ; + i--; + } + ft_memcpy(cs.a, cs.tmp, cs.size * sizeof(*cs.a)); +} + +/* + * used by `ft_naive_radixsort` + */ +static void ft_naive_countsort(size_t size, unsigned int a[size], + unsigned int exp) +{ + unsigned int *tmp; + unsigned int count[10]; + size_t i; + + tmp = malloc(size * sizeof(unsigned int)); + ft_bzero(count, 10 * sizeof(unsigned int)); + i = 0; + while (i < size) + { + count[(a[i] / exp) % 10]++; + i++; + } + i = 1; + while (i < 10) + { + count[i] += count[i - 1]; + i++; + } + ft_naive_countsort2((struct s_countsort){size, a, exp, tmp, count}); + free(tmp); +} + +/* + * Worst-case performance: O(size * max_digits) + * Worst-case space complexity: O(size + max_digits) + */ +void ft_naive_radixsort(size_t size, unsigned int a[size]) +{ + unsigned int m; + unsigned int exp; + + m = ft_max_uint(size, a); + exp = 1; + while (m / exp > 0) + { + ft_naive_countsort(size, a, exp); + exp *= 10; + } +} diff --git a/libft/sorting/ft_radixsort.o b/libft/sorting/ft_radixsort.o new file mode 100644 index 0000000..62c6e50 Binary files /dev/null and b/libft/sorting/ft_radixsort.o differ diff --git a/libft/sorting/ft_sorting.c b/libft/sorting/ft_sorting.c new file mode 100644 index 0000000..3773a9f --- /dev/null +++ b/libft/sorting/ft_sorting.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sorting.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/31 09:34:43 by alier #+# #+# */ +/* Updated: 2025/01/17 11:07:04 by alier ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include +#include +#include "ft_sorting.h" + +static void ft_swap_bytes(void *a, void *b, size_t count) +{ + uint8_t *x; + uint8_t *y; + uint8_t t; + size_t i; + + x = (uint8_t *) a; + y = (uint8_t *) b; + i = 0; + while (i < count) + { + t = x[i]; + x[i] = y[i]; + y[i] = t; + i++; + } +} + +/* + * Worst-case performance: O(n^2) comparisons, O(n^2) swaps + * Worst-case space complexity: O(n) total, O(1) auxiliary + */ +void ft_naive_bubblesort(void *base, size_t nmemb, size_t size, + t_compar compar) +{ + bool swapped; + size_t i; + + if (nmemb == 0) + return ; + swapped = true; + while (swapped) + { + swapped = false; + i = 0; + while (i < nmemb * size - size) + { + if (compar(base + i, base + i + size) > 0) + { + ft_swap_bytes(base + i, base + i + size, size); + swapped = true; + } + i += size; + } + } +} + +static int compare_ints_asc(const void *a, const void *b) +{ + if (*(int *) a > *(int *)b) + return (1); + else + return (-1); +} + +int compare_strs_ptrs_asc(const void *a, const void *b) +{ + const char *left; + const char *right; + + left = *(const char **)a; + right = *(const char **)b; + return (ft_strcmp(left, right)); +} + +/* + * Worst-case performance: O(n^2) comparisons, O(n^2) swaps + * Worst-case space complexity: O(n) total, O(1) auxiliary + */ +void ft_naive_bubblesort_int_asc(int *base, size_t size) +{ + ft_naive_bubblesort(base, size, sizeof(int), compare_ints_asc); +} diff --git a/libft/sorting/ft_sorting.h b/libft/sorting/ft_sorting.h new file mode 100644 index 0000000..723167a --- /dev/null +++ b/libft/sorting/ft_sorting.h @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sorting.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/04 16:45:04 by alier #+# #+# */ +/* Updated: 2025/01/17 11:07:18 by alier ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_SORTING_H +# define FT_SORTING_H +# include +# include "../libft.h" + +struct s_countsort +{ + size_t size; + unsigned int *a; + unsigned int exp; + unsigned int *tmp; + unsigned int *count; +}; + +typedef int (*t_compar)(const void *, const void *); + +int compare_strs_ptrs_asc(const void *a, const void *b); +void ft_naive_radixsort(size_t size, unsigned int a[size]); +void ft_naive_bubblesort_int_asc(int *base, size_t size); +void ft_naive_bubblesort(void *base, size_t nmemb, size_t size, + t_compar compar); + +#endif \ No newline at end of file diff --git a/libft/sorting/ft_sorting.o b/libft/sorting/ft_sorting.o new file mode 100644 index 0000000..03c3811 Binary files /dev/null and b/libft/sorting/ft_sorting.o differ diff --git a/libft_malloc.so b/libft_malloc.so new file mode 120000 index 0000000..bc92c49 --- /dev/null +++ b/libft_malloc.so @@ -0,0 +1 @@ +libft_malloc_x86_64_Linux.so \ No newline at end of file diff --git a/libft_malloc_x86_64_Linux.so b/libft_malloc_x86_64_Linux.so new file mode 100755 index 0000000..053a091 Binary files /dev/null and b/libft_malloc_x86_64_Linux.so differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..71834dd --- /dev/null +++ b/main.c @@ -0,0 +1,419 @@ +#include +#include +#include +#include +#include + +/* +** These match your allocator’s thresholds +** (only used here for shaping size distributions) +*/ +#define TINY_MAX 64 +#define SMALL_MAX 4096 + +#define ARRAY_SIZE 10000 // number of live slots we manage +#define RANDOM_ITERS 200000 // number of random operations +#define PATTERN_BASE 0xA5 +#define MAX_LARGE_SIZE (SMALL_MAX * 8) // up to 32k-ish + +typedef struct s_block +{ + void *ptr; + size_t size; + unsigned char pattern; + int is_calloc; +} t_block; + +static t_block g_blocks[ARRAY_SIZE]; + +/* Fill a block with a simple pattern byte */ +static void fill_pattern(void *ptr, size_t size, unsigned char pattern) +{ + if (!ptr || size == 0) + return; + memset(ptr, pattern, size); +} + +/* Check that a block still has the expected pattern */ +static int check_pattern(void *ptr, size_t size, unsigned char pattern) +{ + if (!ptr || size == 0) + return 1; + unsigned char *p = (unsigned char *)ptr; + for (size_t i = 0; i < size; ++i) + { + if (p[i] != pattern) + { + fprintf(stderr, + "[ERROR] Pattern mismatch at %p (offset %zu): " + "expected 0x%02X, got 0x%02X\n", + ptr, i, (unsigned)pattern, (unsigned)p[i]); + return 0; + } + } + return 1; +} + +/* Check that a calloc'd block is zeroed */ +static int check_zero(void *ptr, size_t size) +{ + if (!ptr || size == 0) + return 1; + unsigned char *p = (unsigned char *)ptr; + for (size_t i = 0; i < size; ++i) + { + if (p[i] != 0) + { + fprintf(stderr, + "[ERROR] Calloc block not zeroed at %p (offset %zu): got 0x%02X\n", + ptr, i, (unsigned)p[i]); + return 0; + } + } + return 1; +} + +/* Generate a pseudo-random size skewed across tiny/small/large */ +static size_t random_size(void) +{ + int r = rand() % 100; + + if (r < 40) + { + /* TINY range [1..TINY_MAX] */ + return (size_t)(1 + rand() % TINY_MAX); + } + else if (r < 85) + { + /* SMALL range [TINY_MAX+1 .. SMALL_MAX] */ + return (size_t)(TINY_MAX + 1 + rand() % (SMALL_MAX - TINY_MAX)); + } + else + { + /* LARGE range [SMALL_MAX+1 .. MAX_LARGE_SIZE] */ + return (size_t)(SMALL_MAX + 1 + rand() % (MAX_LARGE_SIZE - SMALL_MAX - 1)); + } +} + +/* Tear down all blocks cleanly (for the end of tests) */ +static void free_all_blocks(void) +{ + for (int i = 0; i < ARRAY_SIZE; ++i) + { + if (g_blocks[i].ptr) + { + free(g_blocks[i].ptr); + g_blocks[i].ptr = NULL; + g_blocks[i].size = 0; + } + } +} + +/* Simple deterministic sanity tests */ +static void basic_tests(void) +{ + printf("== basic_tests ==\n"); + + /* TINY */ + void *a = malloc(10); + void *b = malloc(TINY_MAX); + fill_pattern(a, 10, 0x11); + fill_pattern(b, TINY_MAX, 0x22); + check_pattern(a, 10, 0x11); + check_pattern(b, TINY_MAX, 0x22); + free(a); + free(b); + + /* SMALL */ + void *c = malloc(SMALL_MAX / 2); + fill_pattern(c, SMALL_MAX / 2, 0x33); + check_pattern(c, SMALL_MAX / 2, 0x33); + c = realloc(c, SMALL_MAX / 2 + 100); // grow within SMALL + check_pattern(c, SMALL_MAX / 2, 0x33); + free(c); + + /* LARGE */ + size_t large_sz = SMALL_MAX * 4; + void *d = malloc(large_sz); + fill_pattern(d, large_sz, 0x44); + check_pattern(d, large_sz, 0x44); + d = realloc(d, large_sz * 2); // grow LARGE + check_pattern(d, large_sz, 0x44); + d = realloc(d, large_sz / 2); // shrink LARGE + check_pattern(d, large_sz / 2, 0x44); + free(d); + + /* CALLOC */ + void *e = calloc(1000, 1); + check_zero(e, 1000); + memset(e, 0xAB, 1000); + e = realloc(e, 2000); + check_pattern(e, 1000, 0xAB); + free(e); + + printf("basic_tests: OK\n\n"); +} + +static void random_stress(void) +{ + printf("== random_stress ==\n"); + + for (int i = 0; i < ARRAY_SIZE; ++i) + { + g_blocks[i].ptr = NULL; + g_blocks[i].size = 0; + g_blocks[i].pattern = 0; + g_blocks[i].is_calloc = 0; + } + + for (int iter = 0; iter < RANDOM_ITERS; ++iter) + { + int idx = rand() % ARRAY_SIZE; + t_block *blk = &g_blocks[idx]; + int op = rand() % 4; /* 0 = alloc/new, 1 = free, 2 = realloc up, 3 = realloc down */ + + /* Invariant: for non-NULL blocks we always keep full [0..size) filled with pattern */ + if (blk->ptr && !blk->is_calloc) + { + if (!check_pattern(blk->ptr, blk->size, blk->pattern)) + { + fprintf(stderr, "[FATAL] pattern mismatch before op; idx=%d\n", idx); + abort(); + } + } + + if (op == 0) + { + /* allocate new if empty, otherwise grow via realloc */ + if (blk->ptr == NULL) + { + size_t sz = random_size(); + int use_calloc = (rand() % 4) == 0; /* 25% calloc */ + + if (use_calloc) + { + blk->ptr = calloc(sz, 1); + blk->is_calloc = 1; + blk->size = sz; + if (!blk->ptr) + { + fprintf(stderr, "[ERROR] calloc returned NULL\n"); + continue; + } + /* we only check zero once; then we switch to pattern mode */ + if (!check_zero(blk->ptr, blk->size)) + fprintf(stderr, "[ERROR] calloc block not zeroed (idx=%d)\n", idx); + blk->pattern = (unsigned char)((PATTERN_BASE + idx) & 0xFF); + fill_pattern(blk->ptr, blk->size, blk->pattern); + blk->is_calloc = 0; + } + else + { + blk->ptr = malloc(sz); + blk->is_calloc = 0; + blk->size = sz; + if (!blk->ptr) + { + fprintf(stderr, "[ERROR] malloc returned NULL\n"); + continue; + } + blk->pattern = (unsigned char)((PATTERN_BASE + idx) & 0xFF); + fill_pattern(blk->ptr, blk->size, blk->pattern); + } + } + else + { + /* grow via realloc */ + size_t old_size = blk->size; + size_t new_sz = old_size + 1 + (rand() % (old_size + 1)); + unsigned char pattern = blk->pattern; + + void *new_ptr = realloc(blk->ptr, new_sz); + if (!new_ptr) + { + fprintf(stderr, "[ERROR] realloc (grow) returned NULL\n"); + continue; /* keep old block as-is */ + } + blk->ptr = new_ptr; + blk->size = new_sz; + blk->pattern = pattern; + + /* Only the first old_size bytes must be preserved */ + if (!check_pattern(blk->ptr, old_size, pattern)) + { + fprintf(stderr, "[ERROR] pattern mismatch after realloc grow (idx=%d)\n", idx); + abort(); + } + /* Now enforce our invariant for the future */ + fill_pattern(blk->ptr, blk->size, blk->pattern); + } + } + else if (op == 1) + { + /* free */ + if (blk->ptr) + { + free(blk->ptr); + blk->ptr = NULL; + blk->size = 0; + blk->is_calloc = 0; + } + } + else if (op == 2) + { + /* explicit realloc up (if exists) */ + if (blk->ptr) + { + size_t old_size = blk->size; + size_t new_sz = old_size + 1 + (rand() % (old_size + 1)); + unsigned char pattern = blk->pattern; + + void *new_ptr = realloc(blk->ptr, new_sz); + if (!new_ptr) + { + fprintf(stderr, "[ERROR] realloc (grow2) returned NULL\n"); + continue; + } + + blk->ptr = new_ptr; + blk->size = new_sz; + blk->pattern = pattern; + + if (!check_pattern(blk->ptr, old_size, pattern)) + { + fprintf(stderr, "[ERROR] pattern mismatch after realloc grow2 (idx=%d)\n", idx); + abort(); + } + fill_pattern(blk->ptr, blk->size, blk->pattern); + } + } + else /* op == 3, realloc down */ + { + if (blk->ptr && blk->size > 1) + { + size_t old_size = blk->size; + size_t new_sz = 1 + (rand() % blk->size); + unsigned char pattern = blk->pattern; + + void *new_ptr = realloc(blk->ptr, new_sz); + if (!new_ptr) + { + fprintf(stderr, "[ERROR] realloc (shrink) returned NULL\n"); + continue; + } + + blk->ptr = new_ptr; + blk->size = new_sz; + blk->pattern = pattern; + + /* For shrink, we only expect the first new_sz bytes to still match */ + if (!check_pattern(blk->ptr, blk->size, blk->pattern)) + { + fprintf(stderr, "[ERROR] pattern mismatch after realloc shrink (idx=%d)\n", idx); + abort(); + } + /* Still keep invariant explicitly (optional here) */ + fill_pattern(blk->ptr, blk->size, blk->pattern); + } + } + + if ((iter % 50000) == 0 && iter != 0) + printf(" random_stress progress: %d / %d\n", iter, RANDOM_ITERS); + } + + free_all_blocks(); + printf("random_stress: DONE\n\n"); +} + +/* Fragmentation test: allocate many small then free some, then big allocs, etc. */ +static void fragmentation_test(void) +{ + printf("== fragmentation_test ==\n"); + + const int count = 10000; + void **arr = malloc(sizeof(void *) * count); + size_t *sizes = malloc(sizeof(size_t) * count); + if (!arr || !sizes) + { + fprintf(stderr, "[ERROR] fragmentation_test: malloc failed\n"); + free(arr); + free(sizes); + return; + } + + /* Step 1: allocate random small blocks */ + for (int i = 0; i < count; ++i) + { + size_t sz = 1 + (rand() % SMALL_MAX); + arr[i] = malloc(sz); + sizes[i] = sz; + if (!arr[i]) + { + fprintf(stderr, "[ERROR] fragmentation_test: malloc failed at i=%d\n", i); + continue; + } + memset(arr[i], 0x5A, sz); + } + + /* Step 2: free every other block */ + for (int i = 0; i < count; i += 2) + { + if (arr[i]) + { + free(arr[i]); + arr[i] = NULL; + sizes[i] = 0; + } + } + + /* Step 3: allocate a bunch of bigger blocks, try to reuse fragmentation */ + const int big_count = 1000; + void **big = malloc(sizeof(void *) * big_count); + size_t *big_sz = malloc(sizeof(size_t) * big_count); + if (!big || !big_sz) + { + fprintf(stderr, "[ERROR] fragmentation_test: big malloc failed\n"); + free(big); + free(big_sz); + free(arr); + free(sizes); + return; + } + + for (int i = 0; i < big_count; ++i) + { + size_t sz = SMALL_MAX + (rand() % (SMALL_MAX * 4)); + big[i] = malloc(sz); + big_sz[i] = sz; + if (!big[i]) + { + fprintf(stderr, "[ERROR] fragmentation_test: big malloc failed at i=%d\n", i); + continue; + } + memset(big[i], 0x6B, sz); + } + + /* cleanup */ + for (int i = 0; i < count; ++i) + free(arr[i]); + for (int i = 0; i < big_count; ++i) + free(big[i]); + free(arr); + free(sizes); + free(big); + free(big_sz); + + printf("fragmentation_test: DONE\n\n"); +} + +int main(void) +{ + srand((unsigned int)time(NULL)); + + basic_tests(); + random_stress(); + fragmentation_test(); + + printf("ALL TESTS DONE\n"); + return 0; +} diff --git a/main_bonus.c b/main_bonus.c new file mode 100644 index 0000000..9a9ac6e --- /dev/null +++ b/main_bonus.c @@ -0,0 +1,68 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/28 17:23:45 by thrieg #+# #+# */ +/* Updated: 2025/11/28 19:16:24 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "includes/ft_malloc_public.h" +#include +#include +#include + +int main(void) +{ + char *a = malloc(10); + char *b = malloc(100); + int *c = malloc(50 * sizeof(int)); + + for (int i = 0; i < 10; ++i) + a[i] = i; + for (int i = 0; i < 100; ++i) + b[i] = 0xAA; + for (int i = 0; i < 50; ++i) + c[i] = i * 2; + + write(1, "\n\n\n\n\nafter first alloc: \n\n\n\n\n", sizeof("\n\n\n\n\nafter first alloc: \n\n\n\n\n") - 1); + show_alloc_mem_ex(false); + + free(a); + free(b); + free(c); + + write(1, "\n\n\n\n\nafter free: \n\n\n\n\n", sizeof("\n\n\n\n\nafter free: \n\n\n\n\n") - 1); + show_alloc_mem_ex(false); + + a = malloc(20); + b = malloc(1000); + c = malloc(500 * sizeof(int)); + + for (int i = 0; i < 20; ++i) + a[i] = i; + for (int i = 0; i < 1000; ++i) + b[i] = 0xAA; + for (int i = 0; i < 500; ++i) + c[i] = i * 2; + + write(1, "\n\n\n\n\nafter allocating again: \n\n\n\n\n", sizeof("\n\n\n\n\nafter allocating again: \n\n\n\n\n") - 1); + show_alloc_mem_ex(false); + + a = realloc(a, 420); + + write(1, "\n\n\n\n\nafter realloc a: \n\n\n\n\n", sizeof("\n\n\n\n\nafter realloc a: \n\n\n\n\n") - 1); + show_alloc_mem_ex(false); + + free(a); + free(b); + free(c); + show_alloc_mem_ex(false); + return (0); +} + +// cc -g main_bonus.c -L. -lft_malloc -o test_show +// export LD_LIBRARY_PATH="$PWD" diff --git a/result.txt b/result.txt new file mode 100644 index 0000000..c62a856 --- /dev/null +++ b/result.txt @@ -0,0 +1,582 @@ + + + + + +after first alloc: + + + + +-------------------------------- +new tiny zone: +size: 12288 +-------------------------------- +-------------------------------- +new allocated header: +size: 16 +-------------------------------- +0x744b0ba71040: 00 01 02 03 04 05 06 07 08 09 00 00 00 00 00 00 +-------------------------------- +new free header: +size: 12176 +-------------------------------- +-------------------------------- +new small zone: +size: 413696 +-------------------------------- +-------------------------------- +new allocated header: +size: 112 +-------------------------------- +0x744b0b79b040: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b050: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b060: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b070: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b080: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b090: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0a0: aa aa aa aa 00 00 00 00 00 00 00 00 00 00 00 00 +-------------------------------- +new allocated header: +size: 208 +-------------------------------- +0x744b0b79b0d0: 00 00 00 00 02 00 00 00 04 00 00 00 06 00 00 00 +0x744b0b79b0e0: 08 00 00 00 0a 00 00 00 0c 00 00 00 0e 00 00 00 +0x744b0b79b0f0: 10 00 00 00 12 00 00 00 14 00 00 00 16 00 00 00 +0x744b0b79b100: 18 00 00 00 1a 00 00 00 1c 00 00 00 1e 00 00 00 +0x744b0b79b110: 20 00 00 00 22 00 00 00 24 00 00 00 26 00 00 00 +0x744b0b79b120: 28 00 00 00 2a 00 00 00 2c 00 00 00 2e 00 00 00 +0x744b0b79b130: 30 00 00 00 32 00 00 00 34 00 00 00 36 00 00 00 +0x744b0b79b140: 38 00 00 00 3a 00 00 00 3c 00 00 00 3e 00 00 00 +0x744b0b79b150: 40 00 00 00 42 00 00 00 44 00 00 00 46 00 00 00 +0x744b0b79b160: 48 00 00 00 4a 00 00 00 4c 00 00 00 4e 00 00 00 +0x744b0b79b170: 50 00 00 00 52 00 00 00 54 00 00 00 56 00 00 00 +0x744b0b79b180: 58 00 00 00 5a 00 00 00 5c 00 00 00 5e 00 00 00 +0x744b0b79b190: 60 00 00 00 62 00 00 00 00 00 00 00 00 00 00 00 +-------------------------------- +new free header: +size: 413248 +-------------------------------- + + + + + +after free: + + + + +-------------------------------- +new tiny zone: +size: 12288 +-------------------------------- +-------------------------------- +new free header: +size: 12224 +-------------------------------- +-------------------------------- +new small zone: +size: 413696 +-------------------------------- +-------------------------------- +new free header: +size: 413632 +-------------------------------- + + + + + +after allocating again: + + + + +-------------------------------- +new tiny zone: +size: 12288 +-------------------------------- +-------------------------------- +new allocated header: +size: 32 +-------------------------------- +0x744b0ba71040: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +0x744b0ba71050: 10 11 12 13 00 00 00 00 00 00 00 00 00 00 00 00 +-------------------------------- +new free header: +size: 12160 +-------------------------------- +-------------------------------- +new small zone: +size: 413696 +-------------------------------- +-------------------------------- +new allocated header: +size: 1008 +-------------------------------- +0x744b0b79b040: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b050: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b060: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b070: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b080: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b090: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0a0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0b0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0c0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0f0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b100: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b110: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b120: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b130: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b140: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b150: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b160: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b170: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b180: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b190: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1a0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1b0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1c0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1f0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b200: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b210: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b220: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b230: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b240: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b250: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b260: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b270: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b280: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b290: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2a0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2b0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2c0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2f0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b300: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b310: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b320: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b330: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b340: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b350: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b360: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b370: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b380: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b390: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3a0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3b0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3c0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3f0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b400: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b410: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b420: aa aa aa aa aa aa aa aa 00 00 00 00 00 00 00 00 +-------------------------------- +new allocated header: +size: 2000 +-------------------------------- +0x744b0b79b450: 00 00 00 00 02 00 00 00 04 00 00 00 06 00 00 00 +0x744b0b79b460: 08 00 00 00 0a 00 00 00 0c 00 00 00 0e 00 00 00 +0x744b0b79b470: 10 00 00 00 12 00 00 00 14 00 00 00 16 00 00 00 +0x744b0b79b480: 18 00 00 00 1a 00 00 00 1c 00 00 00 1e 00 00 00 +0x744b0b79b490: 20 00 00 00 22 00 00 00 24 00 00 00 26 00 00 00 +0x744b0b79b4a0: 28 00 00 00 2a 00 00 00 2c 00 00 00 2e 00 00 00 +0x744b0b79b4b0: 30 00 00 00 32 00 00 00 34 00 00 00 36 00 00 00 +0x744b0b79b4c0: 38 00 00 00 3a 00 00 00 3c 00 00 00 3e 00 00 00 +0x744b0b79b4d0: 40 00 00 00 42 00 00 00 44 00 00 00 46 00 00 00 +0x744b0b79b4e0: 48 00 00 00 4a 00 00 00 4c 00 00 00 4e 00 00 00 +0x744b0b79b4f0: 50 00 00 00 52 00 00 00 54 00 00 00 56 00 00 00 +0x744b0b79b500: 58 00 00 00 5a 00 00 00 5c 00 00 00 5e 00 00 00 +0x744b0b79b510: 60 00 00 00 62 00 00 00 64 00 00 00 66 00 00 00 +0x744b0b79b520: 68 00 00 00 6a 00 00 00 6c 00 00 00 6e 00 00 00 +0x744b0b79b530: 70 00 00 00 72 00 00 00 74 00 00 00 76 00 00 00 +0x744b0b79b540: 78 00 00 00 7a 00 00 00 7c 00 00 00 7e 00 00 00 +0x744b0b79b550: 80 00 00 00 82 00 00 00 84 00 00 00 86 00 00 00 +0x744b0b79b560: 88 00 00 00 8a 00 00 00 8c 00 00 00 8e 00 00 00 +0x744b0b79b570: 90 00 00 00 92 00 00 00 94 00 00 00 96 00 00 00 +0x744b0b79b580: 98 00 00 00 9a 00 00 00 9c 00 00 00 9e 00 00 00 +0x744b0b79b590: a0 00 00 00 a2 00 00 00 a4 00 00 00 a6 00 00 00 +0x744b0b79b5a0: a8 00 00 00 aa 00 00 00 ac 00 00 00 ae 00 00 00 +0x744b0b79b5b0: b0 00 00 00 b2 00 00 00 b4 00 00 00 b6 00 00 00 +0x744b0b79b5c0: b8 00 00 00 ba 00 00 00 bc 00 00 00 be 00 00 00 +0x744b0b79b5d0: c0 00 00 00 c2 00 00 00 c4 00 00 00 c6 00 00 00 +0x744b0b79b5e0: c8 00 00 00 ca 00 00 00 cc 00 00 00 ce 00 00 00 +0x744b0b79b5f0: d0 00 00 00 d2 00 00 00 d4 00 00 00 d6 00 00 00 +0x744b0b79b600: d8 00 00 00 da 00 00 00 dc 00 00 00 de 00 00 00 +0x744b0b79b610: e0 00 00 00 e2 00 00 00 e4 00 00 00 e6 00 00 00 +0x744b0b79b620: e8 00 00 00 ea 00 00 00 ec 00 00 00 ee 00 00 00 +0x744b0b79b630: f0 00 00 00 f2 00 00 00 f4 00 00 00 f6 00 00 00 +0x744b0b79b640: f8 00 00 00 fa 00 00 00 fc 00 00 00 fe 00 00 00 +0x744b0b79b650: 00 01 00 00 02 01 00 00 04 01 00 00 06 01 00 00 +0x744b0b79b660: 08 01 00 00 0a 01 00 00 0c 01 00 00 0e 01 00 00 +0x744b0b79b670: 10 01 00 00 12 01 00 00 14 01 00 00 16 01 00 00 +0x744b0b79b680: 18 01 00 00 1a 01 00 00 1c 01 00 00 1e 01 00 00 +0x744b0b79b690: 20 01 00 00 22 01 00 00 24 01 00 00 26 01 00 00 +0x744b0b79b6a0: 28 01 00 00 2a 01 00 00 2c 01 00 00 2e 01 00 00 +0x744b0b79b6b0: 30 01 00 00 32 01 00 00 34 01 00 00 36 01 00 00 +0x744b0b79b6c0: 38 01 00 00 3a 01 00 00 3c 01 00 00 3e 01 00 00 +0x744b0b79b6d0: 40 01 00 00 42 01 00 00 44 01 00 00 46 01 00 00 +0x744b0b79b6e0: 48 01 00 00 4a 01 00 00 4c 01 00 00 4e 01 00 00 +0x744b0b79b6f0: 50 01 00 00 52 01 00 00 54 01 00 00 56 01 00 00 +0x744b0b79b700: 58 01 00 00 5a 01 00 00 5c 01 00 00 5e 01 00 00 +0x744b0b79b710: 60 01 00 00 62 01 00 00 64 01 00 00 66 01 00 00 +0x744b0b79b720: 68 01 00 00 6a 01 00 00 6c 01 00 00 6e 01 00 00 +0x744b0b79b730: 70 01 00 00 72 01 00 00 74 01 00 00 76 01 00 00 +0x744b0b79b740: 78 01 00 00 7a 01 00 00 7c 01 00 00 7e 01 00 00 +0x744b0b79b750: 80 01 00 00 82 01 00 00 84 01 00 00 86 01 00 00 +0x744b0b79b760: 88 01 00 00 8a 01 00 00 8c 01 00 00 8e 01 00 00 +0x744b0b79b770: 90 01 00 00 92 01 00 00 94 01 00 00 96 01 00 00 +0x744b0b79b780: 98 01 00 00 9a 01 00 00 9c 01 00 00 9e 01 00 00 +0x744b0b79b790: a0 01 00 00 a2 01 00 00 a4 01 00 00 a6 01 00 00 +0x744b0b79b7a0: a8 01 00 00 aa 01 00 00 ac 01 00 00 ae 01 00 00 +0x744b0b79b7b0: b0 01 00 00 b2 01 00 00 b4 01 00 00 b6 01 00 00 +0x744b0b79b7c0: b8 01 00 00 ba 01 00 00 bc 01 00 00 be 01 00 00 +0x744b0b79b7d0: c0 01 00 00 c2 01 00 00 c4 01 00 00 c6 01 00 00 +0x744b0b79b7e0: c8 01 00 00 ca 01 00 00 cc 01 00 00 ce 01 00 00 +0x744b0b79b7f0: d0 01 00 00 d2 01 00 00 d4 01 00 00 d6 01 00 00 +0x744b0b79b800: d8 01 00 00 da 01 00 00 dc 01 00 00 de 01 00 00 +0x744b0b79b810: e0 01 00 00 e2 01 00 00 e4 01 00 00 e6 01 00 00 +0x744b0b79b820: e8 01 00 00 ea 01 00 00 ec 01 00 00 ee 01 00 00 +0x744b0b79b830: f0 01 00 00 f2 01 00 00 f4 01 00 00 f6 01 00 00 +0x744b0b79b840: f8 01 00 00 fa 01 00 00 fc 01 00 00 fe 01 00 00 +0x744b0b79b850: 00 02 00 00 02 02 00 00 04 02 00 00 06 02 00 00 +0x744b0b79b860: 08 02 00 00 0a 02 00 00 0c 02 00 00 0e 02 00 00 +0x744b0b79b870: 10 02 00 00 12 02 00 00 14 02 00 00 16 02 00 00 +0x744b0b79b880: 18 02 00 00 1a 02 00 00 1c 02 00 00 1e 02 00 00 +0x744b0b79b890: 20 02 00 00 22 02 00 00 24 02 00 00 26 02 00 00 +0x744b0b79b8a0: 28 02 00 00 2a 02 00 00 2c 02 00 00 2e 02 00 00 +0x744b0b79b8b0: 30 02 00 00 32 02 00 00 34 02 00 00 36 02 00 00 +0x744b0b79b8c0: 38 02 00 00 3a 02 00 00 3c 02 00 00 3e 02 00 00 +0x744b0b79b8d0: 40 02 00 00 42 02 00 00 44 02 00 00 46 02 00 00 +0x744b0b79b8e0: 48 02 00 00 4a 02 00 00 4c 02 00 00 4e 02 00 00 +0x744b0b79b8f0: 50 02 00 00 52 02 00 00 54 02 00 00 56 02 00 00 +0x744b0b79b900: 58 02 00 00 5a 02 00 00 5c 02 00 00 5e 02 00 00 +0x744b0b79b910: 60 02 00 00 62 02 00 00 64 02 00 00 66 02 00 00 +0x744b0b79b920: 68 02 00 00 6a 02 00 00 6c 02 00 00 6e 02 00 00 +0x744b0b79b930: 70 02 00 00 72 02 00 00 74 02 00 00 76 02 00 00 +0x744b0b79b940: 78 02 00 00 7a 02 00 00 7c 02 00 00 7e 02 00 00 +0x744b0b79b950: 80 02 00 00 82 02 00 00 84 02 00 00 86 02 00 00 +0x744b0b79b960: 88 02 00 00 8a 02 00 00 8c 02 00 00 8e 02 00 00 +0x744b0b79b970: 90 02 00 00 92 02 00 00 94 02 00 00 96 02 00 00 +0x744b0b79b980: 98 02 00 00 9a 02 00 00 9c 02 00 00 9e 02 00 00 +0x744b0b79b990: a0 02 00 00 a2 02 00 00 a4 02 00 00 a6 02 00 00 +0x744b0b79b9a0: a8 02 00 00 aa 02 00 00 ac 02 00 00 ae 02 00 00 +0x744b0b79b9b0: b0 02 00 00 b2 02 00 00 b4 02 00 00 b6 02 00 00 +0x744b0b79b9c0: b8 02 00 00 ba 02 00 00 bc 02 00 00 be 02 00 00 +0x744b0b79b9d0: c0 02 00 00 c2 02 00 00 c4 02 00 00 c6 02 00 00 +0x744b0b79b9e0: c8 02 00 00 ca 02 00 00 cc 02 00 00 ce 02 00 00 +0x744b0b79b9f0: d0 02 00 00 d2 02 00 00 d4 02 00 00 d6 02 00 00 +0x744b0b79ba00: d8 02 00 00 da 02 00 00 dc 02 00 00 de 02 00 00 +0x744b0b79ba10: e0 02 00 00 e2 02 00 00 e4 02 00 00 e6 02 00 00 +0x744b0b79ba20: e8 02 00 00 ea 02 00 00 ec 02 00 00 ee 02 00 00 +0x744b0b79ba30: f0 02 00 00 f2 02 00 00 f4 02 00 00 f6 02 00 00 +0x744b0b79ba40: f8 02 00 00 fa 02 00 00 fc 02 00 00 fe 02 00 00 +0x744b0b79ba50: 00 03 00 00 02 03 00 00 04 03 00 00 06 03 00 00 +0x744b0b79ba60: 08 03 00 00 0a 03 00 00 0c 03 00 00 0e 03 00 00 +0x744b0b79ba70: 10 03 00 00 12 03 00 00 14 03 00 00 16 03 00 00 +0x744b0b79ba80: 18 03 00 00 1a 03 00 00 1c 03 00 00 1e 03 00 00 +0x744b0b79ba90: 20 03 00 00 22 03 00 00 24 03 00 00 26 03 00 00 +0x744b0b79baa0: 28 03 00 00 2a 03 00 00 2c 03 00 00 2e 03 00 00 +0x744b0b79bab0: 30 03 00 00 32 03 00 00 34 03 00 00 36 03 00 00 +0x744b0b79bac0: 38 03 00 00 3a 03 00 00 3c 03 00 00 3e 03 00 00 +0x744b0b79bad0: 40 03 00 00 42 03 00 00 44 03 00 00 46 03 00 00 +0x744b0b79bae0: 48 03 00 00 4a 03 00 00 4c 03 00 00 4e 03 00 00 +0x744b0b79baf0: 50 03 00 00 52 03 00 00 54 03 00 00 56 03 00 00 +0x744b0b79bb00: 58 03 00 00 5a 03 00 00 5c 03 00 00 5e 03 00 00 +0x744b0b79bb10: 60 03 00 00 62 03 00 00 64 03 00 00 66 03 00 00 +0x744b0b79bb20: 68 03 00 00 6a 03 00 00 6c 03 00 00 6e 03 00 00 +0x744b0b79bb30: 70 03 00 00 72 03 00 00 74 03 00 00 76 03 00 00 +0x744b0b79bb40: 78 03 00 00 7a 03 00 00 7c 03 00 00 7e 03 00 00 +0x744b0b79bb50: 80 03 00 00 82 03 00 00 84 03 00 00 86 03 00 00 +0x744b0b79bb60: 88 03 00 00 8a 03 00 00 8c 03 00 00 8e 03 00 00 +0x744b0b79bb70: 90 03 00 00 92 03 00 00 94 03 00 00 96 03 00 00 +0x744b0b79bb80: 98 03 00 00 9a 03 00 00 9c 03 00 00 9e 03 00 00 +0x744b0b79bb90: a0 03 00 00 a2 03 00 00 a4 03 00 00 a6 03 00 00 +0x744b0b79bba0: a8 03 00 00 aa 03 00 00 ac 03 00 00 ae 03 00 00 +0x744b0b79bbb0: b0 03 00 00 b2 03 00 00 b4 03 00 00 b6 03 00 00 +0x744b0b79bbc0: b8 03 00 00 ba 03 00 00 bc 03 00 00 be 03 00 00 +0x744b0b79bbd0: c0 03 00 00 c2 03 00 00 c4 03 00 00 c6 03 00 00 +0x744b0b79bbe0: c8 03 00 00 ca 03 00 00 cc 03 00 00 ce 03 00 00 +0x744b0b79bbf0: d0 03 00 00 d2 03 00 00 d4 03 00 00 d6 03 00 00 +0x744b0b79bc00: d8 03 00 00 da 03 00 00 dc 03 00 00 de 03 00 00 +0x744b0b79bc10: e0 03 00 00 e2 03 00 00 e4 03 00 00 e6 03 00 00 +-------------------------------- +new free header: +size: 410560 +-------------------------------- + + + + + +after realloc a: + + + + +-------------------------------- +new tiny zone: +size: 12288 +-------------------------------- +-------------------------------- +new free header: +size: 12224 +-------------------------------- +-------------------------------- +new small zone: +size: 413696 +-------------------------------- +-------------------------------- +new allocated header: +size: 1008 +-------------------------------- +0x744b0b79b040: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b050: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b060: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b070: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b080: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b090: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0a0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0b0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0c0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b0f0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b100: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b110: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b120: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b130: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b140: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b150: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b160: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b170: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b180: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b190: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1a0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1b0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1c0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b1f0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b200: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b210: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b220: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b230: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b240: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b250: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b260: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b270: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b280: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b290: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2a0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2b0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2c0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b2f0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b300: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b310: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b320: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b330: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b340: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b350: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b360: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b370: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b380: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b390: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3a0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3b0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3c0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b3f0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b400: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b410: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +0x744b0b79b420: aa aa aa aa aa aa aa aa 00 00 00 00 00 00 00 00 +-------------------------------- +new allocated header: +size: 2000 +-------------------------------- +0x744b0b79b450: 00 00 00 00 02 00 00 00 04 00 00 00 06 00 00 00 +0x744b0b79b460: 08 00 00 00 0a 00 00 00 0c 00 00 00 0e 00 00 00 +0x744b0b79b470: 10 00 00 00 12 00 00 00 14 00 00 00 16 00 00 00 +0x744b0b79b480: 18 00 00 00 1a 00 00 00 1c 00 00 00 1e 00 00 00 +0x744b0b79b490: 20 00 00 00 22 00 00 00 24 00 00 00 26 00 00 00 +0x744b0b79b4a0: 28 00 00 00 2a 00 00 00 2c 00 00 00 2e 00 00 00 +0x744b0b79b4b0: 30 00 00 00 32 00 00 00 34 00 00 00 36 00 00 00 +0x744b0b79b4c0: 38 00 00 00 3a 00 00 00 3c 00 00 00 3e 00 00 00 +0x744b0b79b4d0: 40 00 00 00 42 00 00 00 44 00 00 00 46 00 00 00 +0x744b0b79b4e0: 48 00 00 00 4a 00 00 00 4c 00 00 00 4e 00 00 00 +0x744b0b79b4f0: 50 00 00 00 52 00 00 00 54 00 00 00 56 00 00 00 +0x744b0b79b500: 58 00 00 00 5a 00 00 00 5c 00 00 00 5e 00 00 00 +0x744b0b79b510: 60 00 00 00 62 00 00 00 64 00 00 00 66 00 00 00 +0x744b0b79b520: 68 00 00 00 6a 00 00 00 6c 00 00 00 6e 00 00 00 +0x744b0b79b530: 70 00 00 00 72 00 00 00 74 00 00 00 76 00 00 00 +0x744b0b79b540: 78 00 00 00 7a 00 00 00 7c 00 00 00 7e 00 00 00 +0x744b0b79b550: 80 00 00 00 82 00 00 00 84 00 00 00 86 00 00 00 +0x744b0b79b560: 88 00 00 00 8a 00 00 00 8c 00 00 00 8e 00 00 00 +0x744b0b79b570: 90 00 00 00 92 00 00 00 94 00 00 00 96 00 00 00 +0x744b0b79b580: 98 00 00 00 9a 00 00 00 9c 00 00 00 9e 00 00 00 +0x744b0b79b590: a0 00 00 00 a2 00 00 00 a4 00 00 00 a6 00 00 00 +0x744b0b79b5a0: a8 00 00 00 aa 00 00 00 ac 00 00 00 ae 00 00 00 +0x744b0b79b5b0: b0 00 00 00 b2 00 00 00 b4 00 00 00 b6 00 00 00 +0x744b0b79b5c0: b8 00 00 00 ba 00 00 00 bc 00 00 00 be 00 00 00 +0x744b0b79b5d0: c0 00 00 00 c2 00 00 00 c4 00 00 00 c6 00 00 00 +0x744b0b79b5e0: c8 00 00 00 ca 00 00 00 cc 00 00 00 ce 00 00 00 +0x744b0b79b5f0: d0 00 00 00 d2 00 00 00 d4 00 00 00 d6 00 00 00 +0x744b0b79b600: d8 00 00 00 da 00 00 00 dc 00 00 00 de 00 00 00 +0x744b0b79b610: e0 00 00 00 e2 00 00 00 e4 00 00 00 e6 00 00 00 +0x744b0b79b620: e8 00 00 00 ea 00 00 00 ec 00 00 00 ee 00 00 00 +0x744b0b79b630: f0 00 00 00 f2 00 00 00 f4 00 00 00 f6 00 00 00 +0x744b0b79b640: f8 00 00 00 fa 00 00 00 fc 00 00 00 fe 00 00 00 +0x744b0b79b650: 00 01 00 00 02 01 00 00 04 01 00 00 06 01 00 00 +0x744b0b79b660: 08 01 00 00 0a 01 00 00 0c 01 00 00 0e 01 00 00 +0x744b0b79b670: 10 01 00 00 12 01 00 00 14 01 00 00 16 01 00 00 +0x744b0b79b680: 18 01 00 00 1a 01 00 00 1c 01 00 00 1e 01 00 00 +0x744b0b79b690: 20 01 00 00 22 01 00 00 24 01 00 00 26 01 00 00 +0x744b0b79b6a0: 28 01 00 00 2a 01 00 00 2c 01 00 00 2e 01 00 00 +0x744b0b79b6b0: 30 01 00 00 32 01 00 00 34 01 00 00 36 01 00 00 +0x744b0b79b6c0: 38 01 00 00 3a 01 00 00 3c 01 00 00 3e 01 00 00 +0x744b0b79b6d0: 40 01 00 00 42 01 00 00 44 01 00 00 46 01 00 00 +0x744b0b79b6e0: 48 01 00 00 4a 01 00 00 4c 01 00 00 4e 01 00 00 +0x744b0b79b6f0: 50 01 00 00 52 01 00 00 54 01 00 00 56 01 00 00 +0x744b0b79b700: 58 01 00 00 5a 01 00 00 5c 01 00 00 5e 01 00 00 +0x744b0b79b710: 60 01 00 00 62 01 00 00 64 01 00 00 66 01 00 00 +0x744b0b79b720: 68 01 00 00 6a 01 00 00 6c 01 00 00 6e 01 00 00 +0x744b0b79b730: 70 01 00 00 72 01 00 00 74 01 00 00 76 01 00 00 +0x744b0b79b740: 78 01 00 00 7a 01 00 00 7c 01 00 00 7e 01 00 00 +0x744b0b79b750: 80 01 00 00 82 01 00 00 84 01 00 00 86 01 00 00 +0x744b0b79b760: 88 01 00 00 8a 01 00 00 8c 01 00 00 8e 01 00 00 +0x744b0b79b770: 90 01 00 00 92 01 00 00 94 01 00 00 96 01 00 00 +0x744b0b79b780: 98 01 00 00 9a 01 00 00 9c 01 00 00 9e 01 00 00 +0x744b0b79b790: a0 01 00 00 a2 01 00 00 a4 01 00 00 a6 01 00 00 +0x744b0b79b7a0: a8 01 00 00 aa 01 00 00 ac 01 00 00 ae 01 00 00 +0x744b0b79b7b0: b0 01 00 00 b2 01 00 00 b4 01 00 00 b6 01 00 00 +0x744b0b79b7c0: b8 01 00 00 ba 01 00 00 bc 01 00 00 be 01 00 00 +0x744b0b79b7d0: c0 01 00 00 c2 01 00 00 c4 01 00 00 c6 01 00 00 +0x744b0b79b7e0: c8 01 00 00 ca 01 00 00 cc 01 00 00 ce 01 00 00 +0x744b0b79b7f0: d0 01 00 00 d2 01 00 00 d4 01 00 00 d6 01 00 00 +0x744b0b79b800: d8 01 00 00 da 01 00 00 dc 01 00 00 de 01 00 00 +0x744b0b79b810: e0 01 00 00 e2 01 00 00 e4 01 00 00 e6 01 00 00 +0x744b0b79b820: e8 01 00 00 ea 01 00 00 ec 01 00 00 ee 01 00 00 +0x744b0b79b830: f0 01 00 00 f2 01 00 00 f4 01 00 00 f6 01 00 00 +0x744b0b79b840: f8 01 00 00 fa 01 00 00 fc 01 00 00 fe 01 00 00 +0x744b0b79b850: 00 02 00 00 02 02 00 00 04 02 00 00 06 02 00 00 +0x744b0b79b860: 08 02 00 00 0a 02 00 00 0c 02 00 00 0e 02 00 00 +0x744b0b79b870: 10 02 00 00 12 02 00 00 14 02 00 00 16 02 00 00 +0x744b0b79b880: 18 02 00 00 1a 02 00 00 1c 02 00 00 1e 02 00 00 +0x744b0b79b890: 20 02 00 00 22 02 00 00 24 02 00 00 26 02 00 00 +0x744b0b79b8a0: 28 02 00 00 2a 02 00 00 2c 02 00 00 2e 02 00 00 +0x744b0b79b8b0: 30 02 00 00 32 02 00 00 34 02 00 00 36 02 00 00 +0x744b0b79b8c0: 38 02 00 00 3a 02 00 00 3c 02 00 00 3e 02 00 00 +0x744b0b79b8d0: 40 02 00 00 42 02 00 00 44 02 00 00 46 02 00 00 +0x744b0b79b8e0: 48 02 00 00 4a 02 00 00 4c 02 00 00 4e 02 00 00 +0x744b0b79b8f0: 50 02 00 00 52 02 00 00 54 02 00 00 56 02 00 00 +0x744b0b79b900: 58 02 00 00 5a 02 00 00 5c 02 00 00 5e 02 00 00 +0x744b0b79b910: 60 02 00 00 62 02 00 00 64 02 00 00 66 02 00 00 +0x744b0b79b920: 68 02 00 00 6a 02 00 00 6c 02 00 00 6e 02 00 00 +0x744b0b79b930: 70 02 00 00 72 02 00 00 74 02 00 00 76 02 00 00 +0x744b0b79b940: 78 02 00 00 7a 02 00 00 7c 02 00 00 7e 02 00 00 +0x744b0b79b950: 80 02 00 00 82 02 00 00 84 02 00 00 86 02 00 00 +0x744b0b79b960: 88 02 00 00 8a 02 00 00 8c 02 00 00 8e 02 00 00 +0x744b0b79b970: 90 02 00 00 92 02 00 00 94 02 00 00 96 02 00 00 +0x744b0b79b980: 98 02 00 00 9a 02 00 00 9c 02 00 00 9e 02 00 00 +0x744b0b79b990: a0 02 00 00 a2 02 00 00 a4 02 00 00 a6 02 00 00 +0x744b0b79b9a0: a8 02 00 00 aa 02 00 00 ac 02 00 00 ae 02 00 00 +0x744b0b79b9b0: b0 02 00 00 b2 02 00 00 b4 02 00 00 b6 02 00 00 +0x744b0b79b9c0: b8 02 00 00 ba 02 00 00 bc 02 00 00 be 02 00 00 +0x744b0b79b9d0: c0 02 00 00 c2 02 00 00 c4 02 00 00 c6 02 00 00 +0x744b0b79b9e0: c8 02 00 00 ca 02 00 00 cc 02 00 00 ce 02 00 00 +0x744b0b79b9f0: d0 02 00 00 d2 02 00 00 d4 02 00 00 d6 02 00 00 +0x744b0b79ba00: d8 02 00 00 da 02 00 00 dc 02 00 00 de 02 00 00 +0x744b0b79ba10: e0 02 00 00 e2 02 00 00 e4 02 00 00 e6 02 00 00 +0x744b0b79ba20: e8 02 00 00 ea 02 00 00 ec 02 00 00 ee 02 00 00 +0x744b0b79ba30: f0 02 00 00 f2 02 00 00 f4 02 00 00 f6 02 00 00 +0x744b0b79ba40: f8 02 00 00 fa 02 00 00 fc 02 00 00 fe 02 00 00 +0x744b0b79ba50: 00 03 00 00 02 03 00 00 04 03 00 00 06 03 00 00 +0x744b0b79ba60: 08 03 00 00 0a 03 00 00 0c 03 00 00 0e 03 00 00 +0x744b0b79ba70: 10 03 00 00 12 03 00 00 14 03 00 00 16 03 00 00 +0x744b0b79ba80: 18 03 00 00 1a 03 00 00 1c 03 00 00 1e 03 00 00 +0x744b0b79ba90: 20 03 00 00 22 03 00 00 24 03 00 00 26 03 00 00 +0x744b0b79baa0: 28 03 00 00 2a 03 00 00 2c 03 00 00 2e 03 00 00 +0x744b0b79bab0: 30 03 00 00 32 03 00 00 34 03 00 00 36 03 00 00 +0x744b0b79bac0: 38 03 00 00 3a 03 00 00 3c 03 00 00 3e 03 00 00 +0x744b0b79bad0: 40 03 00 00 42 03 00 00 44 03 00 00 46 03 00 00 +0x744b0b79bae0: 48 03 00 00 4a 03 00 00 4c 03 00 00 4e 03 00 00 +0x744b0b79baf0: 50 03 00 00 52 03 00 00 54 03 00 00 56 03 00 00 +0x744b0b79bb00: 58 03 00 00 5a 03 00 00 5c 03 00 00 5e 03 00 00 +0x744b0b79bb10: 60 03 00 00 62 03 00 00 64 03 00 00 66 03 00 00 +0x744b0b79bb20: 68 03 00 00 6a 03 00 00 6c 03 00 00 6e 03 00 00 +0x744b0b79bb30: 70 03 00 00 72 03 00 00 74 03 00 00 76 03 00 00 +0x744b0b79bb40: 78 03 00 00 7a 03 00 00 7c 03 00 00 7e 03 00 00 +0x744b0b79bb50: 80 03 00 00 82 03 00 00 84 03 00 00 86 03 00 00 +0x744b0b79bb60: 88 03 00 00 8a 03 00 00 8c 03 00 00 8e 03 00 00 +0x744b0b79bb70: 90 03 00 00 92 03 00 00 94 03 00 00 96 03 00 00 +0x744b0b79bb80: 98 03 00 00 9a 03 00 00 9c 03 00 00 9e 03 00 00 +0x744b0b79bb90: a0 03 00 00 a2 03 00 00 a4 03 00 00 a6 03 00 00 +0x744b0b79bba0: a8 03 00 00 aa 03 00 00 ac 03 00 00 ae 03 00 00 +0x744b0b79bbb0: b0 03 00 00 b2 03 00 00 b4 03 00 00 b6 03 00 00 +0x744b0b79bbc0: b8 03 00 00 ba 03 00 00 bc 03 00 00 be 03 00 00 +0x744b0b79bbd0: c0 03 00 00 c2 03 00 00 c4 03 00 00 c6 03 00 00 +0x744b0b79bbe0: c8 03 00 00 ca 03 00 00 cc 03 00 00 ce 03 00 00 +0x744b0b79bbf0: d0 03 00 00 d2 03 00 00 d4 03 00 00 d6 03 00 00 +0x744b0b79bc00: d8 03 00 00 da 03 00 00 dc 03 00 00 de 03 00 00 +0x744b0b79bc10: e0 03 00 00 e2 03 00 00 e4 03 00 00 e6 03 00 00 +-------------------------------- +new allocated header: +size: 432 +-------------------------------- +0x744b0b79bc40: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +0x744b0b79bc50: 10 11 12 13 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bc60: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bc70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bc90: 50 43 06 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bca0: 00 b0 79 0b 4b 74 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bcb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bcc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bcd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bcf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bd90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bda0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bdb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bdc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bdd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0x744b0b79bde0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +-------------------------------- +new free header: +size: 410096 +-------------------------------- +-------------------------------- +new tiny zone: +size: 12288 +-------------------------------- +-------------------------------- +new free header: +size: 12224 +-------------------------------- +-------------------------------- +new small zone: +size: 413696 +-------------------------------- +-------------------------------- +new free header: +size: 413632 +-------------------------------- diff --git a/srcs/bonus_utils.c b/srcs/bonus_utils.c new file mode 100644 index 0000000..bd90f25 --- /dev/null +++ b/srcs/bonus_utils.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* bonus_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/28 16:42:13 by thrieg #+# #+# */ +/* Updated: 2025/11/28 18:25:49 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/ft_malloc.h" +#include "../libft/ft_printf/ft_printf.h" + +// bytes_per_line has to be a power of 2 +static void hexdump_block(void *addr, size_t size, size_t bytes_per_Line) +{ + unsigned char *p = (unsigned char *)addr; + uintptr_t start = (uintptr_t)p; + uintptr_t end = start + size; + + // align down to bytes_per_Line bytes + uintptr_t line_start = start & ~(uintptr_t)(bytes_per_Line - 1); + + while (line_start < end) + { + ft_printf("%p: ", (void *)line_start); + + for (size_t i = 0; i < bytes_per_Line; ++i) + { + uintptr_t pos = line_start + (uintptr_t)i; + + if (pos < start || pos >= end) + { + // outside the block; print spaces to keep alignment + ft_printf(" "); + } + else + { + unsigned char byte = *(unsigned char *)pos; + ft_printf("%02x ", (unsigned int)byte); + } + } + ft_printf("\n"); + line_start += bytes_per_Line; + } +} + +void print_zone(t_zone *zone, bool hexdump_free_zones) +{ + ft_printf("--------------------------------\n"); + ft_printf("new %s zone:\n", zone->type == E_TINY ? "tiny" : (zone->type == E_SMALL ? "small" : "large")); + ft_printf("size: %u\n", (unsigned int)zone->size); + ft_printf("--------------------------------\n"); + + char *zone_end = (char *)zone + zone->size; + t_header *header = (t_header *)(zone + 1); + while ((char *)header + sizeof(t_header) <= zone_end) + { + ft_printf("--------------------------------\n"); + ft_printf("new %s header:\n", header->occupied ? "allocated" : "free"); + ft_printf("size: %u\n", (unsigned int)header->size); + ft_printf("--------------------------------\n"); + if (header->occupied || hexdump_free_zones) + hexdump_block(header + 1, header->size, 16); + header = (t_header *)((char *)(header + 1) + header->size); + } +} + +void print_all_zones(t_zone *first_zone, bool hexdump_free_zones) +{ + while (first_zone) + { + print_zone(first_zone, hexdump_free_zones); + first_zone = first_zone->next; + } +} + +void show_alloc_mem_ex(bool hexdump_free_zones) +{ + print_all_zones(g_state.tiny_zone, hexdump_free_zones); + print_all_zones(g_state.small_zone, hexdump_free_zones); + print_all_zones(g_state.large_zone, hexdump_free_zones); +} diff --git a/srcs/bonus_utils.o b/srcs/bonus_utils.o new file mode 100644 index 0000000..63358b8 Binary files /dev/null and b/srcs/bonus_utils.o differ diff --git a/srcs/ft_calloc.c b/srcs/ft_calloc.c new file mode 100644 index 0000000..bfcbcf2 --- /dev/null +++ b/srcs/ft_calloc.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_calloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/25 11:47:16 by thrieg #+# #+# */ +/* Updated: 2025/11/28 16:41:16 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/ft_malloc.h" + +void *calloc(size_t nmemb, size_t size) +{ + size_t real_size = nmemb * size; + void *malloc_ret; + + if (real_size % ALLIGN_BYTES) + real_size = ((real_size / ALLIGN_BYTES) + 1) * ALLIGN_BYTES; + malloc_ret = malloc(real_size); + if (!malloc_ret) + return (NULL); + // pthread_mutex_lock(&g_mut); + ft_memset(malloc_ret, 0, real_size); // no need to lock because pointer is internal until we return it, user can't call any of our function on it + // pthread_mutex_unlock(&g_mut); + return (malloc_ret); +} diff --git a/srcs/ft_calloc.o b/srcs/ft_calloc.o new file mode 100644 index 0000000..56a0ec3 Binary files /dev/null and b/srcs/ft_calloc.o differ diff --git a/srcs/ft_free.c b/srcs/ft_free.c new file mode 100644 index 0000000..52abc7e --- /dev/null +++ b/srcs/ft_free.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/19 15:44:05 by thrieg #+# #+# */ +/* Updated: 2025/11/25 16:21:10 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/ft_malloc.h" + +// returns non-0 (1) when the function munmap the zone +int defrag_zone(t_zone *zone) +{ + t_header *header = (t_header *)(zone + 1); + char *last_adr = ((char *)zone) + zone->size - sizeof(t_header); + while ((((char *)header) + header->size) < last_adr) + { + t_header *next_header = (t_header *)(((char *)header) + sizeof(t_header) + header->size); + if (!header->occupied && !next_header->occupied) + { + header->size = header->size + sizeof(t_header) + next_header->size; + } + else + { + header = next_header; + } + } + // if only 1 free header left, mmunmap the zone + if (header == (t_header *)(zone + 1) && !header->occupied) + { + if (zone->type == E_SMALL) + { + if (g_state.small_zone == zone) + { + if (zone->next) + g_state.small_zone = zone->next; + else + return (0); // last small zone, don't deallocate to avoid mmap stress + } + } + else if (zone->type == E_TINY) + { + if (g_state.tiny_zone == zone) + { + if (zone->next) + g_state.tiny_zone = zone->next; + else + return (0); // last tiny zone, don't deallocate to avoid mmap stress + } + } + if (zone->prev) + zone->prev->next = zone->next; + if (zone->next) + zone->next->prev = zone->prev; + munmap(zone, zone->size); + return (1); + } + return (0); +} + +void free(void *ptr) +{ + pthread_mutex_lock(&g_mut); + if (!ptr) + return ((void)pthread_mutex_unlock(&g_mut)); + t_header *header = ((t_header *)ptr) - 1; + if (header->zone->type == E_LARGE) + { + if (header->zone->prev) + header->zone->prev->next = header->zone->next; + if (header->zone->next) + header->zone->next->prev = header->zone->prev; + if (header->zone == g_state.large_zone) + { + if (g_state.large_zone->next) + g_state.large_zone = g_state.large_zone->next; + else + g_state.large_zone = NULL; + } + void *ptr = header->zone; + size_t len = header->zone->size; + munmap(ptr, len); + } + else if (header->zone->type == E_SMALL) + { + header->occupied = false; + defrag_zone(header->zone); + } + else if (header->zone->type == E_TINY) + { + header->occupied = false; + defrag_zone(header->zone); + } + pthread_mutex_unlock(&g_mut); +} diff --git a/srcs/ft_free.o b/srcs/ft_free.o new file mode 100644 index 0000000..0b60984 Binary files /dev/null and b/srcs/ft_free.o differ diff --git a/srcs/ft_malloc.c b/srcs/ft_malloc.c new file mode 100644 index 0000000..099d2fe --- /dev/null +++ b/srcs/ft_malloc.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_malloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/17 15:02:55 by thrieg #+# #+# */ +/* Updated: 2025/11/25 14:30:44 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/ft_malloc.h" + +void *malloc(size_t size) +{ + pthread_mutex_lock(&g_mut); + if (!size || size % ALLIGN_BYTES) + size = ((size / ALLIGN_BYTES) + 1) * ALLIGN_BYTES; + void *ret = NULL; + if (size > SMALL_SIZE_MAX) + { + ret = add_large(size); + } + else if (size > TINY_SIZE_MAX) + { + ret = add_small(size); + } + else + { + ret = add_tiny(size); + } + pthread_mutex_unlock(&g_mut); + return (ret); +} diff --git a/srcs/ft_malloc.o b/srcs/ft_malloc.o new file mode 100644 index 0000000..2ddfc4a Binary files /dev/null and b/srcs/ft_malloc.o differ diff --git a/srcs/ft_realloc.c b/srcs/ft_realloc.c new file mode 100644 index 0000000..98df6c3 --- /dev/null +++ b/srcs/ft_realloc.c @@ -0,0 +1,146 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_realloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/25 11:47:23 by thrieg #+# #+# */ +/* Updated: 2025/11/28 16:37:22 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/ft_malloc.h" + +// returns non-0 (1) is the zone changes type to a higher type (tiny to small or small to large) +static bool is_upgraded(size_t size, t_type current_type) +{ + if (size > SMALL_SIZE_MAX && current_type != E_LARGE) + return (1); + else if (size > TINY_SIZE_MAX && current_type != E_SMALL) + return (1); + else + return (0); +} + +void *realloc(void *ptr, size_t size) +{ + if (size == 0) + { + free(ptr); + return (NULL); + } + else if (!ptr) + { + return (malloc(size)); + } + size_t original_size = size; + if (size % ALLIGN_BYTES) + size = ((size / ALLIGN_BYTES) + 1) * ALLIGN_BYTES; + void *ret = NULL; + pthread_mutex_lock(&g_mut); + t_header *header = ((t_header *)ptr) - 1; + if (header->zone->type == E_LARGE) + { + pthread_mutex_unlock(&g_mut); + ret = malloc(size); + if (!ret) + return (NULL); + pthread_mutex_lock(&g_mut); + if (original_size > header->size) + ft_memcpy(ret, ptr, header->size); // if grow, copy the entire last buffer + else + ft_memcpy(ret, ptr, original_size); // if shrink, copy the new amount of bytes from older buffer + pthread_mutex_unlock(&g_mut); + free(ptr); + pthread_mutex_lock(&g_mut); + } + else if (is_upgraded(size, header->zone->type)) + { + pthread_mutex_unlock(&g_mut); + ret = malloc(size); + if (!ret) + return (NULL); + pthread_mutex_lock(&g_mut); + if (original_size > header->size) + ft_memcpy(ret, ptr, header->size); // if grow, copy the entire last buffer + else + ft_memcpy(ret, ptr, original_size); // if shrink, copy the new amount of bytes from older buffer + pthread_mutex_unlock(&g_mut); + free(ptr); + pthread_mutex_lock(&g_mut); + } + else if (header->zone->type == E_SMALL || header->zone->type == E_TINY) + { + t_header *next_header = (t_header *)(((char *)header) + sizeof(t_header) + header->size); + if ((char *)next_header > (((char *)header->zone) + header->zone->size - sizeof(t_header))) + next_header = NULL; // next header out of the zone + if (size > header->size) + { + if (next_header && !next_header->occupied && (header->size + next_header->size + sizeof(t_header)) >= size) + { + const size_t available_space = (header->size + next_header->size + sizeof(t_header)); + if (available_space - size > sizeof(t_header)) + { + // Split the block: create a new header in the remaining space + char *new_addr = (char *)(header + 1) + size; + t_header *newhdr = (t_header *)new_addr; + + newhdr->size = available_space - size - sizeof(t_header); + newhdr->occupied = false; + newhdr->zone = header->zone; + + header->size = size; + } + else + { + header->size = available_space; + } + ret = ptr; + } + else + { + pthread_mutex_unlock(&g_mut); + ret = malloc(size); + if (!ret) + return (NULL); + pthread_mutex_lock(&g_mut); + if (original_size > header->size) + ft_memcpy(ret, ptr, header->size); // if grow, copy the entire last buffer + else + ft_memcpy(ret, ptr, original_size); // if shrink, copy the new amount of bytes from older buffer + pthread_mutex_unlock(&g_mut); + free(ptr); + pthread_mutex_lock(&g_mut); + } + } + else + { + ret = ptr; // in all case we just return the original ptr, rest is just internal logic + size_t available_space = header->size - size; // zones are defragmented so all available contiguous space must be in a single header + if (next_header && !next_header->occupied) + available_space += next_header->size + sizeof(t_header); + if (available_space > sizeof(t_header)) + { + if (available_space > sizeof(t_header)) + { + // Split the block: create a new header in the remaining space + char *new_addr = (char *)(header + 1) + size; + t_header *newhdr = (t_header *)new_addr; + + newhdr->size = available_space - sizeof(t_header); + newhdr->occupied = false; + newhdr->zone = header->zone; + + header->size = size; + } + else + { + header->size = available_space; + } + } + } + } + pthread_mutex_unlock(&g_mut); + return (ret); +} diff --git a/srcs/ft_realloc.o b/srcs/ft_realloc.o new file mode 100644 index 0000000..cedb7e1 Binary files /dev/null and b/srcs/ft_realloc.o differ diff --git a/srcs/init_state.c b/srcs/init_state.c new file mode 100644 index 0000000..cc82718 --- /dev/null +++ b/srcs/init_state.c @@ -0,0 +1,267 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init_state.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/18 16:44:13 by thrieg #+# #+# */ +/* Updated: 2025/11/28 16:41:55 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/ft_malloc.h" + +pthread_mutex_t g_mut = PTHREAD_MUTEX_INITIALIZER; +t_state g_state = {.tiny_zone = NULL, .small_zone = NULL, .large_zone = NULL}; + +// only call this for TINY or SMALL +void *add_page(t_type type) +{ + size_t size; + if (type == E_TINY) + size = ((((((TINY_SIZE_MAX + sizeof(t_header)) * 100) + sizeof(t_zone))) / getpagesize()) + 1) * getpagesize(); + else if (type == E_SMALL) + size = ((((((SMALL_SIZE_MAX + sizeof(t_header)) * 100) + sizeof(t_zone))) / getpagesize()) + 1) * getpagesize(); + else + return (NULL); // TODO handle error somehow + t_zone *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + return (NULL); + ptr->size = size; + if (type == E_TINY) + { + ptr->type = E_TINY; + ptr->prev = NULL; + t_header *header = (t_header *)(ptr + 1); + header->occupied = false; + header->size = size - sizeof(t_zone) - sizeof(t_header); + header->zone = ptr; + ptr->next = g_state.tiny_zone; // tiny_zone can be NULL but that's fine + if (g_state.tiny_zone) + g_state.tiny_zone->prev = ptr; + g_state.tiny_zone = ptr; + } + else if (type == E_SMALL) + { + ptr->type = E_SMALL; + ptr->prev = NULL; + t_header *header = (t_header *)(ptr + 1); + header->occupied = false; + header->size = size - sizeof(t_zone) - sizeof(t_header); + header->zone = ptr; + ptr->next = g_state.small_zone; // small_zone can be NULL but that's fine + if (g_state.small_zone) + g_state.small_zone->prev = ptr; + g_state.small_zone = ptr; + } + return (ptr); +} + +// returns the start of the buffer (returned by malloc) +void *add_large(size_t size) +{ + size = (((size + sizeof(t_header) + sizeof(t_zone)) / getpagesize()) + 1) * getpagesize(); + t_zone *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + return (NULL); + ptr->size = size; + ptr->type = E_LARGE; + ptr->prev = NULL; + ptr->next = g_state.large_zone; // large_zone can be NULL but that's fine + if (g_state.large_zone) + g_state.large_zone->prev = ptr; + g_state.large_zone = ptr; + t_header *header = (t_header *)(ptr + 1); + header->occupied = true; + header->size = size - sizeof(t_zone) - sizeof(t_header); + header->zone = ptr; + return ((void *)(header + 1)); +} + +// returns the start of the buffer (returned by malloc) +// size has to be alligned +void *add_small(size_t size) +{ + t_zone *zone; + t_header *hdr; + void *result = NULL; + + zone = g_state.small_zone; + while (zone && !result) + { + char *zone_start = (char *)zone; + char *zone_end = zone_start + zone->size; + + // First header is right after the zone struct + hdr = (t_header *)(zone + 1); + + while ((char *)hdr + sizeof(t_header) <= zone_end) + { + if (!hdr->occupied && hdr->size >= size) + { + // Found a free block big enough + size_t remaining = hdr->size - size; + + if (remaining > sizeof(t_header)) + { + // Split the block: create a new header in the remaining space + char *new_addr = (char *)(hdr + 1) + size; + t_header *newhdr = (t_header *)new_addr; + + newhdr->size = remaining - sizeof(t_header); + newhdr->occupied = false; + newhdr->zone = zone; + + hdr->size = size; + } + // else: not enough room for another header, we just don't touch the size + + hdr->occupied = true; + result = (void *)(hdr + 1); + break; + } + + char *next_addr = (char *)(hdr + 1) + hdr->size; + + // If there's no room for another valid header, stop. + if (next_addr + sizeof(t_header) > zone_end) + break; + + hdr = (t_header *)next_addr; + } + + zone = zone->next; + } + + if (result) + return result; + + // not enough room, create a new page + zone = (t_zone *)add_page(E_SMALL); + if (!zone) + return (NULL); + + hdr = (t_header *)(zone + 1); + + if (hdr->size >= size) + { + size_t remaining = hdr->size - size; + + if (remaining > sizeof(t_header)) // should always be true (enough room for 100 allocs in a page) + { + char *new_addr = (char *)(hdr + 1) + size; + t_header *newhdr = (t_header *)new_addr; + + newhdr->size = remaining - sizeof(t_header); + newhdr->occupied = false; + newhdr->zone = zone; + + hdr->size = size; + } + hdr->occupied = true; + result = (void *)(hdr + 1); + } + else + { + // wtf, not possible, but nice to handle I guess + result = NULL; + } + + return (result); +} + +// returns the start of the buffer (returned by malloc) +// size has to be alligned +void *add_tiny(size_t size) +{ + t_zone *zone; + t_header *hdr; + void *result = NULL; + + zone = g_state.tiny_zone; + while (zone && !result) + { + char *zone_start = (char *)zone; + char *zone_end = zone_start + zone->size; + + // First header is right after the zone struct + hdr = (t_header *)(zone + 1); + + while ((char *)hdr + sizeof(t_header) <= zone_end) + { + if (!hdr->occupied && hdr->size >= size) + { + // Found a free block big enough + size_t remaining = hdr->size - size; + + if (remaining > sizeof(t_header)) + { + // Split the block: create a new header in the remaining space + char *new_addr = (char *)(hdr + 1) + size; + t_header *newhdr = (t_header *)new_addr; + + newhdr->size = remaining - sizeof(t_header); + newhdr->occupied = false; + newhdr->zone = zone; + + hdr->size = size; + } + // else: not enough room for another header, we just + + hdr->occupied = true; + result = (void *)(hdr + 1); + break; + } + + char *next_addr = (char *)(hdr + 1) + hdr->size; + + // If there's no room for another valid header, stop. + if (next_addr + sizeof(t_header) > zone_end) + break; + + hdr = (t_header *)next_addr; + } + + zone = zone->next; + } + + if (result) + return result; + + // not enough room, create a new page + zone = (t_zone *)add_page(E_TINY); + if (!zone) + return (NULL); + + hdr = (t_header *)(zone + 1); + + // hdr->size should always be >= size here + if (hdr->size >= size) + { + size_t remaining = hdr->size - size; + + if (remaining > sizeof(t_header)) // should always be true (enough room for 100 allocs in a page) + { + char *new_addr = (char *)(hdr + 1) + size; + t_header *newhdr = (t_header *)new_addr; + + newhdr->size = remaining - sizeof(t_header); + newhdr->occupied = false; + newhdr->zone = zone; + + hdr->size = size; + } + hdr->occupied = true; + result = (void *)(hdr + 1); + } + else + { + // wtf, not possible, but nice to handle I guess + result = NULL; + } + + return (result); +} diff --git a/srcs/init_state.o b/srcs/init_state.o new file mode 100644 index 0000000..3cc3cef Binary files /dev/null and b/srcs/init_state.o differ diff --git a/test_malloc b/test_malloc new file mode 100755 index 0000000..7c63b0b Binary files /dev/null and b/test_malloc differ diff --git a/test_show b/test_show new file mode 100755 index 0000000..af191f2 Binary files /dev/null and b/test_show differ