save commit
This commit is contained in:
175
minishell-codex/src/parser/parser.c
Normal file
175
minishell-codex/src/parser/parser.c
Normal file
@@ -0,0 +1,175 @@
|
||||
#include "minishell.h"
|
||||
|
||||
static t_command *command_new(void)
|
||||
{
|
||||
t_command *cmd = (t_command *)calloc(1, sizeof(t_command));
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static void command_add_arg(t_command *cmd, const char *text)
|
||||
{
|
||||
char **new_argv;
|
||||
int i;
|
||||
|
||||
if (!cmd || !text)
|
||||
return;
|
||||
i = cmd->argc;
|
||||
new_argv = (char **)calloc((size_t)i + 2, sizeof(char *));
|
||||
if (!new_argv)
|
||||
return;
|
||||
for (int j = 0; j < i; j++)
|
||||
new_argv[j] = cmd->argv[j];
|
||||
new_argv[i] = ms_strdup(text);
|
||||
new_argv[i + 1] = NULL;
|
||||
free(cmd->argv);
|
||||
cmd->argv = new_argv;
|
||||
cmd->argc += 1;
|
||||
}
|
||||
|
||||
static void command_add_redir(t_command *cmd, t_redirtype type, const char *target)
|
||||
{
|
||||
t_redir *r = (t_redir *)calloc(1, sizeof(t_redir));
|
||||
t_redir *cur;
|
||||
if (!r)
|
||||
return;
|
||||
r->type = type;
|
||||
r->target = ms_strdup(target);
|
||||
r->fd = -1;
|
||||
r->next = NULL;
|
||||
if (!cmd->redirs)
|
||||
{
|
||||
cmd->redirs = r;
|
||||
return;
|
||||
}
|
||||
cur = cmd->redirs;
|
||||
while (cur->next)
|
||||
cur = cur->next;
|
||||
cur->next = r;
|
||||
}
|
||||
|
||||
static void free_redirs(t_redir *r)
|
||||
{
|
||||
t_redir *n;
|
||||
while (r)
|
||||
{
|
||||
n = r->next;
|
||||
if (r->fd != -1)
|
||||
close(r->fd);
|
||||
free(r->target);
|
||||
free(r);
|
||||
r = n;
|
||||
}
|
||||
}
|
||||
|
||||
void free_pipeline(t_pipeline *p)
|
||||
{
|
||||
size_t i;
|
||||
if (!p)
|
||||
return;
|
||||
for (i = 0; i < p->count; i++)
|
||||
{
|
||||
if (p->cmds[i])
|
||||
{
|
||||
for (int j = 0; p->cmds[i]->argv && p->cmds[i]->argv[j]; j++)
|
||||
free(p->cmds[i]->argv[j]);
|
||||
free(p->cmds[i]->argv);
|
||||
free(p->cmds[i]->path);
|
||||
free_redirs(p->cmds[i]->redirs);
|
||||
free(p->cmds[i]);
|
||||
}
|
||||
}
|
||||
free(p->cmds);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static int pipeline_add_cmd(t_pipeline *p, t_command *cmd)
|
||||
{
|
||||
t_command **new_cmds;
|
||||
size_t i;
|
||||
|
||||
new_cmds = (t_command **)calloc(p->count + 1, sizeof(t_command *));
|
||||
if (!new_cmds)
|
||||
return 1;
|
||||
for (i = 0; i < p->count; i++)
|
||||
new_cmds[i] = p->cmds[i];
|
||||
new_cmds[p->count] = cmd;
|
||||
free(p->cmds);
|
||||
p->cmds = new_cmds;
|
||||
p->count += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
t_pipeline *parse_tokens(t_token *toks, int *error)
|
||||
{
|
||||
t_pipeline *p;
|
||||
t_command *cmd;
|
||||
t_token *cur;
|
||||
|
||||
*error = 0;
|
||||
p = (t_pipeline *)calloc(1, sizeof(t_pipeline));
|
||||
if (!p)
|
||||
return NULL;
|
||||
cmd = command_new();
|
||||
if (!cmd)
|
||||
{
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
cur = toks;
|
||||
while (cur)
|
||||
{
|
||||
if (cur->type == TOK_PIPE)
|
||||
{
|
||||
if (cmd->argc == 0)
|
||||
{
|
||||
*error = 1;
|
||||
free_pipeline(p);
|
||||
free(cmd);
|
||||
return NULL;
|
||||
}
|
||||
pipeline_add_cmd(p, cmd);
|
||||
cmd = command_new();
|
||||
if (!cmd)
|
||||
{
|
||||
*error = 1;
|
||||
free_pipeline(p);
|
||||
return NULL;
|
||||
}
|
||||
cur = cur->next;
|
||||
continue;
|
||||
}
|
||||
if (cur->type == TOK_REDIR_IN || cur->type == TOK_REDIR_OUT
|
||||
|| cur->type == TOK_REDIR_APPEND || cur->type == TOK_HEREDOC)
|
||||
{
|
||||
if (!cur->next || cur->next->type != TOK_WORD)
|
||||
{
|
||||
*error = 1;
|
||||
free_pipeline(p);
|
||||
free(cmd);
|
||||
return NULL;
|
||||
}
|
||||
if (cur->type == TOK_REDIR_IN)
|
||||
command_add_redir(cmd, REDIR_IN, cur->next->text);
|
||||
else if (cur->type == TOK_REDIR_OUT)
|
||||
command_add_redir(cmd, REDIR_OUT, cur->next->text);
|
||||
else if (cur->type == TOK_REDIR_APPEND)
|
||||
command_add_redir(cmd, REDIR_APPEND, cur->next->text);
|
||||
else if (cur->type == TOK_HEREDOC)
|
||||
command_add_redir(cmd, REDIR_HEREDOC, cur->next->text);
|
||||
cur = cur->next->next;
|
||||
continue;
|
||||
}
|
||||
if (cur->type == TOK_WORD)
|
||||
command_add_arg(cmd, cur->text);
|
||||
cur = cur->next;
|
||||
}
|
||||
if (cmd->argc == 0)
|
||||
{
|
||||
*error = 1;
|
||||
free_pipeline(p);
|
||||
free(cmd);
|
||||
return NULL;
|
||||
}
|
||||
pipeline_add_cmd(p, cmd);
|
||||
return p;
|
||||
}
|
||||
Reference in New Issue
Block a user