minishell
get_next_line.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* get_next_line.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: kfujita <kfujita@student.42tokyo.jp> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2023/02/06 18:17:29 by kfujita #+# #+# */
9 /* Updated: 2023/02/07 01:00:36 by kfujita ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include "get_next_line.h"
14 #include "../ft_mem/ft_mem.h"
15 #include "../ft_vect/ft_vect.h"
16 
17 // - read
18 #include <unistd.h>
19 
20 // - ssize_t
21 #include <sys/types.h>
22 
23 // - free
24 #include <stdlib.h>
25 
27  // fd
28  0,
29  // buf
30  NULL,
31  // len
32  0,
33  // cap
34  0
35 };
36 
37 t_gnl_state gen_gnl_state(int fd, ssize_t cap)
38 {
39  t_gnl_state state;
40 
41  state = g_gnl_state_init_val;
42  state.buf = ft_calloc(cap, sizeof(char));
43  if (state.buf != NULL)
44  state.cap = cap;
45  state.fd = fd;
46  return (state);
47 }
48 
50 {
51  free(state->buf);
52  *state = g_gnl_state_init_val;
53 }
54 
55 // `\n` found: TRUE
56 // not found: FALSE
57 static bool check_and_update_state(t_vect *ret, t_gnl_state *state)
58 {
59  char *lf_ptr;
60  size_t append_len;
61 
62  if (state->len == 0)
63  return (false);
64  lf_ptr = (char *)ft_memchr(state->buf, '\n', state->len);
65  if (lf_ptr == NULL)
66  append_len = state->len;
67  else
68  append_len = lf_ptr - state->buf + 1;
69  vect_append_str(ret, state->buf, append_len);
70  if (lf_ptr != NULL)
71  {
72  ft_memmove(state->buf, state->buf + append_len,
73  state->len - append_len);
74  state->len -= append_len;
75  }
76  else
77  state->len = 0;
78  return (lf_ptr != NULL);
79 }
80 
82 {
83  t_vect ret;
84  ssize_t read_result;
85 
86  if (state == NULL || state->buf == NULL || state->cap == 0)
87  return (NULL);
88  ret = vect_init(0, sizeof(char));
89  if (check_and_update_state(&ret, state))
90  return (ret.p);
91  while (true)
92  {
93  read_result = read(state->fd, state->buf, state->cap);
94  if (read_result <= 0)
95  {
96  dispose_gnl_state(state);
97  if (ret.len == 0)
98  vect_dispose(&ret);
99  return (ret.p);
100  }
101  state->len = read_result;
102  if (check_and_update_state(&ret, state))
103  return (ret.p);
104  }
105 }
void * ft_calloc(size_t count, size_t size)
Definition: ft_calloc.c:29
void * ft_memchr(const void *s, int c, size_t n)
Definition: ft_memchr.c:16
void * ft_memmove(void *dst, const void *src, size_t n)
Definition: ft_memmove.c:16
void vect_dispose(t_vect *vect)
Definition: vect_dispose.c:16
bool vect_append_str(t_vect *vect, const char *value, size_t count)
t_vect vect_init(size_t cap, size_t elemsize)
Definition: vect_init.c:16
t_gnl_state gen_gnl_state(int fd, ssize_t cap)
Definition: get_next_line.c:37
char * get_next_line(t_gnl_state *state)
Definition: get_next_line.c:81
static bool check_and_update_state(t_vect *ret, t_gnl_state *state)
Definition: get_next_line.c:57
void dispose_gnl_state(t_gnl_state *state)
Definition: get_next_line.c:49
static const t_gnl_state g_gnl_state_init_val
Definition: get_next_line.c:26
ssize_t cap
Definition: get_next_line.h:27
ssize_t len
Definition: get_next_line.h:26
Definition: ft_vect.h:24
void * p
Definition: ft_vect.h:28
size_t len
Definition: ft_vect.h:26