get_next_line/scratch/get_next_line.c
Willem Haffmans 0e894b1b63 add all
2024-07-26 22:30:53 +02:00

240 lines
4.1 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/11 17:35:46 by whaffman #+# #+# */
/* Updated: 2024/07/12 10:18:44 by whaffman ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
#include <fcntl.h>
size_t ft_strlen(const char *s)
{
size_t length;
length = 0;
while (*s++)
length++;
return (length);
}
char *ft_strchr(const char *str, int c)
{
while (*str)
{
if (*str == c)
return ((char *) str);
str++;
}
if (*str == c)
return ((char *) str);
return (NULL);
}
void ft_lstclear(t_list **lst, void (*del)(void *))
{
t_list *next;
if (!del || !lst)
return ;
while (*lst)
{
if ((*lst)->next)
next = (*lst)->next;
else
next = NULL;
del((*lst)->content);
free(*lst);
*lst = next;
}
}
t_list *new_node(size_t size)
{
t_list *node;
char *buffer;
if (size <= 0)
return (NULL);
buffer = malloc(size * sizeof(char));
if (!buffer)
return (NULL);
node = malloc(sizeof(t_list));
if (!node)
{
free(buffer);
return (NULL);
}
node->content = buffer;
node->next = NULL;
return (node);
}
int read_block(int fd, t_list **stock)
{
t_list *node;
int read_result;
if (fd < 0)
return (-1);
node = new_node(BUFFER_SIZE + 1);
if (!node)
return (-1);
read_result = read(fd, node->content, BUFFER_SIZE);
if (read_result > 0)
{
(node->content)[read_result] = '\0';
node->next = NULL;
*stock = node;
}
return (read_result);
}
int restock(int fd, t_list **stock)
{
int read_result;
t_list *last_node = *stock;
// Find the last node in the list
while (last_node && last_node->next)
last_node = last_node->next;
// Read blocks until a newline or EOF is reached
while (1)
{
read_result = read_block(fd, &last_node);
if (read_result < 0)
return -1;
if (read_result == 0 || ft_strchr(last_node->content, '\n'))
break;
last_node = last_node->next;
}
return read_result;
}
size_t len_till_newline(t_list *lst)
{
size_t len;
size_t i;
len = 0;
while(lst)
{
i = 0;
while (lst->content[i] && lst->content[i] != '\n')
{
len++;
i++;
}
if (lst->content[i] == '\n')
return (len + 1);
lst = lst->next;
}
return (len);
}
char *get_line(t_list *lst)
{
size_t i;
size_t j;
size_t len;
char *line;
len = len_till_newline(lst);
line = malloc((len + 1) * sizeof(char));
if (!line)
return (NULL);
i = 0;
while (i < len && lst)
{
j = 0;
while(lst->content[j])
{
line[i + j] = (char) lst->content[j];
j++;
}
i += j;
lst = lst->next;
}
line[i] = '\0';
return (line);
}
void clean_lst(t_list **lst)
{
t_list *last;
t_list *new;
size_t i;
size_t j;
last = *lst;
while(last->next)
last = last->next;
i = 0;
while(last->content[i] && last->content[i] != '\n')
i++;
if (!last->content[i])
{
new = new_node(ft_strlen(&(last->content[i++])) + 1);
if (!new)
return ;
j = 0;
while (last->content[i + j])
{
new->content[j] = last->content[i + j];
j++;
}
ft_lstclear(lst, free);
*lst = new;
}
}
char *get_next_line(int fd)
{
static t_list *stock;
char *line;
if (fd < 0)
return (NULL);
restock(fd, &stock);
if (!stock)
return (NULL);
line = get_line(stock);
clean_lst(&stock);
return (line);
}
#include <stdio.h>
int main(int argc, char **argv)
{
int fd;
char *line;
if (argc > 1)
fd = open(argv[1], O_RDONLY);
else
fd = STDIN_FILENO;
if (fd < 0)
{
return 1;
}
while ((line = get_next_line(fd)) != NULL)
{
printf("%s\n", line);
free(line);
}
close(fd);
return 0;
}