diff options
| author | Charles <sircharlesaze@gmail.com> | 2019-11-03 00:19:45 +0100 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2019-11-03 00:19:45 +0100 |
| commit | 0a966722ec0236521d99706632a7fe56b7245379 (patch) | |
| tree | 461cbc387c4691363873bbf5a43c487be82019ea | |
| parent | 9f8c7ca113f0c69d17d8044120fcbd0ba78e1f92 (diff) | |
| download | get_next_line-0a966722ec0236521d99706632a7fe56b7245379.tar.gz get_next_line-0a966722ec0236521d99706632a7fe56b7245379.tar.bz2 get_next_line-0a966722ec0236521d99706632a7fe56b7245379.zip | |
Rewrite to handle massive BUFFER_SIZE
The rest is malloc'd (memory leaks if user doesnt read entier file)
The tmp buf in also malloc'd because the stack hasnt enought memory
| -rw-r--r-- | get_next_line.c | 106 | ||||
| -rw-r--r-- | get_next_line.h | 19 | ||||
| -rw-r--r-- | get_next_line_utils.c | 61 | ||||
| -rw-r--r-- | main.c | 5 |
4 files changed, 92 insertions, 99 deletions
diff --git a/get_next_line.c b/get_next_line.c index 03c7699..3434e5a 100644 --- a/get_next_line.c +++ b/get_next_line.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/10/19 09:08:36 by cacharle #+# #+# */ -/* Updated: 2019/10/27 23:22:33 by cacharle ### ########.fr */ +/* Updated: 2019/11/03 00:18:57 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,73 +33,61 @@ ** return GNL_EOF */ -int real_get_next_line(int fd, char **line, int ret, int counter) -{ - int split_at; - t_bool had_rest; - char buf[BUFFER_SIZE + 1]; - static char rest[OPEN_MAX][BUFFER_SIZE + 1] = {{0}}; - - if ((had_rest = put_rest(line, rest[fd])) == -1 || had_rest == -2) - return (had_rest == -1 ? LINE_READ : ERROR); - while (rest[fd][0] == '\0' && (ret = read(fd, buf, BUFFER_SIZE)) > 0) - { - counter++; - buf[ret] = '\0'; - if ((split_at = find_newline(buf)) != -1) - { - ft_strncpy(rest[fd], buf + split_at + 1, BUFFER_SIZE); - buf[split_at] = '\0'; - *line = ft_strappend(*line, buf); - return (*line == NULL ? ERROR : LINE_READ); - } - if ((*line = ft_strappend(*line, buf)) == NULL) - return (ERROR); - } - if (ret == -1) - return (clean_line(line, ERROR)); - return (had_rest || counter != 0 ? LINE_READ : clean_line(line, GNL_EOF)); -} +#define HAS_NEWLINE(str, split_at) ((split_at = find_newline(str)) != -1) +#define HAS_NO_NEWLINE(str, split_at) ((split_at = find_newline(str)) == -1) int get_next_line(int fd, char **line) { - int ret; - int counter; + int split_at; + static char *rest[OPEN_MAX] = {NULL}; - ret = 0; - counter = 0; - if (fd < 0 || fd > OPEN_MAX || line == NULL || BUFFER_SIZE < 0) - return (ERROR); - if (BUFFER_SIZE == 0) + if (fd < 0 || fd > OPEN_MAX || line == NULL || BUFFER_SIZE <= 0) + return (STATUS_ERROR); + *line = malloc(1); + (*line)[0] = 0; + if (rest[fd] == NULL || rest[fd][0] == 0) + return (read_line(fd, line, &rest[fd])); + if (HAS_NEWLINE(rest[fd], split_at)) { - *line = NULL; - return (LINE_READ); + 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); } - return (real_get_next_line(fd, line, ret, counter)); + if (!(*line = (char*)malloc(sizeof(char) * (ft_strlen(rest[fd]) + 1)))) + return (STATUS_ERROR); + ft_strcpy(*line, rest[fd]); + free(rest[fd]); + rest[fd] = NULL; + return (read_line(fd, line, &rest[fd])); } -int put_rest(char **line, char *rest) +int read_line(int fd, char **line, char **rest) { + int ret; int split_at; - t_bool had_rest; + char *buf; - had_rest = rest[0] != '\0'; - if ((split_at = find_newline(rest)) == -1) + if ((buf = malloc(sizeof(char) * (BUFFER_SIZE + 1))) == NULL) + return (STATUS_ERROR); + while ((ret = read(fd, buf, BUFFER_SIZE)) > 0) { - if ((*line = malloc(sizeof(char) * (ft_strlen(rest) + 1))) == NULL) - return (-2); - ft_strcpy(*line, rest); - rest[0] = '\0'; - return (had_rest); + buf[ret] = '\0'; + if (HAS_NEWLINE(buf, split_at)) + { + free(*rest); + *rest = ft_strdup(buf + split_at + 1); + buf[split_at] = '\0'; + if ((*line = ft_strappend(*line, buf)) == NULL) + return (free_return(&buf, STATUS_ERROR)); + return (free_return(&buf, STATUS_LINE)); + } + if ((*line = ft_strappend(*line, buf)) == NULL) + return (free_return(&buf, STATUS_ERROR)); } - if (split_at + 1 == ft_strlen(rest)) - had_rest = -1; - if ((*line = malloc(sizeof(char) * (split_at + 1))) == NULL) - return (-2); - ft_strncpy(*line, rest, split_at); - (*line)[split_at] = '\0'; - ft_strncpy(rest, rest + split_at + 1, BUFFER_SIZE); - return (had_rest); + return (free_return(&buf, ret)); } int find_newline(char *str) @@ -113,9 +101,11 @@ int find_newline(char *str) return (-1); } -int clean_line(char **line, int ret) +int free_return(char **ptr, int ret) { - free(*line); - *line = NULL; + if (ptr == NULL) + return (ret); + free(*ptr); + *ptr = NULL; return (ret); } diff --git a/get_next_line.h b/get_next_line.h index 151de60..0924d0c 100644 --- a/get_next_line.h +++ b/get_next_line.h @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/10/09 13:52:59 by cacharle #+# #+# */ -/* Updated: 2019/10/27 21:50:05 by cacharle ### ########.fr */ +/* Updated: 2019/11/03 00:10:24 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,33 +19,34 @@ # define BUFFER_SIZE 32 # endif -# define LINE_READ 1 -# define GNL_EOF 0 -# define ERROR -1 +# define STATUS_LINE 1 +# define STATUS_EOF 0 +# define STATUS_ERROR -1 # define TRUE 1 # define FALSE 0 +# define FT_STRNCPY_BUF(dest, src) (ft_strncpy(dest, src, BUFFER_SIZE + 1)) + typedef int t_bool; /* ** get_next_line.c */ -int real_get_next_line(int fd, char **line, int ret, int counter); int get_next_line(int fd, char **line); -int put_rest(char **line, char *rest); +int read_line(int fd, char **line, char **rest); int find_newline(char *str); -int clean_line(char **line, int ret); +int free_return(char **ptr, int ret); /* ** get_next_line_utils.c - helper functions */ +char *ft_strappend(char *dest, char *src); char *ft_strncpy(char *dest, const char *src, int n); int ft_strlen(char *str); -char *ft_strcat(char *dest, const char *src); char *ft_strcpy(char *dest, const char *src); -char *ft_strappend(char *dest, char *src); +char *ft_strdup(const char *s); #endif diff --git a/get_next_line_utils.c b/get_next_line_utils.c index 61c8055..92cb208 100644 --- a/get_next_line_utils.c +++ b/get_next_line_utils.c @@ -6,13 +6,32 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/10/08 08:52:59 by cacharle #+# #+# */ -/* Updated: 2019/10/27 19:02:57 by cacharle ### ########.fr */ +/* Updated: 2019/11/02 23:01:40 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include <stdlib.h> #include "get_next_line.h" +char *ft_strappend(char *dest, char *src) +{ + void *copy; + int dest_len; + + dest_len = ft_strlen(dest); + if ((copy = (char*)malloc(sizeof(char) * (dest_len + 1))) == NULL) + return (NULL); + ft_strcpy(copy, dest); + free(dest); + dest = (char*)malloc(sizeof(char) * (dest_len + ft_strlen(src) + 1)); + if (dest == NULL) + return (NULL); + ft_strcpy(dest, copy); + free(copy); + ft_strcpy(dest + dest_len, src); + return (dest); +} + char *ft_strncpy(char *dest, const char *src, int n) { int i; @@ -38,23 +57,6 @@ int ft_strlen(char *str) return (counter); } -char *ft_strappend(char *dest, char *src) -{ - void *copy; - - if ((copy = (char*)malloc(sizeof(char) * (ft_strlen(dest) + 1))) == NULL) - return (NULL); - ft_strcpy(copy, dest); - free(dest); - dest = (char*)malloc(sizeof(char) * (ft_strlen(copy) + ft_strlen(src) + 1)); - if (dest == NULL) - return (NULL); - ft_strcpy(dest, copy); - free(copy); - ft_strcat(dest, src); - return (dest); -} - char *ft_strcpy(char *dest, const char *src) { int i; @@ -69,20 +71,21 @@ char *ft_strcpy(char *dest, const char *src) return (dest); } -char *ft_strcat(char *dest, const char *src) +char *ft_strdup(const char *s) { - int i; - int j; + char *clone; + size_t i; + size_t len; + len = ft_strlen((char*)s); + if ((clone = (char*)malloc(sizeof(char) * (len + 1))) == NULL) + return (NULL); i = 0; - while (dest[i]) - i++; - j = 0; - while (src[j]) + while (i < len) { - dest[i + j] = src[j]; - j++; + clone[i] = s[i]; + i++; } - dest[i + j] = '\0'; - return (dest); + clone[i] = '\0'; + return (clone); } @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/10/10 09:27:41 by cacharle #+# #+# */ -/* Updated: 2019/10/27 19:08:20 by cacharle ### ########.fr */ +/* Updated: 2019/11/02 22:42:58 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,7 +24,6 @@ int main(int argc, char **argv) char *line; int ret; - printf("limit fdmax %d\n", OPEN_MAX); if (argc != 2) { printf("You forgot the filename"); @@ -33,7 +32,7 @@ int main(int argc, char **argv) printf("BUFFER_SIZE = %d\n", BUFFER_SIZE); fd = open(argv[1], O_RDONLY); i = 0; - while ((ret = get_next_line(fd, &line)) == LINE_READ) + while ((ret = get_next_line(fd, &line)) == STATUS_LINE) { printf("%3d [%s]\n", ++i, line); free(line); |
