From 2e1bc5b5520d0ed88b0298e2224aa31644938abe Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Wed, 25 Oct 2023 15:33:14 +0200 Subject: [PATCH] Patch delete_file_node function, create bonus (copy) The function delete_file_node made the static list NULL when deleting the first entry. When there is more than a single entry in the list this leads to loss the rest of the list. When get_next_line would be called on file descriptor saved in such a "forgotten" list, it would not be able to retrieve the data previously loaded to the files buffer. Because bonus functions were implemented in the basic files, bonus files are created by their duplication. This is needed to let moulinette recognize bonus. --- get_next_line.c | 4 +- get_next_line_bonus.c | 112 ++++++++++++++++++++++++++++++++++++ get_next_line_bonus.h | 43 ++++++++++++++ get_next_line_utils_bonus.c | 110 +++++++++++++++++++++++++++++++++++ 4 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 get_next_line_bonus.c create mode 100644 get_next_line_bonus.h create mode 100644 get_next_line_utils_bonus.c diff --git a/get_next_line.c b/get_next_line.c index ebfa277..4e5cae8 100644 --- a/get_next_line.c +++ b/get_next_line.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/08/28 00:01:15 by ljiriste #+# #+# */ -/* Updated: 2023/10/13 16:01:58 by ljiriste ### ########.fr */ +/* Updated: 2023/10/25 13:06:18 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -51,7 +51,7 @@ static void delete_file_node(int fd, t_list **list) cur = cur->next; } if (prev == NULL) - *list = NULL; + *list = cur->next; else prev->next = cur->next; free(((t_ft *)(cur->content))->buffer); diff --git a/get_next_line_bonus.c b/get_next_line_bonus.c new file mode 100644 index 0000000..4e5cae8 --- /dev/null +++ b/get_next_line_bonus.c @@ -0,0 +1,112 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/28 00:01:15 by ljiriste #+# #+# */ +/* Updated: 2023/10/25 13:06:18 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include "get_next_line.h" + +// How to free? +// static in get_next_line? So it could be passed to select AND delete +static char *select_file_buffer(int fd, t_list **list) +{ + t_list *local_head; + + if (*list == NULL) + { + *list = new_ft_node(fd); + if (list == NULL) + return (NULL); + return (((t_ft *)((*list)->content))->buffer); + } + local_head = *list; + while (local_head->next && ((t_ft *)(local_head->content))->fd != fd) + local_head = local_head->next; + if (((t_ft *)(local_head->content))->fd == fd) + return (((t_ft *)(local_head->content))->buffer); + local_head->next = new_ft_node(fd); + if (local_head->next == NULL) + return (NULL); + return (((t_ft *)(local_head->next->content))->buffer); +} + +static void delete_file_node(int fd, t_list **list) +{ + t_list *cur; + t_list *prev; + + prev = NULL; + cur = *list; + while (((t_ft *)(cur->content))->fd != fd) + { + prev = cur; + cur = cur->next; + } + if (prev == NULL) + *list = cur->next; + else + prev->next = cur->next; + free(((t_ft *)(cur->content))->buffer); + free(cur->content); + free(cur); + return ; +} + +/* Concatenates res and buffer up to newline. + Shifts buffer by the transfered characters. + Returns 0 when buffer is empty (and needs filling with read). + Also returns 1 when newline is transfered + unless buffer empty (to delete node). + Otherwise returns true. +*/ +static int transfer_string(char **res, char *buffer) +{ + int i; + int nl; + + i = 0; + while (buffer[i] && buffer[i] != '\n') + ++i; + nl = (buffer[i] == '\n'); + i += nl; + ft_strncat_alloc(res, buffer, i); + ft_memmove(buffer, buffer + i, BUFFER_SIZE + 1 - i); + return (buffer[0] || nl); +} + +char *get_next_line(int fd) +{ + static t_list *list; + char *buffer; + char *res; + int i; + + res = NULL; + buffer = select_file_buffer(fd, &list); + while (!transfer_string(&res, buffer)) + { + if (buffer[0] == '\0') + { + i = read(fd, buffer, BUFFER_SIZE); + buffer[i] = '\0'; + if (i <= 0) + delete_file_node(fd, &list); + if (i < 0) + { + free(res); + return (NULL); + } + if (i == 0) + return (res); + } + } + return (res); +} diff --git a/get_next_line_bonus.h b/get_next_line_bonus.h new file mode 100644 index 0000000..9f951da --- /dev/null +++ b/get_next_line_bonus.h @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/28 11:24:52 by ljiriste #+# #+# */ +/* Updated: 2023/10/11 18:16:37 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H + +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 80 +# endif + +# include + +typedef struct s_file_thread +{ + int fd; + char *buffer; +} t_ft; + +typedef struct s_list +{ + void *content; + struct s_list *next; +} t_list; + +char *get_next_line(int fd); + +t_list *new_ft_node(int fd); +t_list *ft_lstnew(void *content); +void *ft_memmove(void *dest, const void *src, size_t n); +void ft_strncat_alloc(char **dest, const char *src, int n); + +char *get_next_line(int fd); + +#endif diff --git a/get_next_line_utils_bonus.c b/get_next_line_utils_bonus.c new file mode 100644 index 0000000..fb4048a --- /dev/null +++ b/get_next_line_utils_bonus.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/09/11 13:36:53 by ljiriste #+# #+# */ +/* Updated: 2023/10/11 15:42:18 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +/* Functions in this file may (and should) be substituted by Libft functions + after this project is integrated into Libft +*/ + +#include // malloc etc. +#include "get_next_line.h" + +//This function may be useful enough to add to Libft +/* Functions like ft_strncat but reallocates dest to + make sure it is large enough */ +void ft_strncat_alloc(char **dest, const char *src, int n) +{ + int size; + char *temp; + + if (n <= 0) + return ; + temp = *dest; + size = 0; + if (temp) + while (temp[size]) + ++size; + size += n + 1; + *dest = malloc(size); + if (*dest == NULL) + { + free(temp); + return ; + } + ft_memmove(*dest, temp, size - n - 1); + ft_memmove(*dest + size - n - 1, src, n); + (*dest)[size - 1] = '\0'; + free(temp); + return ; +} + +void *ft_memmove(void *dest, const void *src, size_t n) +{ + size_t i; + + if (dest > src) + { + i = n; + while (i > 0) + { + --i; + *((unsigned char *)dest + i) = *((unsigned char *)src + i); + } + } + else if (dest < src) + { + i = 0; + while (i < n) + { + *((unsigned char *)dest + i) = *((unsigned char *)src + i); + ++i; + } + } + return (dest); +} + +t_list *ft_lstnew(void *content) +{ + t_list *res; + + res = malloc(sizeof(t_list)); + if (res == NULL) + return (res); + res->content = content; + res->next = NULL; + return (res); +} + +t_list *new_ft_node(int fd) +{ + t_list *node; + t_ft *thread; + + thread = malloc(sizeof(t_ft)); + if (thread == NULL) + return (NULL); + node = ft_lstnew(thread); + if (node == NULL) + { + free(thread); + return (NULL); + } + thread->buffer = malloc((BUFFER_SIZE + 1) * sizeof(char)); + if (thread->buffer == NULL) + { + free(thread); + free(node); + return (NULL); + } + (thread->buffer)[0] = '\0'; + thread->fd = fd; + return (node); +} -- 2.30.2