minishell/libft/get_next_line.c
2025-06-04 14:58:04 +02:00

110 lines
3.0 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/18 20:20:17 by vvobis #+# #+# */
/* Updated: 2024/06/14 00:05:31 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
void *buffer_extend(void *ptr_old, size_t size_new, size_t size_old)
{
void *ptr_new;
void *ptr_back;
void *ptr_old_free;
ptr_new = g_calloc(size_new + 1, 1);
if (!ptr_new)
return (free(ptr_old), ptr_old = NULL, NULL);
ptr_back = ptr_new;
ptr_old_free = ptr_old;
while (size_old--)
*(char *)ptr_new++ = *(char *)ptr_old++;
return (free(ptr_old_free), ptr_old_free = NULL, ptr_back);
}
char *handle_no_nl(char **buf, char **left)
{
if (left)
{
free(*left);
*left = NULL;
}
if (!buf)
return (NULL);
if (g_strlen(*buf))
return (*buf);
free(*buf);
*buf = NULL;
return (NULL);
}
char *line_extract(char **buf_joined, char **left, size_t line_len)
{
char *line;
line = g_substr(*buf_joined, 0, line_len);
if (!line)
return (free(*buf_joined), *buf_joined = NULL, (char *)-1);
*left = g_substr(*buf_joined, line_len, g_strlen(*buf_joined) - line_len);
free(*buf_joined);
*buf_joined = NULL;
if (!*left)
return (free(line), line = NULL, (char *)-1);
return (line);
}
char *line_handle(char **buf_fetch)
{
char *buf_joined;
size_t line_len;
static char *left;
if (!buf_fetch)
return (free(left), left = NULL, (char *)-1);
buf_joined = g_strjoin(left, *buf_fetch);
free(*buf_fetch);
*buf_fetch = NULL;
free(left);
left = NULL;
if (!buf_joined)
return ((char *)-1);
line_len = find_newline(buf_joined);
if (line_len)
return (line_extract(&buf_joined, &left, line_len));
return (handle_no_nl(&buf_joined, &left));
}
char *get_next_line(int fd)
{
char *buf;
ssize_t bytes_read;
size_t buf_size_cur;
size_t buf_size_prev;
if (fd < 0)
return (line_handle(NULL), NULL);
buf = g_calloc(sizeof(*buf), BUFFER_SIZE + 1);
buf_size_prev = 0;
buf_size_cur = BUFFER_SIZE;
while (1)
{
if (!buf)
return (line_handle(NULL));
bytes_read = read(fd, buf + buf_size_prev, BUFFER_SIZE);
if (bytes_read < 0)
return (free(buf), buf = NULL, line_handle(NULL));
if (find_newline(buf) || bytes_read == 0)
break ;
buf_size_prev = buf_size_cur;
buf_size_cur += BUFFER_SIZE;
buf = buffer_extend(buf, buf_size_cur, buf_size_prev);
}
return (line_handle(&buf));
}