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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user