aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2019-11-13 15:11:04 +0100
committerCharles <sircharlesaze@gmail.com>2019-11-13 15:31:35 +0100
commitb9a5e7c9ae556988c62dd9efeaf17060ad34bab0 (patch)
tree7bf374e387898f9357aacde31c7b65e2032a75bc
parent5bf49994b911abc2b8ff3bdb525cdc23c71f2102 (diff)
downloadlibft-b9a5e7c9ae556988c62dd9efeaf17060ad34bab0.tar.gz
libft-b9a5e7c9ae556988c62dd9efeaf17060ad34bab0.tar.bz2
libft-b9a5e7c9ae556988c62dd9efeaf17060ad34bab0.zip
Added get_next_line
-rw-r--r--Makefile2
-rw-r--r--get_next_line.c119
-rw-r--r--get_next_line.h35
-rw-r--r--libft.h1
4 files changed, 156 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index f713b34..f7caf07 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,7 @@ SRC = ft_atoi.c ft_bzero.c ft_isalnum.c ft_isalpha.c ft_isascii.c ft_isdigit.c \
ft_strncmp.c ft_strncpy.c ft_strnequ.c ft_strnew.c ft_strnstr.c \
ft_strrchr.c ft_split.c ft_strstr.c ft_substr.c ft_strtrim.c \
ft_tolower.c ft_toupper.c ft_strlcpy.c ft_calloc.c ft_strndup.c \
- ft_strjoin_free.c ft_strjoin_free_snd.c
+ ft_strjoin_free.c ft_strjoin_free_snd.c get_next_line.c
OBJ = $(SRC:.c=.o)
INCLUDE = libft.h
diff --git a/get_next_line.c b/get_next_line.c
new file mode 100644
index 0000000..61d74c0
--- /dev/null
+++ b/get_next_line.c
@@ -0,0 +1,119 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* get_next_line.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2019/10/19 09:08:36 by cacharle #+# #+# */
+/* Updated: 2019/11/04 00:00:16 by cacharle ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "libft.h"
+#include "get_next_line.h"
+
+/*
+** if has rest:
+** if rest has newline:
+** push rest until newline in line, shift rest
+** return LINE_READ
+** else:
+** push rest in line
+**
+** while can read fd in buf
+** if buf has newline:
+** push buf until newline in line
+** push buf after newline in rest
+** return LINE_READ
+** push buf in line
+**
+** return GNL_EOF
+*/
+
+#define HAS_NEWLINE(str, split_at) ((split_at = find_newline(str)) != -1)
+
+int get_next_line(int fd, char **line)
+{
+ int split_at;
+ static char rest[OPEN_MAX][BUFFER_SIZE + 1] = {{0}};
+
+ if (fd < 0 || fd > OPEN_MAX || line == NULL || BUFFER_SIZE <= 0)
+ return (STATUS_ERROR);
+ if ((*line = ft_strdup("")) == NULL)
+ return (STATUS_ERROR);
+ if (rest[fd][0] == '\0')
+ return (read_line(fd, line, rest[fd]));
+ if (HAS_NEWLINE(rest[fd], split_at))
+ {
+ free(*line);
+ if ((*line = (char*)malloc(sizeof(char) * (split_at + 1))) == NULL)
+ return (STATUS_ERROR);
+ ft_strncpy(*line, rest[fd], split_at);
+ (*line)[split_at] = '\0';
+ ft_strcpy(rest[fd], rest[fd] + split_at + 1);
+ return (STATUS_LINE);
+ }
+ free(*line);
+ if (!(*line = (char*)malloc(sizeof(char) * (ft_strlen(rest[fd]) + 1))))
+ return (STATUS_ERROR);
+ ft_strcpy(*line, rest[fd]);
+ rest[fd][0] = '\0';
+ return (read_line(fd, line, rest[fd]));
+}
+
+int read_line(int fd, char **line, char *rest)
+{
+ int ret;
+ int split_at;
+ char *buf;
+
+ if ((buf = malloc(sizeof(char) * (BUFFER_SIZE + 1))) == NULL)
+ return (free_return(line, NULL, STATUS_ERROR));
+ while ((ret = read(fd, buf, BUFFER_SIZE)) > 0)
+ {
+ buf[ret] = '\0';
+ if (HAS_NEWLINE(buf, split_at))
+ {
+ ft_strcpy(rest, buf + split_at + 1);
+ buf[split_at] = '\0';
+ if ((*line = ft_strjoin_free(*line, buf, 1)) == NULL)
+ return (free_return(&buf, NULL, STATUS_ERROR));
+ return (free_return(&buf, NULL, STATUS_LINE));
+ }
+ if ((*line = ft_strjoin_free(*line, buf, 1)) == NULL)
+ return (free_return(&buf, NULL, STATUS_ERROR));
+ }
+ if (ret == -1)
+ return (free_return(&buf, line, STATUS_ERROR));
+ return (free_return(&buf, NULL, ret));
+}
+
+int find_newline(char *str)
+{
+ int i;
+
+ i = -1;
+ while (str[++i])
+ if (str[i] == '\n')
+ return (i);
+ return (-1);
+}
+
+int free_return(char **ptr, char **ptr2, int ret)
+{
+ if (ptr != NULL)
+ {
+ free(*ptr);
+ *ptr = NULL;
+ }
+ if (ptr2 != NULL)
+ {
+ free(*ptr2);
+ *ptr2 = NULL;
+ }
+ return (ret);
+}
diff --git a/get_next_line.h b/get_next_line.h
new file mode 100644
index 0000000..4afd0fb
--- /dev/null
+++ b/get_next_line.h
@@ -0,0 +1,35 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* get_next_line.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2019/10/09 13:52:59 by cacharle #+# #+# */
+/* Updated: 2019/11/03 22:43:18 by cacharle ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#ifndef GET_NEXT_LINE_H
+# define GET_NEXT_LINE_H
+
+# include <limits.h>
+
+# ifndef BUFFER_SIZE
+# define BUFFER_SIZE 32
+# endif
+
+# define STATUS_LINE 1
+# define STATUS_EOF 0
+# define STATUS_ERROR -1
+
+/*
+** get_next_line.c
+*/
+
+int get_next_line(int fd, char **line);
+int read_line(int fd, char **line, char *rest);
+int find_newline(char *str);
+int free_return(char **ptr, char **rest, int ret);
+
+#endif
diff --git a/libft.h b/libft.h
index 7303028..1dff1c0 100644
--- a/libft.h
+++ b/libft.h
@@ -14,6 +14,7 @@
# define LIBFT_H
# include <string.h>
+# include "get_next_line.h"
# define TRUE 1
# define FALSE 0