Patch delete_file_node function, create bonus (copy)
authorLukas Jiriste <ljiriste@student.42prague.com>
Wed, 25 Oct 2023 13:33:14 +0000 (15:33 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Wed, 25 Oct 2023 13:33:14 +0000 (15:33 +0200)
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
get_next_line_bonus.c [new file with mode: 0644]
get_next_line_bonus.h [new file with mode: 0644]
get_next_line_utils_bonus.c [new file with mode: 0644]

index ebfa2779cf651e8008d657783388236bd163e3f0..4e5cae8568dbde2f773c15b2ff1c1f286a5b68fd 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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 (file)
index 0000000..4e5cae8
--- /dev/null
@@ -0,0 +1,112 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/08/28 00:01:15 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/10/25 13:06:18 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <stdlib.h>
+#include <unistd.h>
+#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 (file)
index 0000000..9f951da
--- /dev/null
@@ -0,0 +1,43 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line.h                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 <stddef.h>
+
+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 (file)
index 0000000..fb4048a
--- /dev/null
@@ -0,0 +1,110 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line_utils.c                              :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 <stdlib.h>    // 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);
+}