Add get_next_line to libft
authorLukas Jiriste <ljiriste@student.42prague.com>
Sun, 3 Dec 2023 19:41:16 +0000 (20:41 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Sun, 3 Dec 2023 19:41:16 +0000 (20:41 +0100)
Splice get_next_line project neatly fit it inside libft while conforming
the Norm.
Change libft.h and Makefile accordingly.

Makefile
ft_strncat_alloc.c [new file with mode: 0755]
get_next_line.c [new file with mode: 0755]
get_next_line.h [new file with mode: 0644]
libft.h

index 92ef2daeb26cc152ae6300d261868715e3ff6e90..3f7e3e8b6df8e2a9c0e8308633cbe1162921011a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,7 @@ SOURCES :=    ft_strndup.c                    \
                        ft_split.c                              \
                        ft_toupper.c                    \
                        ft_strlcat.c                    \
+                       ft_strncat_alloc.c              \
                        ft_bzero.c                              \
                        ft_abs.c                                \
                        ft_isalpha.c                    \
@@ -50,6 +51,8 @@ SOURCES :=    ft_strndup.c                    \
                        ft_strncmp.c                    \
                        ft_swap.c                               \
                        \
+                       get_next_line.c                 \
+                       \
                        ft_lst/ft_lstnew.c                              \
                        ft_lst/ft_lstiter.c                             \
                        ft_lst/ft_lstmap.c                              \
diff --git a/ft_strncat_alloc.c b/ft_strncat_alloc.c
new file mode 100755 (executable)
index 0000000..d9f246d
--- /dev/null
@@ -0,0 +1,42 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_strncat_alloc.c                                 :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/09/11 13:36:53 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/03 19:45:18 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <stdlib.h>    // malloc etc.
+#include "libft.h"
+
+/*     Functions like ft_strncat but reallocates dest to
+       make sure it is large enough    */
+char   *ft_strncat_alloc(char **dest, const char *src, size_t n)
+{
+       int             size;
+       char    *temp;
+
+       if (n == 0)
+               return (*dest);
+       temp = *dest;
+       size = 0;
+       if (temp)
+               while (temp[size])
+                       ++size;
+       size += n + 1;
+       *dest = malloc(size);
+       if (*dest == NULL)
+       {
+               free(temp);
+               return (NULL);
+       }
+       ft_memmove(*dest, temp, size - n - 1);
+       ft_memmove(*dest + size - n - 1, src, n);
+       (*dest)[size - 1] = '\0';
+       free(temp);
+       return (*dest);
+}
diff --git a/get_next_line.c b/get_next_line.c
new file mode 100755 (executable)
index 0000000..07ed37b
--- /dev/null
@@ -0,0 +1,139 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/08/28 00:01:15 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/03 19:52:16 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "get_next_line.h"
+#include "libft.h"
+
+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);
+}
+
+// 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);
+                       if (i <= 0)
+                               delete_file_node(fd, &list);
+                       if (i < 0)
+                       {
+                               free(res);
+                               return (NULL);
+                       }
+                       if (i == 0)
+                               return (res);
+                       buffer[i] = '\0';
+               }
+       }
+       return (res);
+}
diff --git a/get_next_line.h b/get_next_line.h
new file mode 100644 (file)
index 0000000..0b0f615
--- /dev/null
@@ -0,0 +1,30 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   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;
+
+char   *get_next_line(int fd);
+
+#endif
diff --git a/libft.h b/libft.h
index e40e68827aa8b584bf6042664b4621f394bb8afd..ac0e5b263b80ca3a62cd81a0fd0ddbd7dac83127 100644 (file)
--- a/libft.h
+++ b/libft.h
@@ -38,6 +38,7 @@ int           ft_memcmp(const void *s1, const void *s2, size_t n);
 size_t ft_strlen(const char *s);
 size_t ft_strlcpy(char *dst, const char *src, size_t size);
 size_t ft_strlcat(char *dst, const char *src, size_t size);
+char   *ft_strncat_alloc(char **dest, const char *src, size_t n);
 int            ft_strncmp(const char *s1, const char *s2, size_t n);
 char   *ft_strchr(const char *s, int c);
 char   *ft_strrchr(const char *s, int c);
@@ -71,6 +72,8 @@ int           ft_printf(const char *format, ...);
 
 void   ft_swap(void **a, void **b);
 
+char   *get_next_line(int fd);
+
 typedef struct s_list
 {
        struct s_list   *next;