minishell/src/parser/cmd_parsing.c

91 lines
2.7 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cmd_parsing.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/31 10:28:28 by jguelen #+# #+# */
/* Updated: 2025/04/16 13:07:33 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "cmd_parsing.h"
#include <fcntl.h>
#include "connec_cmd/connec_reorient_subtree.h"
#include "worddesc/worddesc.h"
#include "wordlist/wordlist.h"
#include <unistd.h>
#include "cmd/cmd_destroy.h"
#include "pipeline/pipeline_parse.h"
#include "cmd/opt_cmds_parse.h"
void parse_error(t_minishell *app, t_worddesc *token)
{
ft_dprintf(STDERR_FILENO, "minishell: syntax error near unexpected "
"token `%s'\n", token->word);
app->last_return_value = 2;
}
/*
** Parse list of commands or pipeline.
*/
t_cmd *minishell_cmds_parse(t_minishell *app, t_wordlist **tokens)
{
t_cmd *subtree;
t_cmd *opt;
t_cmd *list;
t_connector connec;
subtree = minishell_pipeline_parse(app, tokens);
if (!subtree)
return (NULL);
opt = minishell_opt_cmds_parse(app, tokens, &connec);
if (!opt && ft_errno_get() != FT_ESUCCESS)
return (cmd_destroy(subtree), NULL);
if (!opt)
return (subtree);
while (opt)
{
if (connec_reorient_subtree(&list, &subtree, &opt, connec) == NULL)
{
app->last_return_value = 1;
return (ft_perror("minishell_cmds_parse"), NULL);
}
opt = minishell_opt_cmds_parse(app, tokens, &connec);
}
if (ft_errno_get() != FT_ESUCCESS)
return (cmd_destroy(subtree), NULL);
return (list);
}
/*
** TODO check if we need to differentiate the cause of a NULL return.
*/
t_cmd *minishell_parse(t_minishell *app, char *command_line)
{
t_cmd *root_cmd;
t_wordlist *tokens;
ft_errno(FT_ESUCCESS);
if (!command_line)
return (NULL);
tokens = minishell_wordsplit(command_line);
if (!tokens)
return (NULL);
root_cmd = minishell_cmds_parse(app, &tokens);
if (!root_cmd)
{
if (ft_errno_get() != FT_ESUCCESS)
app->last_return_value = 1;
return (wordlist_destroy(tokens), NULL);
}
if (tokens)
{
parse_error(app, tokens->word);
wordlist_destroy(tokens);
cmd_destroy(root_cmd);
return (NULL);
}
return (root_cmd);
}