240 lines
4.1 KiB
C
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;
|
|
} |