aboutsummaryrefslogtreecommitdiff
path: root/src/eval/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval/eval.c')
-rw-r--r--src/eval/eval.c128
1 files changed, 51 insertions, 77 deletions
diff --git a/src/eval/eval.c b/src/eval/eval.c
index 8fca2c1..a5e2c71 100644
--- a/src/eval/eval.c
+++ b/src/eval/eval.c
@@ -3,101 +3,75 @@
** \brief Evaluation of an AST
*/
-#include "minishell.h"
+#include "ms_eval.h"
-
-static bool check_node(t_ast *ast)
+static int eval_line(t_eval_state *state, t_line *line)
{
+ int status;
+ if (line->right == NULL)
+ return (ms_eval(state, line->left));
+ status = ms_eval(state, line->left);
+ if ((line->sep == SEP_AND && status != 0) ||
+ (line->sep == SEP_OR && status == 0))
+ return (status);
+ return (ms_eval(state, line->right));
}
-static int eval_sep(t_ast *ast)
+static char *search_exec_path(t_path path, char *path_var, char *exec_name)
{
- if (ast->children_num != 2)
- return (-1);
- if (ast->tag == TAG_ENDCMD)
- {
- ms_eval(path, env, ast->children[0]);
- return (ms_eval(path, env, ast->children[1]));
- }
- if (ast->tag == TAG_AND)
- {
- status = ms_eval(path, env, ast->children[0]);
- if (status == 0)
- return (ms_eval(path, env, ast->children[1]));
- else
- return (status);
- }
- if (ast->tag == TAG_OR)
+ char *exec_path;
+
+ // try current first
+ if ((exec_path = ft_htget(path, exec_name)) == NULL)
{
- status = ms_eval(path, env, ast->children[0]);
- if (status != 0)
- return (ms_eval(path, env, ast->children[1]));
- else
- return (status);
+ if (ms_path_update(path, path_var) == NULL)
+ return (NULL);
+ if ((exec_path = ft_htget(path, exec_name)) == NULL)
+ return (NULL);
}
- return (-1);
+ return exec_path;
}
-static char **get_args(t_ast *ast)
+static int eval_cmd(t_eval_state *state, t_cmd *cmd)
{
- int i;
- int counter;
- char **argv;
+ int child_pid;
+ char *exec_path;
- if (ast->tag != TAG_CMD)
- return (NULL);
- counter = 0;
- i = -1;
- while (++i < ast->children_num)
- if (ast->children[i]->tag == TAG_ARG)
- counter++;
- if ((argv = (char**)ft_calloc(counter + 1, sizeof(char*))) == NULL)
- return (NULL);
- counter = 0;
- i = -1;
- while (++i < ast->children_num)
+ if ((exec_path = search_exec_path(state->path, ft_htget(state->env, "PATH"), cmd->argv[0])) == NULL)
+ return (-1);
+ if (cmd->in != NULL)
{
- if (ast->children[i]->tag != TAG_ARG)
- continue ;
- if ((argv[counter] = ft_strdup(ast->children[i]->content)) == NULL)
- {
- ft_split_destroy(argv);
- return (NULL);
- }
+ if ((state->in_pipe[PIPE_WRITE] = open(cmd->in, O_RDONLY)) < 0)
+ return (-1);
+ }
+ if (cmd->out != NULL)
+ {
+ if ((state->out_pipe[PIPE_READ] = open(cmd->out,
+ (cmd->is_append ? O_WRONLY : O_APPEND) | O_CREAT)) < 0)
+ return (-1);
}
- return (argv);
-
- /* maybe
- int i;
- char *tmp;
- t_vec *vec;
- if ((vec = ft_vecnew(sizeof(char*))) == NULL)
- return (NULL);
- i = -1;
- while (++i < ast->children_num)
+ if ((child_pid = fork()) == -1)
+ return (-1);
+ if (child_pid == 0)
{
- if (ast->children[i]->tag != TAG_ARG)
- continue ;
- if ((tmp = ft_strdup(ast->children[i]->content)) == NULL
- || ft_vecpush(vec, tmp) == NULL))
- {
- ft_vecdestroy(vec, free);
- return (NULL);
- }
+ if (state->in_pipe[PIPE_READ] != PIPE_CLOSED)
+ dup2(STDIN_FILENO, state->in_pipe[PIPE_READ]);
+ if (state->out_pipe[PIPE_WRITE] != PIPE_CLOSED)
+ dup2(STDOUT_FILENO, state->out_pipe[PIPE_WRITE]);
+ if (execve(exec_path, cmd->argv, NULL /*env_array*/) == -1)
+ exit(EXIT_FAILURE);
}
- return (vec);
- */
+ wait(&child_pid);
+ return (WEXITSTATUS(child_pid));
}
-//reduce?
-int ms_eval(t_path path, t_env env, t_ast *ast)
+int ms_eval(t_eval_state *state, t_ast *ast)
{
- int status;
-
- if (ast->tag == TAG_ENDCMD || ast->tag == TAG_AND
- || ast->tag == TAG_OR || ast->tag == TAG_PIPE)
- return (eval_sep(ast));
-
+ if (ast->tag == TAG_LINE)
+ return eval_line(state, &ast->data.line);
+ if (ast->tag == TAG_CMD)
+ return eval_cmd(state, &ast->data.cmd);
+ return (-1);
}