From 926774846f3f63e7da1290713417478edd31ce70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gu=C3=A9len?= Date: Tue, 8 Apr 2025 19:56:46 +0200 Subject: [PATCH] parse-cmd: Almost done but stopped by the gong --- grammar.md | 2 +- src/destroy_cmds.c | 12 +++- src/minishell.h | 11 ++-- src/parser/cmd_parsing.c | 129 +++++++++++++++++++++++++++++---------- 4 files changed, 115 insertions(+), 39 deletions(-) diff --git a/grammar.md b/grammar.md index 602be99..122ae45 100644 --- a/grammar.md +++ b/grammar.md @@ -41,7 +41,7 @@ OPT_PIPELINE -> | GROUP_OR_SIMPLE OPT_PIPELINE OPT_PIPELINE -> ε GROUP_OR_SIMPLE -> (CMDS) REDIR GROUP_OR_SIMPLE -> SIMPLE -SIMPLE -> REDIR word REDIR SIMPLST +SIMPLE -> REDIR word REDIR SIMPLE_LST SIMPLE_LST -> word REDIR SIMPLE_LST SIMPLE_LST -> ε REDIR -> > word REDIR diff --git a/src/destroy_cmds.c b/src/destroy_cmds.c index 5877b62..f3f255b 100644 --- a/src/destroy_cmds.c +++ b/src/destroy_cmds.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* destroy_cmds.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jguelen +#+ +:+ +#+ */ +/* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/08 14:26:06 by jguelen #+# #+# */ -/* Updated: 2025/04/08 15:32:12 by jguelen ### ########.fr */ +/* Updated: 2025/04/08 19:06:42 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,8 @@ void simple_cmd_destroy(t_simple_cmd *cmd) { + if (!cmd) + return ; wordlist_destroy(cmd->words); redirect_destroy(cmd->redirections); free(cmd); @@ -21,6 +23,8 @@ void simple_cmd_destroy(t_simple_cmd *cmd) void group_cmd_destroy(t_group_cmd *cmd) { + if (!cmd) + return ; t_cmd_destroy(cmd->cmd); redirect_destroy(cmd->redirects); free(cmd); @@ -28,6 +32,8 @@ void group_cmd_destroy(t_group_cmd *cmd) void connec_cmd_destroy(t_connec_cmd *cmd) { + if (!cmd) + return ; t_cmd_destroy(cmd->first); t_cmd_destroy(cmd->second); free(cmd); @@ -58,6 +64,8 @@ void redirect_destroy(t_redirect *redirections) */ void t_cmd_destroy(t_cmd *cmd) { + if (!cmd) + return ; if (cmd->type == FT_CONNECTION) { t_cmd_destroy(cmd->value.connection->first); diff --git a/src/minishell.h b/src/minishell.h index 55c9dcb..9d7641e 100644 --- a/src/minishell.h +++ b/src/minishell.h @@ -6,7 +6,7 @@ /* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/28 14:55:31 by khais #+# #+# */ -/* Updated: 2025/04/08 15:12:29 by jguelen ### ########.fr */ +/* Updated: 2025/04/08 19:46:43 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -120,10 +120,11 @@ typedef struct s_minishell int last_return_value; } t_minishell; -void simple_cmd_destroy(t_simple_cmd *cmd); -void group_cmd_destroy(t_group_cmd *cmd); -void connec_cmd_destroy(t_connec_cmd *cmd); -void redirect_destroy(t_redirect *redirections); +t_redirect *t_redirect_add_back(t_redirect **init, t_redirect *back); +void simple_cmd_destroy(t_simple_cmd *cmd); +void group_cmd_destroy(t_group_cmd *cmd); +void connec_cmd_destroy(t_connec_cmd *cmd); +void redirect_destroy(t_redirect *redirections); /* ** This function recursively destroys the whole command tree. */ diff --git a/src/parser/cmd_parsing.c b/src/parser/cmd_parsing.c index ff6099a..58f72aa 100644 --- a/src/parser/cmd_parsing.c +++ b/src/parser/cmd_parsing.c @@ -6,7 +6,7 @@ /* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/31 10:28:28 by jguelen #+# #+# */ -/* Updated: 2025/04/08 16:02:39 by jguelen ### ########.fr */ +/* Updated: 2025/04/08 19:56:28 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,6 +18,8 @@ /* ** TODO Check if builder grows that destruction is appropriate. ** TODO Remove debugs +** TODO Add a function to write a message and set errno in case of allocation +** error. */ void parse_error(t_minishell *app, t_worddesc *token) { @@ -26,10 +28,20 @@ void parse_error(t_minishell *app, t_worddesc *token) app->last_return_value = 2; } -t_connector which_connector_type(t_worddesc *token) +t_redirect *t_redirect_add_back(t_redirect **init, t_redirect *back) { + t_redirect *tmp; - return ((t_connector)0); + if (!(*init)) + { + *init = back; + return (*init); + } + tmp = *init; + while (tmp->next) + tmp = tmp->next; + tmp->next = back; + return (*init); } t_cmd *minishell_simple_lst_parse(t_minishell *app, t_cmd_builder *builder) @@ -41,49 +53,87 @@ t_cmd *minishell_simple_lst_parse(t_minishell *app, t_cmd_builder *builder) t_redirect *minishell_redir_parse(t_minishell *app, t_cmd_builder *builder) { ft_printf("%s() %s\n", __FUNCTION__, builder->tokens->word->word); - t_cmd *subtree; - -// subtree = minishell_group_or_smp_parse(app, builder); return ((t_redirect *)NULL); } -#define FT_TOKENTYPE_WORD 65 + +/* +** TODO +*/ t_cmd *minishell_simple_parse(t_minishell *app, t_cmd_builder *builder) { ft_printf("%s() %s\n", __FUNCTION__, builder->tokens->word->word); - t_cmd *subtree; - t_worddesc *old_worddesc; + t_cmd *simple; - subtree = minishell_redir_parse(app, builder); - -// a virer -builder->tokens->word->token_type = FT_TOKENTYPE_WORD; - - if (builder->tokens->word->token_type != FT_TOKENTYPE_WORD) - return (parse_error(app, builder->tokens->word), NULL); - - old_worddesc = wordlist_pop(builder->tokens); - - - - subtree = minishell_redir_parse(app, builder); - - return (subtree); + simple = ft_calloc(1, sizeof(t_cmd)); + if (!simple) + { + ft_errno(FT_ENOMEM); + return (NULL); + } + simple->type = FT_SIMPLE; + simple->value.simple = ft_calloc(1, sizeof(t_simple_cmd)); + if (simple->value.simple == NULL) + { + ft_errno(FT_ENOMEM); + return (NULL); + } + //////////////// + return (simple); } t_cmd *minishell_opt_pipeline_parse(t_minishell *app, t_cmd_builder *builder) { - return ((t_cmd *)NULL); + t_cmd *opt; + t_worddesc *token; + + token = builder->tokens->word; + if (token->token_type == PIPE_TOKEN) + { + token = wordlist_pop(builder->tokens); + worddesc_destroy(token); + opt = minishell_group_or_smp_parse(app, builder); + if (!opt) + ft_errno(FT_EERRNO); + return (opt); + } + return (NULL); } +/* +** TODO NORM -> function is too long +*/ t_cmd *minishell_group_or_smp_parse(t_minishell *app, t_cmd_builder *builder) { ft_printf("%s() %s\n", __FUNCTION__, builder->tokens->word->word); t_cmd *subtree; + t_cmd *group; + if (builder->tokens->word->token_type == OPEN_PARENTH_TOKEN) + { + worddesc_destroy(wordlist_pop(builder->tokens)); + subtree = minishell_cmds_parse(app, builder); + if (!subtree + || builder->tokens->word->token_type != CLOSE_PARENTH_TOKEN) + { + ft_errno(FT_EERRNO); + if (builder->tokens->word->token_type != CLOSE_PARENTH_TOKEN) + parse_error(app, builder->tokens->word); + return (t_cmd_destroy(subtree), NULL); + } + worddesc_destroy(wordlist_pop(builder->tokens)); + group = ft_calloc(1, sizeof(t_cmd)); + if (!group) + return (ft_errno(FT_ENOMEM), t_cmd_destroy(subtree), NULL); + group->value.group->cmd = subtree; + group->value.group->redirects = minishell_redir_parse(app, builder); + if (group->value.group->redirects == NULL && ft_errno_get() != FT_ESUCCESS) + return (t_cmd_destroy(group), NULL); + return (group); + } subtree = minishell_simple_parse(app, builder); - - + if (!subtree) + ft_errno(FT_EERRNO); return (subtree); } @@ -92,8 +142,24 @@ t_cmd *minishell_opt_cmds_parse(t_minishell *app, t_cmd_builder *builder, { ft_printf("%s() %s\n", __FUNCTION__, builder->tokens->word->word); + t_worddesc *token; + t_cmd *opt; - return ((t_cmd *)NULL); + token = builder->tokens->word; + if (token->token_type == OR_TOKEN || token->token_type == AND_TOKEN) + { + if (token->token_type == OR_TOKEN) + *connec = FT_OR; + else + *connec = FT_AND; + token = wordlist_pop(builder->tokens); + worddesc_destroy(token); + opt = minishell_pipeline_parse(app, builder); + if (!opt) + ft_errno(FT_EERRNO); + return (opt); + } + return (NULL); } static t_cmd *connec_reorient_subtree(t_cmd **list, t_cmd **subtree, @@ -165,7 +231,6 @@ t_cmd *minishell_cmds_parse(t_minishell *app, t_cmd_builder *builder) t_connector connec; ft_printf("%s() %s\n", __FUNCTION__, builder->tokens->word->word); - subtree = minishell_pipeline_parse(app, builder); if (!subtree) return (NULL); @@ -197,6 +262,7 @@ t_cmd *minishell_parse(t_minishell *app, char *command_line) t_cmd *root_cmd; ft_errno(FT_ESUCCESS); + app->last_return_value = 0; if (!command_line) return (NULL); builder.tokens = minishell_wordsplit(command_line); @@ -205,8 +271,9 @@ t_cmd *minishell_parse(t_minishell *app, char *command_line) root_cmd = minishell_cmds_parse(app, &builder); if (!root_cmd) { - wordlist_destroy(builder.tokens); - return (NULL); + if (ft_errno_get() != FT_ESUCCESS && !app->last_return_value) + app->last_return_value = 1; + return (wordlist_destroy(builder.tokens), NULL); } if (builder.tokens) {