words_expansions() complete
+ TODO : need refactoring and fix to valgrind invalid read size + redirections() WIP + Generic ft_dup_2d_arr(), ft_split_quotes(), ft_strdup_quotes() + shell_loop() continue on error + various small fix
This commit is contained in:
1
Makefile
1
Makefile
@@ -29,6 +29,7 @@ SRCS = main.c init.c free.c generic.c \
|
||||
parsing.c alloc_cmd_array.c \
|
||||
valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \
|
||||
words_expansions.c expand_token.c rejoin_after_expand.c new_token_for_each_field.c \
|
||||
ft_split_quotes.c ft_strdup_quotes.c \
|
||||
env.c exit.c echo.c
|
||||
|
||||
DIR_OBJS = builds
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/07 04:13:53 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/13 04:20:43 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -57,5 +57,7 @@ void *ft_resize_2d_arr(void *ptr, size_t add_nbr);
|
||||
void print_matrix(char **matrix, char *sep);
|
||||
t_list *ft_lstbeforelast(t_list *lst);
|
||||
t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size);
|
||||
typedef void *(*t_dup_func)(void *);
|
||||
void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */
|
||||
/* Updated: 2021/10/30 13:31:07 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/11 07:21:47 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -23,7 +23,8 @@ enum e_token_id
|
||||
T_PIPE = '|',
|
||||
T_DLESS,
|
||||
T_DGREAT,
|
||||
T_WORD
|
||||
T_WORD,
|
||||
T_REDIRECTION_WORD
|
||||
};
|
||||
// T_DLESS == '<<'
|
||||
// T_DGREAT == '>>'
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/07 04:07:10 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/13 04:23:54 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -85,7 +85,7 @@ size_t ft_2d_arrlen(void *ptr) // Replace ft_arrlen()
|
||||
return (len);
|
||||
}
|
||||
|
||||
char **ft_dup_2d_char_arr(char **ptr)
|
||||
char **ft_dup_2d_char_arr(char **ptr) // Superflu si ft_dup_2d_arr() fonctionne
|
||||
{
|
||||
unsigned int i;
|
||||
char **arr;
|
||||
@@ -107,6 +107,29 @@ char **ft_dup_2d_char_arr(char **ptr)
|
||||
return (new_arr);
|
||||
}
|
||||
|
||||
// Test generic. Pas certain que ça fonctionne bien avec le pointeur sur fonction
|
||||
void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *))
|
||||
{
|
||||
unsigned int i;
|
||||
char **arr;
|
||||
char **new_arr;
|
||||
|
||||
new_arr = malloc((ft_2d_arrlen(ptr) + 1) * sizeof (void *));
|
||||
if (!new_arr)
|
||||
return (NULL);
|
||||
arr = (char **)ptr;
|
||||
i = 0;
|
||||
while (arr[i])
|
||||
{
|
||||
new_arr[i] = dup_func(arr[i]);
|
||||
if (!new_arr[i])
|
||||
return (ft_retp_free(NULL, new_arr, ft_free_2d_arr));
|
||||
i++;
|
||||
}
|
||||
new_arr[i] = NULL;
|
||||
return (new_arr);
|
||||
}
|
||||
|
||||
void *ft_resize_2d_arr(void *ptr, size_t add_nbr)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -151,7 +174,7 @@ t_list *ft_lstbeforelast(t_list *lst)
|
||||
return (lst);
|
||||
}
|
||||
|
||||
t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size)
|
||||
t_list *ft_lstnew_generic(size_t lst_size, size_t content_size)
|
||||
{
|
||||
t_list *elem;
|
||||
void *content;
|
||||
@@ -164,7 +187,7 @@ t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size)
|
||||
if (!content)
|
||||
return (NULL);
|
||||
}
|
||||
elem = ft_calloc(1, lst_sizse);
|
||||
elem = ft_calloc(1, lst_size);
|
||||
if (!elem)
|
||||
{
|
||||
free(content);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/02 13:50:33 by hulamy ### ########.fr */
|
||||
/* Updated: 2021/11/13 05:31:47 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -19,9 +19,10 @@ int init(t_all *c, char *envp[])
|
||||
{
|
||||
g_all = c;
|
||||
ft_bzero(c, sizeof (*c));
|
||||
c->envp = ft_dup_2d_char_arr(envp);
|
||||
c->envp = ft_dup_2d_arr(envp, (t_dup_func)ft_strdup); // TEST WIP
|
||||
if (!c->envp)
|
||||
return (ft_reti_perror(0, "ft_dup_2d_char_arr(envp) error"));
|
||||
//print_matrix(c->envp, "\n --- \n"); // TEST WIP
|
||||
c->prompt_base = init_prompt_base();
|
||||
if (!c->prompt_base)
|
||||
return (ft_reti_perror(0, "init_prompt_base() error"));
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/11/02 22:46:23 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/07 04:29:54 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/11 08:47:46 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -43,6 +43,8 @@ t_cmd **alloc_cmd_array(size_t cmd_nbr)
|
||||
ft_free_2d_arr(cmd_arr);
|
||||
return (ft_retp_perror(NULL, "alloc_cmd()"));
|
||||
}
|
||||
cmd_arr[i]->fd_in = STDIN_FILENO;
|
||||
cmd_arr[i]->fd_out = STDOUT_FILENO;
|
||||
i++;
|
||||
}
|
||||
return (cmd_arr);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/07 04:36:12 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/11 21:04:41 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -21,9 +21,9 @@ enum e_in_quote_state
|
||||
IN_DQUOTES = '\"'
|
||||
};
|
||||
|
||||
static t_list *ret_parameter_expansion(t_token *t, int *i);
|
||||
static t_list *ret_parameter_expansion(char *content, int *i);
|
||||
|
||||
t_list *expand_token(t_token *t)
|
||||
t_list *expand_token(char *content)
|
||||
{
|
||||
int in_quotes;
|
||||
int i;
|
||||
@@ -35,11 +35,11 @@ t_list *expand_token(t_token *t)
|
||||
i = 0;
|
||||
head.next = NULL;
|
||||
expand = &head;
|
||||
while (t->content[i])
|
||||
while (content[i])
|
||||
{
|
||||
if (t->content[i] == '$')
|
||||
if (content[i] == '$')
|
||||
{
|
||||
expand->next = ret_parameter_expansion(t, &i);
|
||||
expand->next = ret_parameter_expansion(content, &i);
|
||||
expand = expand->next;
|
||||
if (!expand)
|
||||
{//todo wrap
|
||||
@@ -49,7 +49,7 @@ t_list *expand_token(t_token *t)
|
||||
}
|
||||
else
|
||||
{
|
||||
expand->next = ft_lstnew_generic(sizeof(t_list), ft_strlen(&t->content[i]) + 1);
|
||||
expand->next = ft_lstnew_generic(sizeof(t_list), ft_strlen(&content[i]) + 1);
|
||||
expand = expand->next;
|
||||
i_exp = 0;
|
||||
if (!expand)
|
||||
@@ -57,17 +57,17 @@ t_list *expand_token(t_token *t)
|
||||
perror("expand_token() error");
|
||||
return (ft_lstclear(&head.next, free));
|
||||
}
|
||||
while (t->content[i] && (t->content[i] != '$' || in_quotes == IN_QUOTES))
|
||||
while (content[i] && (content[i] != '$' || in_quotes == IN_QUOTES))
|
||||
{
|
||||
// quoting
|
||||
if (t->content[i] == '\'' && in_quotes != IN_DQUOTES)
|
||||
if (content[i] == '\'' && in_quotes != IN_DQUOTES)
|
||||
{
|
||||
if (in_quotes == IN_QUOTES)
|
||||
in_quotes = 0;
|
||||
else
|
||||
in_quotes = IN_QUOTES;
|
||||
}
|
||||
((char *)expand->content)[i_exp++] = t->content[i++];
|
||||
((char *)expand->content)[i_exp++] = content[i++];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,35 +76,34 @@ t_list *expand_token(t_token *t)
|
||||
|
||||
// a voir si je retourne pas plutot un "char *".
|
||||
// Malloc la lst dans la fonction est peut-être un peu superflu et pas super clair.
|
||||
// et aussi changer "t_token *t" en "char *content", inutile d'avoir le token entier.
|
||||
static t_list *ret_parameter_expansion(t_token *t, int *i)
|
||||
static t_list *ret_parameter_expansion(char *content, int *i)
|
||||
{
|
||||
t_list *expand;
|
||||
char *tmp;
|
||||
int i_tmp;
|
||||
|
||||
tmp = ft_calloc(ft_strlen(&t->content[*i]) + 1, 1);
|
||||
tmp = ft_calloc(ft_strlen(&content[*i]) + 1, 1);
|
||||
if (!tmp)
|
||||
return (NULL);
|
||||
expand = ft_lstnew(NULL);
|
||||
if (!expand)
|
||||
return (ft_retp_free(NULL, tmp, free));
|
||||
(*i)++; // skip '$'
|
||||
if (t->content[*i] == '?')
|
||||
if (content[*i] == '?')
|
||||
{
|
||||
(*i)++;
|
||||
expand->content = ft_itoa(g_all->last_exit_status);
|
||||
return (ft_retp_free(expand, tmp, free));
|
||||
}
|
||||
else if (t->content[*i] != '_' && !ft_isalpha(t->content[*i]))
|
||||
else if (content[*i] != '_' && !ft_isalpha(content[*i]))
|
||||
{
|
||||
tmp[0] = '$';
|
||||
expand->content = tmp;
|
||||
return (expand);
|
||||
}
|
||||
i_tmp = 0;
|
||||
while (t->content[*i] == '_' || ft_isalnum(t->content[*i]))
|
||||
tmp[i_tmp++] = t->content[(*i)++];
|
||||
while (content[*i] == '_' || ft_isalnum(content[*i]))
|
||||
tmp[i_tmp++] = content[(*i)++];
|
||||
expand->content = getenv(tmp);
|
||||
free(tmp);
|
||||
if (expand->content)
|
||||
|
||||
186
srcs/parsing/expansions/ft_split_quotes.c
Normal file
186
srcs/parsing/expansions/ft_split_quotes.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_split_quotes.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/11/13 07:08:40 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/13 22:35:34 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "minishell.h"
|
||||
|
||||
enum e_in_quote_state
|
||||
{
|
||||
NOT_IN = 0,
|
||||
IN_QUOTES = '\'',
|
||||
IN_DQUOTES = '\"'
|
||||
};
|
||||
|
||||
static size_t count_word(char const *s, char c);
|
||||
static char **alloc_words(char const *s, char c, char **str_arr,
|
||||
size_t words_count);
|
||||
static void fill_arr(char const *s, char c, char **str_arr);
|
||||
static int quote_state_change(int *quote_state, const char *s);
|
||||
|
||||
char **ft_split_quotes(char const *s, char c)
|
||||
{
|
||||
char **str_arr;
|
||||
size_t words_count;
|
||||
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
words_count = count_word(s, c);
|
||||
str_arr = ft_calloc(words_count + 1, sizeof(char *));
|
||||
if (!str_arr)
|
||||
return (NULL);
|
||||
if (!(alloc_words(s, c, str_arr, words_count)))
|
||||
{
|
||||
ft_free_2d_arr(str_arr);
|
||||
return (NULL);
|
||||
}
|
||||
fill_arr(s, c, str_arr);
|
||||
return (str_arr);
|
||||
}
|
||||
|
||||
static size_t count_word(char const *s, char c)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t count;
|
||||
int quote_state;
|
||||
|
||||
i = 0;
|
||||
count = 0;
|
||||
quote_state = 0;
|
||||
while (s[i])
|
||||
{
|
||||
while (s[i] == c)
|
||||
i++;
|
||||
if (s[i])
|
||||
count++;
|
||||
while (s[i] && (s[i] != c || quote_state))
|
||||
{
|
||||
while (quote_state_change("e_state, &s[i]))
|
||||
i++;
|
||||
if (s[i] != c || quote_state)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
static char **alloc_words(char const *s, char c, char **str_arr,
|
||||
size_t words_count)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t len;
|
||||
unsigned int arr_i;
|
||||
int quote_state;
|
||||
|
||||
i = 0;
|
||||
arr_i = 0;
|
||||
quote_state = 0;
|
||||
while (arr_i < words_count)
|
||||
{
|
||||
len = 0;
|
||||
while (s[i] == c)
|
||||
i++;
|
||||
while (s[i + len]
|
||||
&& (quote_state_change("e_state, &s[i + len])
|
||||
|| (s[i + len] != c || quote_state)))
|
||||
len++;
|
||||
i = i + len;
|
||||
str_arr[arr_i] = ft_calloc(len + 1, 1);
|
||||
if (!str_arr[arr_i])
|
||||
return (NULL);
|
||||
arr_i++;
|
||||
}
|
||||
return (str_arr);
|
||||
}
|
||||
|
||||
// Plus clair, plus de 25 lignes :(
|
||||
/* static char **alloc_words(char const *s, char c, char **str_arr,
|
||||
size_t words_count)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t len;
|
||||
unsigned int arr_i;
|
||||
int quote_state;
|
||||
|
||||
i = 0;
|
||||
arr_i = 0;
|
||||
quote_state = 0;
|
||||
while (arr_i < words_count)
|
||||
{
|
||||
len = 0;
|
||||
while (s[i] == c)
|
||||
i++;
|
||||
while (s[i + len] && (s[i + len] != c || quote_state))
|
||||
{
|
||||
while (quote_state_change("e_state, &s[i + len]))
|
||||
len++;
|
||||
if (s[i + len] != c || quote_state)
|
||||
len++;
|
||||
}
|
||||
i = i + len;
|
||||
str_arr[arr_i] = ft_calloc(len + 1, 1);
|
||||
if (!str_arr[arr_i])
|
||||
return (NULL);
|
||||
arr_i++;
|
||||
}
|
||||
return (str_arr);
|
||||
} */
|
||||
|
||||
static void fill_arr(char const *s, char c, char **str_arr)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int arr_i;
|
||||
unsigned int char_i;
|
||||
int quote_state;
|
||||
|
||||
i = 0;
|
||||
arr_i = 0;
|
||||
quote_state = 0;
|
||||
while (str_arr[arr_i])
|
||||
{
|
||||
while (s[i] == c)
|
||||
i++;
|
||||
char_i = 0;
|
||||
while (s[i] && (s[i] != c || quote_state))
|
||||
{
|
||||
while (quote_state_change("e_state, &s[i]))
|
||||
str_arr[arr_i][char_i++] = s[i++];
|
||||
if (s[i] != c || quote_state)
|
||||
str_arr[arr_i][char_i++] = s[i++];
|
||||
}
|
||||
str_arr[arr_i][char_i] = '\0'; //superflu si ft_calloc
|
||||
arr_i++;
|
||||
}
|
||||
}
|
||||
|
||||
static int quote_state_change(int *quote_state, const char *s)
|
||||
{
|
||||
if (s[0] == '\'' && *quote_state != IN_DQUOTES)
|
||||
{
|
||||
if (*quote_state == IN_QUOTES)
|
||||
*quote_state = 0;
|
||||
else if (ft_strchr(&s[1], '\'')) // if closed quotes
|
||||
*quote_state = IN_QUOTES;
|
||||
else
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
else if (s[0] == '\"' && *quote_state != IN_QUOTES)
|
||||
{
|
||||
if (*quote_state == IN_DQUOTES)
|
||||
*quote_state = 0;
|
||||
else if (ft_strchr(&s[1], '\"')) // if closed quotes
|
||||
*quote_state = IN_DQUOTES;
|
||||
else
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
68
srcs/parsing/expansions/ft_strdup_quotes.c
Normal file
68
srcs/parsing/expansions/ft_strdup_quotes.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_strdup_quotes.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/11/13 04:35:06 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/13 10:18:51 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "minishell.h"
|
||||
|
||||
enum e_in_quote_state
|
||||
{
|
||||
NOT_IN = 0,
|
||||
IN_QUOTES = '\'',
|
||||
IN_DQUOTES = '\"'
|
||||
};
|
||||
static int quote_state_change(int *quote_state, const char *s);
|
||||
|
||||
char *ft_strdup_quotes(const char *s)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i_dup;
|
||||
char *dup;
|
||||
int quote_state;
|
||||
|
||||
dup = ft_calloc(ft_strlen(s) + 1, 1);
|
||||
if (!dup)
|
||||
return (NULL);
|
||||
i = 0;
|
||||
i_dup = 0;
|
||||
quote_state = 0;
|
||||
while (s[i])
|
||||
{
|
||||
while (quote_state_change("e_state, &s[i]))
|
||||
i++;
|
||||
dup[i_dup++] = s[i++];
|
||||
}
|
||||
return (dup);
|
||||
}
|
||||
|
||||
static int quote_state_change(int *quote_state, const char *s)
|
||||
{
|
||||
if (s[0] == '\'' && *quote_state != IN_DQUOTES)
|
||||
{
|
||||
if (*quote_state == IN_QUOTES)
|
||||
*quote_state = 0;
|
||||
else if (ft_strchr(&s[1], '\'')) // if closed quotes
|
||||
*quote_state = IN_QUOTES;
|
||||
else
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
else if (s[0] == '\"' && *quote_state != IN_QUOTES)
|
||||
{
|
||||
if (*quote_state == IN_DQUOTES)
|
||||
*quote_state = 0;
|
||||
else if (ft_strchr(&s[1], '\"')) // if closed quotes
|
||||
*quote_state = IN_DQUOTES;
|
||||
else
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@@ -27,16 +27,21 @@ int new_token_for_each_field(char **fields, t_token **t)
|
||||
i = 0;
|
||||
while (fields[i])
|
||||
{
|
||||
insert_lst->next = (t_token *)ft_lstnew_generic(sizeof(*insert_lst), 0);
|
||||
insert_lst = insert_lst->next;
|
||||
if (!insert_lst)
|
||||
{//todo wrap
|
||||
perror("insert_token_for_each_field() error");
|
||||
ft_free_2d_arr(fields);
|
||||
return ((int)ft_lstclear((t_list **)&head.next, NULL));
|
||||
if (fields[i][0])
|
||||
{
|
||||
insert_lst->next = (t_token *)ft_lstnew_generic(sizeof(t_token), 0);
|
||||
insert_lst = insert_lst->next;
|
||||
if (!insert_lst)
|
||||
{//todo wrap
|
||||
perror("insert_token_for_each_field() error");
|
||||
ft_free_2d_arr(fields);
|
||||
return ((int)ft_lstclear((t_list **)&head.next, NULL));
|
||||
}
|
||||
insert_lst->content = fields[i];
|
||||
insert_lst->id = T_WORD;
|
||||
}
|
||||
insert_lst->content = fields[i];
|
||||
insert_lst->id = T_WORD;
|
||||
else
|
||||
free(fields[i]);
|
||||
i++;
|
||||
}
|
||||
free(fields);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/08 03:59:02 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/13 21:27:20 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -20,15 +20,18 @@ enum e_in_quote_state
|
||||
};
|
||||
|
||||
t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size);
|
||||
t_list *expand_token(t_token *t);
|
||||
t_list *expand_token(char *content);
|
||||
char *rejoin_after_expand(t_list *expand_lst);
|
||||
char **ft_split_quotes(char const *s, char c); // Generic
|
||||
char *ft_strdup_quotes(const char *s); // Generic
|
||||
int new_token_for_each_field(char **fields, t_token **t);
|
||||
|
||||
// 1 - chaque bout dans un element d'une t_list
|
||||
// (telle quelle si non expand, ou VARIABLE de env)
|
||||
// 2 - strjoin() le tout
|
||||
// 3 - split avec un ft_strplit() modifié (ne splitant pas dans les quotes)
|
||||
// 4 - creer un token T_WORD pour chaque *string du **split_arr
|
||||
// 4 - quotes removal, ft_strdup_quotes() le tableau split
|
||||
// 5 - creer un token T_WORD pour chaque *string du **split_arr
|
||||
// (ft_lstadd_front() sur le token original, puis set le token orignal à :
|
||||
// t->id = 0 ; free(t->content) ; t->content = NULL ; pour qu'il soit ignoré sur la suite du parsing)
|
||||
|
||||
@@ -42,19 +45,25 @@ int words_expansions(t_token *t)
|
||||
if (t->id == T_WORD)
|
||||
{
|
||||
// 1
|
||||
tmp_expand = expand_token(t);
|
||||
tmp_expand = expand_token(t->content);
|
||||
if (!tmp_expand)
|
||||
return (0);
|
||||
// 2
|
||||
tmp_expand = rejoin_after_expand(tmp_expand);
|
||||
if (!tmp_expand)
|
||||
return (0);
|
||||
// 3 WIP PLACEHOLDER, MUST WRITE A ft_split_quoted() FOR NO SPLIT IN QUOTES
|
||||
tmp_split = ft_split(tmp_expand, ' ');
|
||||
// 3
|
||||
tmp_split = ft_split_quotes(tmp_expand, ' ');
|
||||
free(tmp_expand);
|
||||
if (!tmp_split)
|
||||
return (0);
|
||||
// 4
|
||||
tmp_expand = ft_dup_2d_arr(tmp_split, (t_dup_func)ft_strdup_quotes);
|
||||
ft_free_2d_arr(tmp_split);
|
||||
tmp_split = tmp_expand;
|
||||
if (!tmp_split)
|
||||
return (0);
|
||||
// 5
|
||||
if (!new_token_for_each_field(tmp_split, &t))
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/08 01:03:29 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/13 05:13:40 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -25,28 +25,72 @@ int next_cmd(t_token *token);
|
||||
int is_redirection(enum e_token_id id);
|
||||
// HUGO WIP
|
||||
|
||||
void save_redirections_words(t_token *t)
|
||||
{
|
||||
while (t)
|
||||
{
|
||||
if (t->id == '>' || t->id == T_DGREAT
|
||||
|| t->id == '<' || t->id == T_DLESS)
|
||||
{
|
||||
t = t->next;
|
||||
t->id = T_REDIRECTION_WORD;
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
}
|
||||
|
||||
void ft_free_cmd_arr(t_cmd **cmd_arr)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (cmd_arr[i])
|
||||
{
|
||||
if (cmd_arr[i]->argv)
|
||||
ft_free_2d_arr(cmd_arr[i]->argv);
|
||||
if (cmd_arr[i]->fd_in != STDIN_FILENO && cmd_arr[i]->fd_in > 0)
|
||||
if (close(cmd_arr[i]->fd_in) == -1)
|
||||
perror("close()");
|
||||
if (cmd_arr[i]->fd_out != STDOUT_FILENO && cmd_arr[i]->fd_out > 0)
|
||||
if (close(cmd_arr[i]->fd_out) == -1)
|
||||
perror("close()");
|
||||
i++;
|
||||
}
|
||||
ft_free_2d_arr(cmd_arr);
|
||||
}
|
||||
|
||||
t_cmd **parsing(t_token *token_list)
|
||||
{
|
||||
t_cmd **cmd_arr;
|
||||
|
||||
if (!valid_syntax(token_list))
|
||||
return (NULL);
|
||||
// Struct CMD alloc
|
||||
cmd_arr = alloc_cmd_array(count_pipes(token_list) + 1);
|
||||
if (!cmd_arr)
|
||||
return (NULL);
|
||||
|
||||
// 2.9.1 - 1) Save Words
|
||||
save_redirections_words(token_list);
|
||||
|
||||
// 2.9.1 - 2) Expansion
|
||||
// TEST TOKENS PRINT
|
||||
ft_putstr_fd("TOKENS LIST :\n-----------\n", 1);
|
||||
ft_lstprint((t_list *)token_list, 1);
|
||||
//
|
||||
words_expansions(token_list);
|
||||
// getenv() ne va pas fonctionner avec le changement d'environnement prévu jusqu'ici.
|
||||
// TODO : Revoir le changement d'environnement (avec extern char **environ ?)
|
||||
// OU Integrer un equivalent perso comme dans pipex
|
||||
if (!words_expansions(token_list))
|
||||
return (NULL);
|
||||
//
|
||||
ft_putstr_fd("TOKENS LIST EXPANDED :\n-----------\n", 1);
|
||||
ft_lstprint((t_list *)token_list, 1);
|
||||
|
||||
// Struct CMD alloc
|
||||
cmd_arr = alloc_cmd_array(1 + count_pipes(token_list));
|
||||
if (!cmd_arr)
|
||||
return (NULL);
|
||||
|
||||
// 2.9.1 - 3) Redirection
|
||||
/* if (!redirections(token_list, cmd_arr))
|
||||
return (ft_retp_free(NULL, cmd_arr, ft_free_cmd_arr)); */
|
||||
|
||||
// Struct CMD fill
|
||||
|
||||
|
||||
100
srcs/parsing/redirections.c
Normal file
100
srcs/parsing/redirections.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* redirections.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/12 20:17:09 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "minishell.h"
|
||||
|
||||
int ft_reti_perror_io(int ret, char *err_str, char *io_file) // generic
|
||||
{
|
||||
ft_putstr_fd(err_str, 2);
|
||||
perror(io_file);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int here_doc_handle_PLACEHOLDER(char *delimiter)
|
||||
{
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
|
||||
/* If any part of word is quoted,
|
||||
the delimiter shall be formed by performing quote removal on word,
|
||||
and the here-document lines shall not be expanded.
|
||||
Otherwise, the delimiter shall be the word itself. */
|
||||
// Pas d'expansion sur le delimiter, mais quote removal tout de même.
|
||||
// TODO : quote removal sur le delimiter.
|
||||
QUOTE_REMOVAL_PLACEHOLDER();
|
||||
}
|
||||
|
||||
int redirect_cmd_input(t_token *t, t_cmd *cmd)
|
||||
{
|
||||
if (cmd->fd_in != STDIN_FILENO && cmd->fd_in > 0)
|
||||
if (close(cmd->fd_in) == -1)
|
||||
perror("close()");
|
||||
if (t->id == '<')
|
||||
{
|
||||
// TODO : Expansion + quote removal sur le word t->next->content.
|
||||
// si plus d'un champ ou aucun champ aprés expansion,
|
||||
// message d'erreur comme bash "bash: $VAR: ambiguous redirect"
|
||||
// OU prise en compte seulement du premier champ.
|
||||
EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER();
|
||||
cmd->fd_in = open(t->next->content, O_RDONLY);
|
||||
if (cmd->fd_in == -1)
|
||||
ft_reti_perror_io(0, "open() ", t->next->content);
|
||||
}
|
||||
else if (t->id == T_DLESS)
|
||||
cmd->fd_in = here_doc_handle_PLACEHOLDER(t->next->content); // TODO
|
||||
return (1);
|
||||
}
|
||||
|
||||
int redirect_cmd_output(t_token *t, t_cmd *cmd)
|
||||
{
|
||||
int flags;
|
||||
|
||||
if (cmd->fd_out != STDOUT_FILENO && cmd->fd_out > 0)
|
||||
if (close(cmd->fd_out) == -1)
|
||||
perror("close()");
|
||||
// TODO : Expansion + quote removal sur le word t->next->content.
|
||||
// si plus d'un champ ou aucun champ aprés expansion,
|
||||
// message d'erreur comme bash "bash: $VAR: ambiguous redirect"
|
||||
// OU prise en compte seulement du premier champ.
|
||||
EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER();
|
||||
if (t->id == '>')
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
else if (t->id == T_DGREAT)
|
||||
flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||
cmd->fd_out = open(t->next->content, flags, S_IRWXU);
|
||||
if (cmd->fd_out == -1)
|
||||
return (ft_reti_perror_io(0, "open() ", t->next->content));
|
||||
return (1);
|
||||
}
|
||||
|
||||
int redirections(t_token *t, t_cmd **cmd_arr)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (t)
|
||||
{
|
||||
if (t->id == '<' || t->id == T_DLESS)
|
||||
{
|
||||
if (!redirect_cmd_input(t, cmd_arr[i]))
|
||||
return (0);
|
||||
}
|
||||
else if (t->id == '>' || t->id == T_DGREAT)
|
||||
{
|
||||
if (!redirect_cmd_output(t, cmd_arr[i]))
|
||||
return (0);
|
||||
}
|
||||
else if (t->id == '|')
|
||||
i++;
|
||||
t = t->next;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/02 22:38:35 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/08 05:16:48 by lperrey ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -32,14 +32,18 @@ void shell_loop(t_all *c)
|
||||
if (line_input && *line_input)
|
||||
{
|
||||
add_history(line_input);
|
||||
//test_signal(c);
|
||||
// Lexing
|
||||
c->token_list = input_to_tokens(line_input);
|
||||
if (!c->token_list)
|
||||
continue ;
|
||||
// Parsing
|
||||
c->cmd_arr = parsing(c->token_list);
|
||||
ft_lstclear((t_list **)&c->token_list, free);
|
||||
if (!c->cmd_arr)
|
||||
continue ;
|
||||
// Search Path/builtins
|
||||
// Exec
|
||||
// Bien penser à mettre les ptr à NULL aprés free en cas d'erreur (pour ne pas double free si appel à free_exit())
|
||||
// Exec Pipeline
|
||||
//execute_cmd(c->envp, c->cmd_arr);
|
||||
}
|
||||
else if (!line_input)
|
||||
|
||||
157
valgrind_invalid_read_to_fix.txt
Normal file
157
valgrind_invalid_read_to_fix.txt
Normal file
@@ -0,0 +1,157 @@
|
||||
lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> 3[5;6;35
|
||||
TOKENS LIST :
|
||||
-----------
|
||||
3[5;6;35
|
||||
TOKENS LIST EXPANDED :
|
||||
-----------
|
||||
3[5;6;35
|
||||
lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> [6;34'.6'
|
||||
TOKENS LIST :
|
||||
-----------
|
||||
[6;34'.6'
|
||||
==2095== Invalid read of size 1
|
||||
==2095== at 0x403938: count_word (ft_split_quotes.c:63)
|
||||
==2095== by 0x403806: ft_split_quotes (ft_split_quotes.c:35)
|
||||
==2095== by 0x402FC0: words_expansions (words_expansions.c:56)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23)
|
||||
==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29)
|
||||
==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29)
|
||||
==2095== by 0x402F97: words_expansions (words_expansions.c:52)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
==2095== Invalid read of size 1
|
||||
==2095== at 0x4038D1: count_word (ft_split_quotes.c:57)
|
||||
==2095== by 0x403806: ft_split_quotes (ft_split_quotes.c:35)
|
||||
==2095== by 0x402FC0: words_expansions (words_expansions.c:56)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23)
|
||||
==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29)
|
||||
==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29)
|
||||
==2095== by 0x402F97: words_expansions (words_expansions.c:52)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
==2095== Invalid read of size 1
|
||||
==2095== at 0x403C0F: fill_arr (ft_split_quotes.c:151)
|
||||
==2095== by 0x403888: ft_split_quotes (ft_split_quotes.c:44)
|
||||
==2095== by 0x402FC0: words_expansions (words_expansions.c:56)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23)
|
||||
==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29)
|
||||
==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29)
|
||||
==2095== by 0x402F97: words_expansions (words_expansions.c:52)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
==2095== Invalid write of size 1
|
||||
==2095== at 0x403D30: fill_arr (ft_split_quotes.c:158)
|
||||
==2095== by 0x403888: ft_split_quotes (ft_split_quotes.c:44)
|
||||
==2095== by 0x402FC0: words_expansions (words_expansions.c:56)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095== Address 0x56d26fa is 0 bytes after a block of size 10 alloc'd
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x404760: ft_calloc (ft_calloc.c:19)
|
||||
==2095== by 0x403B3C: alloc_words (ft_split_quotes.c:95)
|
||||
==2095== by 0x403852: ft_split_quotes (ft_split_quotes.c:39)
|
||||
==2095== by 0x402FC0: words_expansions (words_expansions.c:56)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
==2095== Invalid read of size 1
|
||||
==2095== at 0x403EE2: ft_strdup_quotes (ft_strdup_quotes.c:36)
|
||||
==2095== by 0x40149A: ft_dup_2d_arr (generic.c:124)
|
||||
==2095== by 0x402FFA: words_expansions (words_expansions.c:61)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095== Address 0x56d26fa is 0 bytes after a block of size 10 alloc'd
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x404760: ft_calloc (ft_calloc.c:19)
|
||||
==2095== by 0x403B3C: alloc_words (ft_split_quotes.c:95)
|
||||
==2095== by 0x403852: ft_split_quotes (ft_split_quotes.c:39)
|
||||
==2095== by 0x402FC0: words_expansions (words_expansions.c:56)
|
||||
==2095== by 0x40275E: parsing (parsing.c:80)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
TOKENS LIST EXPANDED :
|
||||
-----------
|
||||
[6;34.6
|
||||
lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> ^D==2095==
|
||||
==2095== FILE DESCRIPTORS: 3 open at exit.
|
||||
==2095== Open file descriptor 2: /dev/tty1
|
||||
==2095== <inherited from parent>
|
||||
==2095==
|
||||
==2095== Open file descriptor 1: /dev/tty1
|
||||
==2095== <inherited from parent>
|
||||
==2095==
|
||||
==2095== Open file descriptor 0: /dev/tty1
|
||||
==2095== <inherited from parent>
|
||||
==2095==
|
||||
==2095==
|
||||
==2095== HEAP SUMMARY:
|
||||
==2095== in use at exit: 134,842 bytes in 208 blocks
|
||||
==2095== total heap usage: 557 allocs, 349 frees, 165,633 bytes allocated
|
||||
==2095==
|
||||
==2095== 16 bytes in 1 blocks are still reachable in loss record 7 of 46
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x404760: ft_calloc (ft_calloc.c:19)
|
||||
==2095== by 0x40284F: alloc_cmd_array (alloc_cmd_array.c:34)
|
||||
==2095== by 0x4027AB: parsing (parsing.c:87)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
==2095== 32 bytes in 1 blocks are still reachable in loss record 10 of 46
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x404760: ft_calloc (ft_calloc.c:19)
|
||||
==2095== by 0x4028A3: alloc_cmd_array (alloc_cmd_array.c:40)
|
||||
==2095== by 0x4027AB: parsing (parsing.c:87)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
==2095== 224 bytes in 7 blocks are indirectly lost in loss record 19 of 46
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x404760: ft_calloc (ft_calloc.c:19)
|
||||
==2095== by 0x4028A3: alloc_cmd_array (alloc_cmd_array.c:40)
|
||||
==2095== by 0x4027AB: parsing (parsing.c:87)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
==2095== 336 (112 direct, 224 indirect) bytes in 7 blocks are definitely lost in loss record 21 of 46
|
||||
==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==2095== by 0x404760: ft_calloc (ft_calloc.c:19)
|
||||
==2095== by 0x40284F: alloc_cmd_array (alloc_cmd_array.c:34)
|
||||
==2095== by 0x4027AB: parsing (parsing.c:87)
|
||||
==2095== by 0x401A6E: shell_loop (shell_loop.c:40)
|
||||
==2095== by 0x400DA0: main (main.c:25)
|
||||
==2095==
|
||||
==2095== LEAK SUMMARY:
|
||||
==2095== definitely lost: 112 bytes in 7 blocks
|
||||
==2095== indirectly lost: 224 bytes in 7 blocks
|
||||
==2095== possibly lost: 0 bytes in 0 blocks
|
||||
==2095== still reachable: 48 bytes in 2 blocks
|
||||
==2095== suppressed: 134,458 bytes in 192 blocks
|
||||
==2095==
|
||||
==2095== For counts of detected and suppressed errors, rerun with: -v
|
||||
==2095== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
|
||||
➜ minishell git:(master) ✗
|
||||
Reference in New Issue
Block a user