]> Untitled Git - axy/ft/get_next_line.git/commitdiff
Reworked to not use linked lists
author= <=>
Thu, 6 Nov 2025 17:01:08 +0000 (18:01 +0100)
committer= <=>
Thu, 6 Nov 2025 17:01:08 +0000 (18:01 +0100)
.get_next_line.c.swp [new file with mode: 0644]
get_next_line.c
get_next_line.h
get_next_line_bonus.c [deleted file]
get_next_line_bonus.h [deleted file]
get_next_line_utils.c
get_next_line_utils_bonus.c [deleted file]

diff --git a/.get_next_line.c.swp b/.get_next_line.c.swp
new file mode 100644 (file)
index 0000000..b9295ba
Binary files /dev/null and b/.get_next_line.c.swp differ
index b9d888604f0ebb21a00c7b18a6d68b50472318ef..964cfb0584c304df0c469b0ccd3ead832be98e64 100644 (file)
@@ -6,99 +6,80 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/11/01 10:55:35 by agilliar          #+#    #+#             */
-/*   Updated: 2025/11/01 20:55:35 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/11/06 18:00:50 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include <stdbool.h>
 #include <stdlib.h>
-#include "get_next_line.h"
 
-void   *ft_memcpy(void *dest, const void *src, size_t n);
-bool   buffer_shrink_near_fit(t_buf *buf);
-bool   buffer_search(t_buf *buf);
-bool   buffer_read(t_buf *buf, int fd);
+#include "get_next_line.h"
 
-t_buf  *buffers_get(t_list **buffers, int fd)
-{
-       while (*buffers && (*buffers)->fd != fd)
-               buffers = &(*buffers)->next;
-       if (*buffers)
-               return (&(*buffers)->buf);
-       (*buffers) = malloc(sizeof(t_list));
-       if (!*buffers)
-               return (NULL);
-       (*buffers)->next = NULL;
-       (*buffers)->fd = fd;
-       (*buffers)->buf.len = 0;
-       (*buffers)->buf.capacity = 0;
-       (*buffers)->buf.search_offset = 0;
-       (*buffers)->buf.buf = NULL;
-       return (&(*buffers)->buf);
-}
+void           buffer_pushchar(t_buf *buf, char c);
+void           buffers_remove(t_readbufs *bufs, int fd);
+void           *ft_memcpy(void *dest, const void *src, size_t n);
+bool           readbuf_read(t_readbuf *buf);
+t_readbuf      *buffers_get(t_readbufs *bufs, int fd);
 
-void   *buffers_del(t_list **buffers, int fd)
+char   *buffer_finish(t_buf buf, t_readbufs *buffers, int fd)
 {
-       t_list  *next;
-
-       while (*buffers && (*buffers)->fd != fd)
-               buffers = &(*buffers)->next;
-       if (!*buffers)
-               return (NULL);
-       free((*buffers)->buf.buf);
-       next = (*buffers)->next;
-       free(*buffers);
-       *buffers = next;
-       return (NULL);
+       if (buf.buf)
+               buffer_pushchar(&buf, '\0');
+       if (!buf.buf)
+               buffers_remove(buffers, fd);
+       return (buf.buf);
 }
 
-char   *ft_substr(const char *src, size_t len)
-{
-       char    *res;
-
-       res = malloc(len + 1);
-       if (!res)
-               return (res);
-       ft_memcpy(res, src, len);
-       res[len] = '\0';
-       return (res);
-}
-
-char   *buffer_gnl(t_buf *buf, t_list **buffers, int fd)
+/*
+       returns whether it should keep going
+*/
+bool   buffer_empty(t_readbuf *buf, t_buf *dst)
 {
-       char    *res;
+       size_t  i;
 
-       res = ft_substr(buf->buf, buf->search_offset);
-       if (!res)
-               return (buffers_del(buffers, fd));
-       buf->len -= buf->search_offset;
-       ft_memcpy(buf->buf, &buf->buf[buf->search_offset], buf->len);
-       buf->search_offset = 0;
-       buffer_shrink_near_fit(buf);
-       return (res);
+       if (buf->written == 0)
+               return (false);
+       i = 0;
+       while (i < buf->written)
+       {
+               buffer_pushchar(dst, buf->buf[i++]);
+               if (dst->buf == NULL)
+                       return (false);
+               if (dst->buf[dst->len - 1] == '\n')
+                       break ;
+       }
+       buf->written -= i;
+       ft_memcpy(buf->buf, &buf->buf[i], buf->written);
+       if (dst->buf[dst->len - 1] == '\n')
+               return (false);
+       return (true);
 }
 
 char   *get_next_line(int fd)
 {
-       static t_list   *buffers = NULL;
-       t_buf                   *buf;
-       char                    *res;
+       static t_readbufs       buffers = {
+               .used = 0
+       };
+       t_readbuf                       *buf;
+       t_buf                           res;
 
+       res.len = 0;
+       res.capacity = 0;
+       res.buf = NULL;
        buf = buffers_get(&buffers, fd);
        if (!buf)
                return (NULL);
-       while (buf->len != buf->search_offset || buffer_read(buf, fd))
+       while (true)
        {
-               if (buf->search_offset == buf->len)
+               if (!readbuf_read(buf))
                {
-                       res = ft_substr(buf->buf, buf->len);
-                       buffers_del(&buffers, fd);
-                       return (res);
+                       buffers_remove(&buffers, fd);
+                       free(res.buf);
+                       return (NULL);
                }
-               if (buffer_search(buf))
-                       return (buffer_gnl(buf, &buffers, fd));
+               if (!buffer_empty(buf, &res))
+                       return (buffer_finish(res, &buffers, fd));
        }
-       return (buffers_del(&buffers, fd));
 }
 
 /*
index 14eb65797d12eab1edfa2a14971383b8f7692aeb..ac33fb4fea36a53a9fe7692ce862b22427bd5160 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/11/01 10:38:19 by agilliar          #+#    #+#             */
-/*   Updated: 2025/11/01 20:52:08 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/11/06 17:20:44 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 
 # include <stddef.h>
 
+# ifndef BUFFER_SIZE
+#  define BUFFER_SIZE 256
+# endif
+
+# ifndef GNL_MAX_FD
+#  define GNL_MAX_FD 256
+# endif
+
 typedef struct s_buf
 {
        size_t  len;
        size_t  capacity;
-       size_t  search_offset;
        char    *buf;
 }      t_buf;
 
-typedef struct s_list
+typedef struct s_readbuf
 {
-       int                             fd;
-       t_buf                   buf;
-       struct s_list   *next;
-}      t_list;
+       size_t  written;
+       int             fd;
+       char    buf[BUFFER_SIZE];
+}      t_readbuf;
 
-# ifndef BUFFER_SIZE
-#  define BUFFER_SIZE 256
-# endif
+typedef struct s_readbufs
+{
+       size_t          used;
+       t_readbuf       bufs[GNL_MAX_FD];
+}      t_readbufs;
 
 char   *get_next_line(int fd);
 
diff --git a/get_next_line_bonus.c b/get_next_line_bonus.c
deleted file mode 100644 (file)
index c63adbb..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ************************************************************************** */
-/*                                                                            */
-/*                                                        :::      ::::::::   */
-/*   get_next_line_bonus.c                              :+:      :+:    :+:   */
-/*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
-/*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2025/11/01 10:55:35 by agilliar          #+#    #+#             */
-/*   Updated: 2025/11/01 20:57:34 by agilliar         ###   ########.fr       */
-/*                                                                            */
-/* ************************************************************************** */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include "get_next_line_bonus.h"
-
-void   *ft_memcpy(void *dest, const void *src, size_t n);
-bool   buffer_shrink_near_fit(t_buf *buf);
-bool   buffer_search(t_buf *buf);
-bool   buffer_read(t_buf *buf, int fd);
-
-t_buf  *buffers_get(t_list **buffers, int fd)
-{
-       while (*buffers && (*buffers)->fd != fd)
-               buffers = &(*buffers)->next;
-       if (*buffers)
-               return (&(*buffers)->buf);
-       (*buffers) = malloc(sizeof(t_list));
-       if (!*buffers)
-               return (NULL);
-       (*buffers)->next = NULL;
-       (*buffers)->fd = fd;
-       (*buffers)->buf.len = 0;
-       (*buffers)->buf.capacity = 0;
-       (*buffers)->buf.search_offset = 0;
-       (*buffers)->buf.buf = NULL;
-       return (&(*buffers)->buf);
-}
-
-void   *buffers_del(t_list **buffers, int fd)
-{
-       t_list  *next;
-
-       while (*buffers && (*buffers)->fd != fd)
-               buffers = &(*buffers)->next;
-       if (!*buffers)
-               return (NULL);
-       free((*buffers)->buf.buf);
-       next = (*buffers)->next;
-       free(*buffers);
-       *buffers = next;
-       return (NULL);
-}
-
-char   *ft_substr(const char *src, size_t len)
-{
-       char    *res;
-
-       res = malloc(len + 1);
-       if (!res)
-               return (res);
-       ft_memcpy(res, src, len);
-       res[len] = '\0';
-       return (res);
-}
-
-char   *buffer_gnl(t_buf *buf, t_list **buffers, int fd)
-{
-       char    *res;
-
-       res = ft_substr(buf->buf, buf->search_offset);
-       if (!res)
-               return (buffers_del(buffers, fd));
-       buf->len -= buf->search_offset;
-       ft_memcpy(buf->buf, &buf->buf[buf->search_offset], buf->len);
-       buf->search_offset = 0;
-       buffer_shrink_near_fit(buf);
-       return (res);
-}
-
-char   *get_next_line(int fd)
-{
-       static t_list   *buffers = NULL;
-       t_buf                   *buf;
-       char                    *res;
-
-       buf = buffers_get(&buffers, fd);
-       if (!buf)
-               return (NULL);
-       while (buf->len != buf->search_offset || buffer_read(buf, fd))
-       {
-               if (buf->search_offset == buf->len)
-               {
-                       res = ft_substr(buf->buf, buf->len);
-                       buffers_del(&buffers, fd);
-                       return (res);
-               }
-               if (buffer_search(buf))
-                       return (buffer_gnl(buf, &buffers, fd));
-       }
-       return (buffers_del(&buffers, fd));
-}
-
-/*
-#include <fcntl.h>
-#include <stdio.h>
-
-int    main(int argc, char **argv)
-{
-       char    *nl;
-       bool    any_line;
-
-       for (int i = 1; i < argc; i++)
-               ((int *)argv)[i] = open(argv[i], O_RDONLY);
-       any_line = true;
-       for (int i = 0; any_line; i++)
-       {
-               any_line = false;
-               for (int j = 1; j < argc; j++)
-               {
-                       nl = get_next_line(((int *)argv)[j]);
-                       if (!nl)
-                               continue;
-                       any_line = true;
-                       printf("line %i file %i: %s", i, j, nl);
-                       free(nl);
-               }
-       }
-       for (char *nl; (nl = get_next_line(0));)
-       {
-               printf("stdin: %s", nl);
-               free(nl);
-       }
-}
-*/
diff --git a/get_next_line_bonus.h b/get_next_line_bonus.h
deleted file mode 100644 (file)
index ae03cf9..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ************************************************************************** */
-/*                                                                            */
-/*                                                        :::      ::::::::   */
-/*   get_next_line_bonus.h                              :+:      :+:    :+:   */
-/*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
-/*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2025/11/01 10:38:19 by agilliar          #+#    #+#             */
-/*   Updated: 2025/11/01 20:57:37 by agilliar         ###   ########.fr       */
-/*                                                                            */
-/* ************************************************************************** */
-
-#ifndef GET_NEXT_LINE_BONUS_H
-# define GET_NEXT_LINE_BONUS_H
-
-# include <stddef.h>
-
-typedef struct s_buf
-{
-       size_t  len;
-       size_t  capacity;
-       size_t  search_offset;
-       char    *buf;
-}      t_buf;
-
-typedef struct s_list
-{
-       int                             fd;
-       t_buf                   buf;
-       struct s_list   *next;
-}      t_list;
-
-# ifndef BUFFER_SIZE
-#  define BUFFER_SIZE 256
-# endif
-
-char   *get_next_line(int fd);
-
-#endif
index a7a215c7e2b9d039cba68234b411575f05534163..7e986cc3064bfa1d0fd8cb3821c319fd4794633b 100644 (file)
@@ -3,94 +3,99 @@
 /*                                                        :::      ::::::::   */
 /*   get_next_line_utils.c                              :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2025/11/01 20:47:32 by agilliar          #+#    #+#             */
