From 8ee24b1bcf097d2d284b2221063c16b7bc6c16c3 Mon Sep 17 00:00:00 2001 From: Maieul BOYER Date: Sat, 3 Aug 2024 16:18:15 +0200 Subject: [PATCH] update --- exec/include/exec/_run_ast.h | 12 +++- exec/src/run_ast.c | 121 +++++++++++++++++++++++++++++------ includes/app/state.h | 18 ++---- sources/ft_exit.c | 6 +- sources/main.c | 89 ++++++++++++-------------- 5 files changed, 161 insertions(+), 85 deletions(-) diff --git a/exec/include/exec/_run_ast.h b/exec/include/exec/_run_ast.h index c27dbefd..867b1125 100644 --- a/exec/include/exec/_run_ast.h +++ b/exec/include/exec/_run_ast.h @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/02 14:41:48 by rparodi #+# #+# */ -/* Updated: 2024/08/02 21:13:33 by maiboyer ### ########.fr */ +/* Updated: 2024/08/03 15:39:10 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -46,6 +46,7 @@ typedef struct s_command_result t_command_result; struct s_command_result { + int exit; t_process process; }; @@ -65,17 +66,23 @@ struct s_word_iterator }; typedef struct s_cmd_pipe t_cmd_pipe; - struct s_cmd_pipe { t_fd *input; bool create_output; }; +typedef struct s_program_result t_program_result; +struct s_program_result +{ + int exit; +}; + t_error run_arithmetic_expansion(t_ast_arithmetic_expansion *arithmetic_expansion, t_state *state, t_i64 *out); t_error run_command(t_ast_command *command, t_state *state, t_cmd_pipe cmd_pipe, t_command_result *out); t_error run_expansion(t_ast_expansion *self, t_state *state, t_expansion_result *out); t_error run_word(t_ast_word *word, t_state *state, t_word_result *out); +t_error run_program(t_ast_program *program, t_state *state, t_program_result *out); t_error run_case_(t_ast_case *case_, t_state *state, void *out); t_error run_case_item(t_ast_case_item *case_item, t_state *state, void *out); @@ -92,7 +99,6 @@ t_error run_heredoc_redirection(t_ast_heredoc_redirection *heredoc_redirection, t_error run_if_(t_ast_if *if_, t_state *state, void *out); t_error run_list(t_ast_list *list, t_state *state, void *out); t_error run_pipeline(t_ast_pipeline *pipeline, t_state *state, void *out); -t_error run_program(t_ast_program *program, t_state *state, void *out); t_error run_raw_string(t_ast_raw_string *raw_string, t_state *state, void *out); t_error run_regex(t_ast_regex *regex, t_state *state, void *out); t_error run_subshell(t_ast_subshell *subshell, t_state *state, void *out); diff --git a/exec/src/run_ast.c b/exec/src/run_ast.c index 4ce61a4d..c9374343 100644 --- a/exec/src/run_ast.c +++ b/exec/src/run_ast.c @@ -6,14 +6,14 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/11 17:22:29 by maiboyer #+# #+# */ -/* Updated: 2024/08/02 23:17:47 by maiboyer ### ########.fr */ +/* Updated: 2024/08/03 16:13:05 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ +#include "app/env.h" #include "app/state.h" #include "ast/ast.h" #include "exec/_run_ast.h" -#include "app/env.h" #include "exec/run.h" #include "me/convert/numbers_to_str.h" #include "me/fs/fs.h" @@ -26,6 +26,7 @@ #include "me/vec/vec_ast.h" #include "me/vec/vec_estr.h" #include "me/vec/vec_str.h" +#include #include @@ -372,15 +373,13 @@ t_error _word_into_str(t_ast_node self, t_state *state, t_vec_str *append) t_str ifs; t_str tmp_str; - if (self == NULL || state == NULL || append == NULL || self->kind == AST_WORD) + if (self == NULL || state == NULL || append == NULL || self->kind != AST_WORD) return (ERROR); if (run_word(&self->data.word, state, &res)) return (ERROR); if (res.kind == AST_WORD_NO_QUOTE) { tmp = string_new(64); - if (!vec_str_pop_front(&splitted, &tmp_str)) - string_push(&tmp, tmp_str), str_free(tmp_str); i = 0; while (i < res.value.len) { @@ -427,6 +426,7 @@ t_error _word_into_str(t_ast_node self, t_state *state, t_vec_str *append) } } } + i++; } vec_str_push(append, tmp.buf); } @@ -477,7 +477,6 @@ t_error run_heredoc_redirection(t_ast_heredoc_redirection *heredoc_redirection, t_error run_if_(t_ast_if *if_, t_state *state, void *out) NOT_DONE; t_error run_list(t_ast_list *list, t_state *state, void *out) NOT_DONE; t_error run_pipeline(t_ast_pipeline *pipeline, t_state *state, void *out) NOT_DONE; -t_error run_program(t_ast_program *program, t_state *state, void *out) NOT_DONE; t_error run_raw_string(t_ast_raw_string *raw_string, t_state *state, void *out) NOT_DONE; t_error run_regex(t_ast_regex *regex, t_state *state, void *out) NOT_DONE; t_error run_subshell(t_ast_subshell *subshell, t_state *state, void *out) NOT_DONE; @@ -485,6 +484,43 @@ t_error run_until(t_ast_until *until, t_state *state, void *out) NOT_DONE; t_error run_variable_assignment(t_ast_variable_assignment *variable_assignment, t_state *state, bool is_temporary, void *out) NOT_DONE; t_error run_while_(t_ast_while *while_, t_state *state, void *out) NOT_DONE; +/// TODO: remove this +void mem_free(void *ptr); + +t_error run_program(t_ast_program *self, t_state *state, t_program_result *out) +{ + t_usize i; + t_ast_node child; + + t_command_result cmd_result; + + if (self == NULL || state == NULL || out == NULL) + return (ERROR); + i = 0; + while (i < self->body.len) + { + child = self->body.buffer[i]; + if (child->kind == AST_COMMAND) + { + if (run_command(&child->data.command, state, (t_cmd_pipe){NULL, false}, &cmd_result)) + return (out->exit = 127, ERROR); + out->exit = cmd_result.exit; + if (cmd_result.process.stdin != NULL) + close_fd(cmd_result.process.stdin); + if (cmd_result.process.stdout != NULL) + close_fd(cmd_result.process.stdout); + if (cmd_result.process.stderr != NULL) + close_fd(cmd_result.process.stderr); + } + else if (child->kind == AST_IF) + ; + else + ; + } + + return (ERROR); +} + // FUNCTIONS // t_error run_command(t_ast_command *command, t_state *state, void *out) {} @@ -517,13 +553,37 @@ t_error _clone_env(const t_kv_env *kv, void *ctx, t_kv_env *out) return (NO_ERROR); } +struct s_ffree_state +{ + t_state *state; + t_cmd_pipe cmd_pipe; +}; + +void _ffree_func(struct s_ffree_state *state) +{ + if (state == NULL) + return; + hmap_env_free(state->state->env); + hmap_env_free(state->state->tmp_var); +} + +bool _is_builtin(t_const_str argv0); +t_error _handle_builtin(t_spawn_info info, t_state *state); + +t_error _handle_builtin(t_spawn_info info, t_state *state) +{ + return (ERROR); +} + + t_error _spawn_cmd_and_run(t_vec_str args, t_vec_ast redirection, t_state *state, t_cmd_pipe cmd_pipe, t_command_result *out) { - t_spawn_info info; - t_usize i; - t_ast_node red; - t_vec_str filename_args; - t_fd *red_fd; + t_spawn_info info; + t_usize i; + t_ast_node red; + t_vec_str filename_args; + t_fd *red_fd; + struct s_ffree_state ffree; info = (t_spawn_info){}; if (cmd_pipe.input) @@ -609,20 +669,44 @@ t_error _spawn_cmd_and_run(t_vec_str args, t_vec_ast redirection, t_state *state i++; } + ffree = (struct s_ffree_state){.state = state, .cmd_pipe = cmd_pipe}; redirection.len = 0; vec_ast_free(redirection); vec_str_free(filename_args); info.arguments = args; - //if (build_envp(state, info.arguments)); if (args.len == 0) - { - vec_str_free(args); + return (vec_str_free(args), ERROR); + if (_is_builtin(args.buffer[0])) + return (_handle_builtin(info, state)); + if (build_envp(state->env, state->tmp_var, &info.environement)) return (ERROR); - } - //if (_is_builtin(args.buffer[0])) - // return (_handle_builtin(args, info)); + info.binary_path = str_clone(info.arguments.buffer[0]); + info.forked_free_args = &ffree; + info.forked_free = (void (*)(void *))_ffree_func; + if (spawn_process(info, &out->process)) + return (ERROR); + int status; + if (waitpid(out->process.pid, &status, 0) == -1) + return (ERROR); + if (WIFEXITED(status)) + out->exit = WEXITSTATUS(status); + if (WIFSIGNALED(status)) + out->exit = WTERMSIG(status); + return (NO_ERROR); +} - return (ERROR); +bool _is_builtin(t_const_str argv0) +{ + t_usize i; + const t_str value[] = {"cd", "echo", "env", "exit", "export", "pwd", "unset", NULL}; + + i = 0; + if (argv0 == NULL) + return (false); + while (value[i] != NULL) + if (str_compare(argv0, value[i++])) + return (true); + return (false); } t_error run_command(t_ast_command *command, t_state *state, t_cmd_pipe cmd_pipe, t_command_result *out) @@ -637,6 +721,7 @@ t_error run_command(t_ast_command *command, t_state *state, t_cmd_pipe cmd_pipe, if (command == NULL || state == NULL || out == NULL) return (ERROR); + hmap_env_clear(state->tmp_var); args = vec_str_new(command->cmd_word.len, str_free); redirection = vec_ast_new(command->suffixes_redirections.len, ast_free); i = 0; diff --git a/includes/app/state.h b/includes/app/state.h index 5a95a90e..79a0d40c 100644 --- a/includes/app/state.h +++ b/includes/app/state.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/02 15:49:56 by maiboyer #+# #+# */ -/* Updated: 2024/08/02 22:26:20 by maiboyer ### ########.fr */ +/* Updated: 2024/08/03 15:51:25 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,27 +17,19 @@ # include "me/hashmap/hashmap_env.h" # include "me/os/os.h" # include "me/types.h" +# include "ast/ast.h" typedef struct s_state t_state; -typedef struct s_parser t_parser; - -struct s_parser -{ - t_first_parser *parser; -}; - struct s_state { - t_str prompt; + t_const_str prompt; t_str str_input; - t_str *strs_input; - t_str *path; - t_parser parser; t_hashmap_env *env; t_hashmap_env *tmp_var; t_node current_node; - t_process ret; + t_first_parser *parser; + t_ast_node ast; }; #endif /* STATE_H */ diff --git a/sources/ft_exit.c b/sources/ft_exit.c index 6c46bef8..9d11bb5c 100644 --- a/sources/ft_exit.c +++ b/sources/ft_exit.c @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/29 11:35:51 by rparodi #+# #+# */ -/* Updated: 2024/08/02 12:09:53 by rparodi ### ########.fr */ +/* Updated: 2024/08/03 15:18:33 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,11 +37,9 @@ void ft_free_utils(t_state *s) { if (s->str_input) mem_free(s->str_input); - if (s->path) - ft_free_strs(s->path); if (s->env) hmap_env_free(s->env); - ts_parser_delete(s->parser.parser); + ts_parser_delete(s->parser); } void ft_exit(t_state *maiboyerlpb, t_u8 exit_status) diff --git a/sources/main.c b/sources/main.c index 2fe93f1d..2351fce6 100644 --- a/sources/main.c +++ b/sources/main.c @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/28 14:40:38 by rparodi #+# #+# */ -/* Updated: 2024/08/02 23:00:50 by maiboyer ### ########.fr */ +/* Updated: 2024/08/03 16:16:12 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include "app/signal_handler.h" #include "app/state.h" #include "ast/ast.h" +#include "exec/_run_ast.h" #include "line/line.h" #include "me/hashmap/hashmap_env.h" #include "me/str/str.h" @@ -25,7 +26,7 @@ #include #include -t_error ast_from_node(t_parse_node node, t_str input, t_ast_node *out); +t_error ast_from_node(t_parse_node node, t_str input, t_ast_node *out); void ast_print_node(t_ast_node self); void ft_exit(t_state *maiboyerlpb, t_u8 exit_status); @@ -34,13 +35,12 @@ void ft_exit(t_state *maiboyerlpb, t_u8 exit_status); // cle avant le = // data apres le = -t_language *tree_sitter_sh(void); +t_language *tree_sitter_sh(void); void ast_free(t_ast_node node); -t_error split_str_first(t_const_str s, char splitter, \ - t_str *before, t_str *after) +t_error split_str_first(t_const_str s, char splitter, t_str *before, t_str *after) { - t_usize i; + t_usize i; if (s == NULL || before == NULL || after == NULL || splitter == '\0') return (ERROR); @@ -56,9 +56,9 @@ t_error split_str_first(t_const_str s, char splitter, \ return (NO_ERROR); } -t_error populate_env(t_hashmap_env *env, t_str envp[]) +t_error populate_env(t_hashmap_env *env, t_str envp[]) { - t_usize i; + t_usize i; t_str temp[2]; i = 0; @@ -77,13 +77,13 @@ t_error populate_env(t_hashmap_env *env, t_str envp[]) return (NO_ERROR); } -void print_node_data(t_node *t, t_usize depth) +void print_node_data(t_node *t, t_usize depth) { - t_usize idx; + t_usize idx; idx = 0; if (t->kind == 7) - return ; + return; printf("\x1b[%im[%-6s](%lu)\x1b[0m", t->field_str == NULL ? 90 : 32, t->field_str == NULL ? "nil" : t->field_str, t->field); while (idx++ < depth + 1) printf("\t"); @@ -93,38 +93,40 @@ void print_node_data(t_node *t, t_usize depth) print_node_data(&t->childs[idx++], depth + 1); } -t_node parse_to_nodes(t_first_parser *parser, t_const_str input) +t_node parse_str(t_state *state) { - t_first_tree *tree; - t_parse_node node; - t_node ret; - t_ast_node out; + t_first_tree *tree; + t_parse_node node; + t_node ret; + t_ast_node out; - tree = ts_parser_parse_string(parser, NULL, input, str_len(input)); + tree = ts_parser_parse_string(state->parser, NULL, state->str_input, str_len(state->str_input)); node = ts_tree_root_node(tree); - if (ast_from_node(node, (t_str)input, &out)) - printf("Error when building node\n"); + printf("BUILDING AST\n"); + if (ast_from_node(node, state->str_input, &out)) + (state->ast = NULL, printf("Error when building node\n")); else - (ast_print_node(out), printf("\n"), ast_free(out)); - ret = build_node(node, input); + state->ast = out; + ret = build_node(node, state->str_input); ts_tree_delete(tree); return (ret); } -t_node parse_str(t_parser *parser, t_const_str input) +void exec_shcat(t_state *state) { - return (parse_to_nodes(parser->parser, input)); + t_program_result prog_res; + + prog_res = (t_program_result){.exit = 0}; + print_node_data(&state->current_node, 0); + free_node(state->current_node); + if (state->ast != NULL && run_program(&state->ast->data.program, state, &prog_res)) + printf("Error when execting the Command \n"); + ast_free(state->ast); } -void exec_shcat(t_state *shcat) +t_error get_user_input(t_state *state) { - print_node_data(&shcat->current_node, 0); - free_node(shcat->current_node); -} - -t_error get_user_input(t_state *state) -{ - t_line_state lstate; + t_line_state lstate; if (line_edit_start(&lstate, get_stdin(), get_stdout(), state->prompt)) return (ERROR); @@ -143,7 +145,7 @@ t_error get_user_input(t_state *state) return (NO_ERROR); } -void ft_take_args(t_state *state) +void ft_take_args(t_state *state) { while (true) { @@ -153,43 +155,36 @@ void ft_take_args(t_state *state) if (state->str_input == NULL) ft_exit(state, 0); line_history_add(state->str_input); - state->current_node = parse_str(&state->parser, state->str_input); + state->current_node = parse_str(state); exec_shcat(state); mem_free(state->str_input); } } -t_parser create_myparser(void) +t_first_parser *create_myparser(void) { - t_language *lang; - t_first_parser *parser; + t_language *lang; + t_first_parser *parser; lang = tree_sitter_sh(); parser = ts_parser_new(); ts_parser_set_language(parser, lang); - return ((t_parser){.parser = parser}); + return (parser); } -void free_myparser(t_parser self) +t_i32 main(t_i32 argc, t_str argv[], t_str envp[]) { - ts_parser_delete(self.parser); -} - -// char truc[] = COLB_YELLOW "42sh" COL_GREEN ">" COL_WHITE "$ " RESET; - -t_i32 main(t_i32 argc, t_str argv[], t_str envp[]) -{ - t_state state; + t_state state; (void)argc; (void)argv; (void)envp; - me_abort("abort"); if (install_signal()) me_abort("Unable to install signals"); state = (t_state){}; state.parser = create_myparser(); state.env = create_env_map(); + state.tmp_var = create_env_map(); if (populate_env(state.env, envp)) me_abort("Unable to build env hashmap"); state.prompt = COLB_YELLOW "42sh" COL_GREEN ">" COL_WHITE "$ " RESET;