diff --git a/.gitignore b/.gitignore index 3a271bd..a301abd 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ dkms.conf # Executable push_swap +checker # File obj obj/ diff --git a/Makefile b/Makefile index 4929b90..dded088 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ COMPLEX_DIR = radix FLAGS_DIR = flags -CHECKER_DIR = checker +CHECKER_DIR = check_error INCLUDES = includes @@ -32,7 +32,7 @@ INSERTION = insertion.c FLAGS_FILES = algorithms_sort.c flag.c bench.c -PARSING = ft_atoi.c parsing.c ft_strncmp.c ft_split.c ft_strlen.c ft_substr.c checker.c ft_itoa.c ft_isdigit.c \ +PARSING = ft_atoi.c parsing.c ft_strncmp.c ft_split.c ft_strlen.c ft_substr.c ft_itoa.c ft_isdigit.c \ ft_strjoin.c ft_strlcat.c ft_strlcpy.c parsing_2.c disorder.c CHECKER_FILES = check_error.c verif_flag.c verif_is_digit.c verif_overflow.c verif_double.c @@ -65,7 +65,33 @@ NAME = push_swap OBJ = $(addprefix $(OBJ_DIR)/, $(notdir $(ALL_FILES:.c=.o))) DEP = $(OBJ:.o=.d) -.PHONY: all clean fclean re +#============================ +# BONUS CONFIG +#============================ + +BONUS_DIR = bonus + +GNL_D = GNL + +GNL_DIR = bonus/GNL + +BONUS_FILES = checker_bonus.c + +GNL_FILES = get_next_line.c get_next_line_utils.c + +SRC_FOR_BONUS = ft_putnbr.c secure_write.c + +ALL_BONUS_FILES = $(SRC_FOR_BONUS) $(BONUS_DIR)/$(BONUS_FILES) $(BONUS_DIR)/$(GNL_D)/$(GNL_FILES) \ + $(STACK_UTILS_DIR)/$(STACK_UTILS) $(PARS_DIR)/$(PARSING) \ + $(ALGO_DIR)/$(MEDIUM_DIR)/$(MEDIUM_ALGO) $(ALGO_UTILS_DIR)/$(ALGO_UTILS) \ + $(INSERT_DIR)/$(INSERTION) $(ALGO_DIR)/$(COMPLEX_DIR)/$(COMPLEX_ALGO) \ + $(FLAGS_DIR)/$(FLAGS_FILES) $(CHECKER_DIR)/$(CHECKER_FILES) + +BONUS_OBJ = $(addprefix $(OBJ_DIR)/, $(notdir $(ALL_BONUS_FILES:.c=.o))) + +NAME_BONUS = checker + +.PHONY: all clean fclean re bonus all: $(NAME) @@ -75,6 +101,12 @@ $(NAME): $(OBJ) @echo "======= PUSH SWAP COMPILED =========" @echo "====================================" +$(NAME_BONUS): $(BONUS_OBJ) + @$(CC) $(CFLAGS) $(BONUS_OBJ) -o $(NAME_BONUS) + @echo "====================================" + @echo "======= PUSH SWAP COMPILED =========" + @echo "====================================" + $(OBJ_DIR)/%.o: $(PARS_DIR)/%.c | $(OBJ_DIR) $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ @@ -102,9 +134,18 @@ $(OBJ_DIR)/%.o: $(FLAGS_DIR)/%.c | $(OBJ_DIR) $(OBJ_DIR)/%.o: $(CHECKER_DIR)/%.c | $(OBJ_DIR) $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ +$(OBJ_DIR)/%.o: $(BONUS_DIR)/%.c | $(OBJ_DIR) + $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ + +$(OBJ_DIR)/%.o: $(BONUS_DIR)/$(GNL_D)/%.c | $(OBJ_DIR) + $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ + $(OBJ_DIR)/%.o: %.c | $(OBJ_DIR) $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ +$(OBJ_DIR_BONUS)/%.o: %.c | $(OBJ_DIR_BONUS) + $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ + $(OBJ_DIR): @mkdir -p $(OBJ_DIR) @@ -116,9 +157,12 @@ clean: fclean: clean @rm -f $(NAME) + @rm -f $(NAME_BONUS) @echo "========== EXEC DELETED ============" @echo "====================================" re: fclean all +bonus: $(NAME_BONUS) + -include $(DEP) diff --git a/bonus/GNL/get_next_line.c b/bonus/GNL/get_next_line.c new file mode 100644 index 0000000..402c49d --- /dev/null +++ b/bonus/GNL/get_next_line.c @@ -0,0 +1,112 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/21 17:20:41 by dgaillet #+# #+# */ +/* Updated: 2025/11/28 13:47:15 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" +#include "parsing.h" +#include + +static int del_before_nl(char buf[BUFFER_SIZE]) +{ + int nl_i; + int i; + char *temp; + + nl_i = index_of_nl(buf, BUFFER_SIZE); + if (nl_i >= 0) + { + temp = ft_substr_gnl(buf, nl_i + 1, BUFFER_SIZE - nl_i); + if (!temp) + return (-1); + ft_bzero(buf, BUFFER_SIZE); + i = 0; + while (temp[i]) + { + buf[i] = temp[i]; + i++; + } + free(temp); + } + return (1); +} + +static char *ft_read_one(char buf[BUFFER_SIZE], int fd, char *str) +{ + int temp; + + str = ft_strjoin_new(str, buf, BUFFER_SIZE); + if (!str) + return (NULL); + ft_bzero(buf, BUFFER_SIZE); + temp = read(fd, buf, BUFFER_SIZE); + if (temp < 0) + { + free(str); + return (NULL); + } + if ((!str || ft_strlen_1(str) == 0) && temp == 0) + { + free(str); + return (NULL); + } + if (temp == 0) + return (str); + return (str); +} + +static char *extract_all_nl(char buf[BUFFER_SIZE], int fd, char *str, int nl_i) +{ + int temp; + + if (!str) + return (NULL); + while (nl_i < 0) + { + str = ft_read_one(buf, fd, str); + if (!str) + return (NULL); + nl_i = index_of_nl(buf, BUFFER_SIZE); + if (nl_i < 0 && !ft_strlen_1(buf)) + return (str); + } + str = ft_strjoin_new(str, buf, nl_i); + if (!str) + return (NULL); + temp = del_before_nl(buf); + if (temp < 0) + { + free(str); + return (NULL); + } + return (str); +} + +char *get_next_line(int fd) +{ + static char buf[BUFFER_SIZE + 1]; + int nl_i; + int temp; + char *str; + + if (fd < 0 || BUFFER_SIZE <= 0) + return (NULL); + nl_i = index_of_nl(buf, BUFFER_SIZE); + if (nl_i >= 0) + { + str = ft_substr_gnl(buf, 0, nl_i + 1); + temp = del_before_nl(buf); + if (temp < 0) + return (free(str), NULL); + } + else + str = extract_all_nl(buf, fd, ft_substr_gnl("", 0, 1), nl_i); + return (str); +} diff --git a/bonus/GNL/get_next_line_utils.c b/bonus/GNL/get_next_line_utils.c new file mode 100644 index 0000000..0dc960e --- /dev/null +++ b/bonus/GNL/get_next_line_utils.c @@ -0,0 +1,102 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/21 17:21:38 by dgaillet #+# #+# */ +/* Updated: 2025/11/27 18:06:51 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" +#include + +int index_of_nl(char *str, int limit) +{ + int i; + + if (!str) + return (-1); + i = 0; + while (i < limit && str[i]) + { + if (str[i] == '\n') + return (i); + i++; + } + return (-1); +} + +size_t ft_strlen_1(const char *s) +{ + size_t i; + + i = 0; + while (s[i]) + i++; + return (i); +} + +char *ft_strjoin_new(char const *s1, char const *s2, size_t limit) +{ + char *str; + size_t i; + size_t j; + + str = malloc(sizeof(char) * (ft_strlen_1(s1) + ft_strlen_1(s2) + 1)); + if (!str) + return (NULL); + i = 0; + j = 0; + while (s1[i]) + { + str[i] = s1[i]; + i++; + } + while (j <= limit && s2[j]) + { + str[i + j] = s2[j]; + j++; + } + str[i + j] = '\0'; + free((void *) s1); + return (str); +} + +char *ft_substr_gnl(char const *s, unsigned int start, size_t len) +{ + size_t i; + char *sub_str; + size_t s_len; + + if (!s) + return (NULL); + s_len = ft_strlen_1(s); + if (start > s_len) + len = 0; + else if (s_len < (start + len)) + len = s_len - start; + sub_str = malloc(sizeof(char) * (len + 1)); + if (!sub_str) + return (NULL); + i = 0; + while (i < len) + { + sub_str[i] = s[start + i]; + i++; + } + sub_str[i] = '\0'; + return (sub_str); +} + +void ft_bzero(void *s, size_t n) +{ + while (n > 0) + { + *((unsigned char *) s) = '\0'; + s++; + n--; + } +} diff --git a/bonus/checker_bonus.c b/bonus/checker_bonus.c new file mode 100644 index 0000000..67b54a6 --- /dev/null +++ b/bonus/checker_bonus.c @@ -0,0 +1,104 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* checker_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/01/09 11:46:36 by dgaillet #+# #+# */ +/* Updated: 2026/01/09 14:51:32 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include "push_swap.h" +#include "parsing.h" +#include "get_next_line.h" +#include "check_error.h" +#include + +static int apply_operation(t_stacks *stacks, char buf[1024]) +{ + if (!ft_strncmp("sa", buf, ft_strlen(buf))) + return (sa(stacks), 1); + if (!ft_strncmp("sb", buf, ft_strlen(buf))) + return (sb(stacks), 1); + if (!ft_strncmp("ss", buf, ft_strlen(buf))) + return (ss(stacks), 1); + if (!ft_strncmp("pa", buf, ft_strlen(buf))) + return (pa(stacks), 1); + if (!ft_strncmp("pb", buf, ft_strlen(buf))) + return (pb(stacks), 1); + if (!ft_strncmp("ra", buf, ft_strlen(buf))) + return (ra(stacks), 1); + if (!ft_strncmp("rb", buf, ft_strlen(buf))) + return (rb(stacks), 1); + if (!ft_strncmp("rr", buf, ft_strlen(buf))) + return (rr(stacks), 1); + if (!ft_strncmp("rra", buf, ft_strlen(buf))) + return (rra(stacks), 1); + if (!ft_strncmp("rrb", buf, ft_strlen(buf))) + return (rrb(stacks), 1); + if (!ft_strncmp("rrr", buf, ft_strlen(buf))) + return (rrr(stacks), 1); + return (0); +} + +static int is_stacks_b_empty(t_stacks *stacks) +{ + if (stacks->b != NULL) + return (0); + return (1); +} + +static int tester(t_stacks *stacks) +{ + char *buf; + + buf = get_next_line(0); + while (buf) + { + if (!apply_operation(stacks, buf)) + break ; + free(buf); + buf = get_next_line(0); + } + if (!is_stacks_b_empty(stacks)) + return (write(1, "KO\n", 3)); + if (!check_order(stacks->a)) + return (write(1, "KO\n", 3)); + write(1, "OK\n", 3); + return (0); +} + +static int bonus(char **tab) +{ + t_stacks *stacks; + int len; + + stacks = NULL; + len = len_split(tab); + stacks = init_stacks(len, tab, 0); + stacks->print = 0; + if (!stacks) + return (0); + tester(stacks); + free_all(stacks); + return (1); +} + +int main(int argc, char **argv) +{ + char **tab; + + if (argc < 2) + return (write(2, "Error\n", 7)); + tab = split_all(join_all(argc, argv)); + if (!tab) + return (0); + if (!check_error_bonus(tab)) + write(2, "Error\n", 7); + else + bonus(tab); + free_tab(tab); + return (0); +} diff --git a/checker/check_error.c b/check_error/check_error.c similarity index 88% rename from checker/check_error.c rename to check_error/check_error.c index c936923..05a01e0 100644 --- a/checker/check_error.c +++ b/check_error/check_error.c @@ -23,6 +23,17 @@ int verif_is_number(char **tab) return (1); } +int check_error_bonus(char **tab) +{ + if (!verif_is_digit(tab, 0)) + return (0); + if (!verif_overflow(tab, 0)) + return (0); + if (!verif_double(tab, 0)) + return (0); + return (1); +} + int check_error(char **tab, int mod) { if (!verif_flag(tab, mod)) diff --git a/checker/verif_double.c b/check_error/verif_double.c similarity index 100% rename from checker/verif_double.c rename to check_error/verif_double.c diff --git a/checker/verif_flag.c b/check_error/verif_flag.c similarity index 100% rename from checker/verif_flag.c rename to check_error/verif_flag.c diff --git a/checker/verif_is_digit.c b/check_error/verif_is_digit.c similarity index 100% rename from checker/verif_is_digit.c rename to check_error/verif_is_digit.c diff --git a/checker/verif_overflow.c b/check_error/verif_overflow.c similarity index 100% rename from checker/verif_overflow.c rename to check_error/verif_overflow.c diff --git a/includes/check_error.h b/includes/check_error.h index b6f64f1..261622c 100644 --- a/includes/check_error.h +++ b/includes/check_error.h @@ -19,5 +19,6 @@ int verif_is_digit(char **tab, int mod); int verif_overflow(char **tab, int mod); int verif_double(char **tab, int mod); int scan_str_is_digit(char *tab); +int check_error_bonus(char **tab); #endif diff --git a/includes/get_next_line.h b/includes/get_next_line.h new file mode 100644 index 0000000..81a7e8f --- /dev/null +++ b/includes/get_next_line.h @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/21 17:22:03 by dgaillet #+# #+# */ +/* Updated: 2025/11/27 18:05:13 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H + +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 42 +# endif + +# include + +char *get_next_line(int fd); + +size_t ft_strlen_1(const char *s); +char *ft_strjoin_new(char const *s1, char const *s2, size_t limit); +void ft_bzero(void *s, size_t n); +int index_of_nl(char *str, int limit); +char *ft_substr_gnl(char const *s, unsigned int start, size_t len); + +#endif diff --git a/includes/push_swap.h b/includes/push_swap.h index 0631636..9105eb4 100644 --- a/includes/push_swap.h +++ b/includes/push_swap.h @@ -26,6 +26,7 @@ typedef struct s_stacks t_stack *b; int algo; int bench; + int print; float disorder; unsigned int ra; unsigned int rb; diff --git a/parsing/parsing.c b/parsing/parsing.c index 64f2edd..68ddb8c 100644 --- a/parsing/parsing.c +++ b/parsing/parsing.c @@ -51,6 +51,7 @@ static void set_t_stacks(t_stacks *stacks) stacks->algo = 0; stacks->bench = 0; stacks->disorder = 0; + stacks->print = 1; stacks->sa = 0; stacks->sb = 0; stacks->ss = 0; diff --git a/stack_utils/push.c b/stack_utils/push.c index 63636e9..763cd72 100644 --- a/stack_utils/push.c +++ b/stack_utils/push.c @@ -31,7 +31,8 @@ void pa(t_stacks *stacks) } stack_add_front(&(stacks->a), b_push); stacks->pa++; - write(1, "pa\n", 3); + if (stacks->print) + write(1, "pa\n", 3); } void pb(t_stacks *stacks) @@ -51,5 +52,6 @@ void pb(t_stacks *stacks) } stack_add_front(&(stacks->b), a_push); stacks->pb++; - write(1, "pb\n", 3); + if (stacks->print) + write(1, "pb\n", 3); } diff --git a/stack_utils/rev_rotate.c b/stack_utils/rev_rotate.c index e575827..135bf22 100644 --- a/stack_utils/rev_rotate.c +++ b/stack_utils/rev_rotate.c @@ -26,7 +26,8 @@ void rrb(t_stacks *stacks) if (stacks && stacks->b && stacks->b->previous) stacks->b = stacks->b->previous; stacks->rrb++; - write(1, "rrb\n", 4); + if (stacks->print) + write(1, "rrb\n", 4); } void rrr(t_stacks *stacks) @@ -36,5 +37,6 @@ void rrr(t_stacks *stacks) if (stacks && stacks->a && stacks->a->previous) stacks->a = stacks->a->previous; stacks->rrr++; - write(1, "rrr\n", 4); + if (stacks->print) + write(1, "rrr\n", 4); } diff --git a/stack_utils/rotate.c b/stack_utils/rotate.c index 26d0896..922a56c 100644 --- a/stack_utils/rotate.c +++ b/stack_utils/rotate.c @@ -18,7 +18,8 @@ void ra(t_stacks *stacks) if (stacks && stacks->a && stacks->a->next) stacks->a = stacks->a->next; stacks->ra++; - write(1, "ra\n", 3); + if (stacks->print) + write(1, "ra\n", 3); } void rb(t_stacks *stacks) @@ -26,7 +27,8 @@ void rb(t_stacks *stacks) if (stacks && stacks->b && stacks->b->next) stacks->b = stacks->b->next; stacks->rb++; - write(1, "rb\n", 3); + if (stacks->print) + write(1, "rb\n", 3); } void rr(t_stacks *stacks) @@ -36,5 +38,6 @@ void rr(t_stacks *stacks) if (stacks && stacks->b && stacks->b->next) stacks->b = stacks->b->next; stacks->rr++; - write(1, "rr\n", 3); + if (stacks->print) + write(1, "rr\n", 3); } diff --git a/stack_utils/swap.c b/stack_utils/swap.c index e32e4e3..c37c468 100644 --- a/stack_utils/swap.c +++ b/stack_utils/swap.c @@ -25,7 +25,8 @@ void sa(t_stacks *stacks) a->value = a->next->value; a->next->value = stock; stacks->sa++; - write(1, "sa\n", 3); + if (stacks->print) + write(1, "sa\n", 3); } void sb(t_stacks *stacks) @@ -40,7 +41,8 @@ void sb(t_stacks *stacks) b->value = b->next->value; b->next->value = stock; stacks->sb++; - write(1, "sb\n", 3); + if (stacks->print) + write(1, "sb\n", 3); } void ss(t_stacks *stacks) @@ -66,5 +68,6 @@ void ss(t_stacks *stacks) a->next->value = stock; } stacks->ss++; - write(1, "ss\n", 3); + if (stacks->print) + write(1, "ss\n", 3); }