-/*   Updated: 2025/11/01 20:52:30 by agilliar         ###   ########.fr       */
+/*   Created: 2025/11/06 17:56:20 by agilliar          #+#    #+#             */
+/*   Updated: 2025/11/06 17:58:50 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include <stdbool.h>
 #include <stdlib.h>
 #include <unistd.h>
+
 #include "get_next_line.h"
 
-/*
-       not restrict, therefor it is safe to use it on overlapping memory regions so
-       long as the destination is before the source
-*/
-void   *ft_memcpy(void *dest, const void *src, size_t n)
+t_readbuf      *buffers_get(t_readbufs *bufs, int fd)
 {
        size_t  i;
 
        i = 0;
-       while (i < n)
-       {
-               ((unsigned char *)dest)[i] = ((unsigned char *)src)[i];
+       while (i < bufs->used && bufs->bufs[i].fd != fd)
                i++;
+       if (i == GNL_MAX_FD)
+               return (NULL);
+       if (i == bufs->used)
+       {
+               bufs->bufs[i].written = 0;
+               bufs->bufs[i].fd = fd;
+               bufs->used++;
        }
-       return (dest);
+       return (&bufs->bufs[i]);
 }
 
-/*
-       returns false when an allocation error occured
-*/
-bool   buffer_reserve(t_buf *buf, size_t extra)
+void   buffers_remove(t_readbufs *bufs, int fd)
 {
-       size_t  new_capacity;
-       char    *new_buf;
+       size_t  i;
+
+       i = 0;
+       while (i < bufs->used && bufs->bufs[i].fd != fd)
+               i++;
+       if (i == GNL_MAX_FD)
+               return ;
+       bufs->bufs[i] = bufs->bufs[--bufs->used];
+}
+
+bool   readbuf_read(t_readbuf *buf)
+{
+       int     n;
 
-       if (buf->len + extra <= buf->capacity)
+       if (buf->written != 0)
                return (true);
-       new_capacity = buf->len + extra;
-       if (new_capacity < buf->capacity * 2)
-               new_capacity = buf->capacity * 2;
-       new_buf = malloc(new_capacity);
-       if (!new_buf)
+       n = read(buf->fd, &buf->buf, BUFFER_SIZE);
+       if (n < 0)
                return (false);
-       ft_memcpy(new_buf, buf->buf, buf->len);
-       free(buf->buf);
-       buf->buf = new_buf;
-       buf->capacity = new_capacity;
+       buf->written = n;
        return (true);
 }
 
-bool   buffer_read(t_buf *buf, int fd)
+void   *ft_memcpy(void *dest, const void *src, size_t n)
 {
-       char    read_buf[BUFFER_SIZE];
-       ssize_t res;
+       size_t  i;
 
-       res = read(fd, read_buf, BUFFER_SIZE);
-       if (res < 1 || !buffer_reserve(buf, res))
-               return (false);
-       ft_memcpy(&buf->buf[buf->len], read_buf, res);
-       buf->len += res;
-       return (true);
+       i = 0;
+       while (i < n)
+       {
+               ((unsigned char *)dest)[i] = ((unsigned char *)src)[i];
+               i++;
+       }
+       return (dest);
 }
 
 /*
-       returns false when an allocation error occured
+       frees its own resources on failure
 */
-bool   buffer_shrink_near_fit(t_buf *buf)
+void   buffer_pushchar(t_buf *buf, char c)
 {
+       size_t  new_capacity;
        char    *new_buf;
 
-       if (buf->capacity <= buf->len * 2 + BUFFER_SIZE)
-               return (true);
-       new_buf = malloc(buf->len * 2);
-       if (!new_buf)
-               return (false);
-       ft_memcpy(new_buf, buf->buf, buf->len);
-       free(buf->buf);
-       buf->buf = new_buf;
-       buf->capacity = buf->len * 2;
-       return (true);
-}
-
-bool   buffer_search(t_buf *buf)
-{
-       while (buf->search_offset < buf->len)
-               if (buf->buf[buf->search_offset++] == '\n')
-                       return (true);
-       return (false);
+       if (buf->len + 1 > buf->capacity)
+       {
+               new_capacity = buf->len + 1;
+               if (new_capacity < BUFFER_SIZE + buf->capacity * 2)
+                       new_capacity = BUFFER_SIZE + buf->capacity * 2;
+               new_buf = malloc(new_capacity);
+               if (!new_buf)
+               {
+                       free(buf->buf);
+                       buf->buf = NULL;
+                       return ;
+               }
+               ft_memcpy(new_buf, buf->buf, buf->len);
+               free(buf->buf);
+               buf->buf = new_buf;
+               buf->capacity = new_capacity;
+       }
+       buf->buf[buf->len++] = c;
 }
diff --git a/get_next_line_utils_bonus.c b/get_next_line_utils_bonus.c
deleted file mode 100644 (file)
index 1500ee6..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ************************************************************************** */
-/*                                                                            */
-/*                                                        :::      ::::::::   */
-/*   get_next_line_utils_bonus.c                        :+:      :+:    :+:   */
-/*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
-/*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2025/11/01 20:47:32 by agilliar          #+#    #+#             */
-/*   Updated: 2025/11/01 20:57:50 by agilliar         ###   ########.fr       */
-/*                                                                            */
-/* ************************************************************************** */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "get_next_line_bonus.h"
-
-/*
-       not restrict, therefor it is safe to use it on overlapping memory regions so
-       long as the destination is before the source
-*/
-void   *ft_memcpy(void *dest, const void *src, size_t n)
-{
-       size_t  i;
-
-       i = 0;
-       while (i < n)
-       {
-               ((unsigned char *)dest)[i] = ((unsigned char *)src)[i];
-               i++;
-       }
-       return (dest);
-}
-
-/*
-       returns false when an allocation error occured
-*/
-bool   buffer_reserve(t_buf *buf, size_t extra)
-{
-       size_t  new_capacity;
-       char    *new_buf;
-
-       if (buf->len + extra <= buf->capacity)
-               return (true);
-       new_capacity = buf->len + extra;
-       if (new_capacity < buf->capacity * 2)
-               new_capacity = buf->capacity * 2;
-       new_buf = malloc(new_capacity);
-       if (!new_buf)
-               return (false);
-       ft_memcpy(new_buf, buf->buf, buf->len);
-       free(buf->buf);
-       buf->buf = new_buf;
-       buf->capacity = new_capacity;
-       return (true);
-}
-
-bool   buffer_read(t_buf *buf, int fd)
-{
-       char    read_buf[BUFFER_SIZE];
-       ssize_t res;
-
-       res = read(fd, read_buf, BUFFER_SIZE);
-       if (res < 1 || !buffer_reserve(buf, res))
-               return (false);
-       ft_memcpy(&buf->buf[buf->len], read_buf, res);
-       buf->len += res;
-       return (true);
-}
-
-/*
-       returns false when an allocation error occured
-*/
-bool   buffer_shrink_near_fit(t_buf *buf)
-{
-       char    *new_buf;
-
-       if (buf->capacity <= buf->len * 2 + BUFFER_SIZE)
-               return (true);
-       new_buf = malloc(buf->len * 2);
-       if (!new_buf)
-               return (false);
-       ft_memcpy(new_buf, buf->buf, buf->len);
-       free(buf->buf);
-       buf->buf = new_buf;
-       buf->capacity = buf->len * 2;
-       return (true);
-}
-
-bool   buffer_search(t_buf *buf)
-{
-       while (buf->search_offset < buf->len)
-               if (buf->buf[buf->search_offset++] == '\n')
-                       return (true);
-       return (false);
-}