This commit is contained in:
Maieul BOYER 2024-08-03 16:18:15 +02:00
parent 709c124028
commit 8ee24b1bcf
No known key found for this signature in database
5 changed files with 161 additions and 85 deletions

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);

View file

@ -6,14 +6,14 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <sys/wait.h>
#include <stdio.h>
@ -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;

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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)

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <errno.h>
#include <sys/types.h>
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;