From ce0db9550f7c542f44e090a0dd3189238e1f4d71 Mon Sep 17 00:00:00 2001 From: savalet Date: Wed, 21 May 2025 23:12:47 +0200 Subject: [PATCH] Fix multi line --- FIX.md | 2 +- Makefile | 9 - bonus/alias.c | 111 ------------ bonus/alias.h | 21 --- bonus/args.c | 90 ---------- bonus/args.h | 24 --- bonus/ast.h | 147 --------------- bonus/ast/ast.c | 192 -------------------- bonus/ast/ast_cap.c | 75 -------- bonus/ast/ast_utils.c | 65 ------- bonus/ast/conditions.c | 148 ---------------- bonus/ast/tokeniser.c | 175 ------------------ bonus/builtins.h | 56 ------ bonus/builtins/break.c | 33 ---- bonus/builtins/builtin_history.c | 172 ------------------ bonus/builtins/builtins.c | 23 --- bonus/builtins/builtins_alias.c | 124 ------------- bonus/builtins/cd.c | 95 ---------- bonus/builtins/env.c | 55 ------ bonus/builtins/exit.c | 27 --- bonus/builtins/expr/expr.h | 51 ------ bonus/builtins/expr/expr_applicators.c | 138 --------------- bonus/builtins/expr/expr_eval.c | 100 ----------- bonus/builtins/expr/expr_main.c | 37 ---- bonus/builtins/fg.c | 27 --- bonus/builtins/funny_double_dot.c | 17 -- bonus/builtins/get_loop_cmd.c | 101 ----------- bonus/builtins/history.c | 25 --- bonus/builtins/if.c | 165 ----------------- bonus/builtins/local.c | 123 ------------- bonus/builtins/loop.c | 174 ------------------ bonus/builtins/repeat.c | 55 ------ bonus/builtins/set.c | 73 -------- bonus/builtins/unset.c | 26 --- bonus/builtins/where.c | 74 -------- bonus/builtins/which.c | 80 --------- bonus/builtins/yes.c | 70 -------- bonus/common.h | 25 --- bonus/ctx.h | 47 ----- bonus/debug.h | 36 ---- bonus/env.c | 149 ---------------- bonus/env.h | 30 ---- bonus/exec.c | 236 ------------------------- bonus/exec.h | 60 ------- bonus/handle_quotes.c | 107 ----------- bonus/handle_vars.c | 147 --------------- bonus/history.h | 54 ------ bonus/init_history.c | 46 ----- bonus/job.c | 82 --------- bonus/job.h | 19 -- bonus/local.h | 25 --- bonus/loop.h | 23 --- bonus/magic_quotes.c | 121 ------------- bonus/main.c | 57 ------ bonus/parse_history.c | 129 -------------- bonus/path.c | 68 ------- bonus/path.h | 15 -- bonus/readline.c | 119 ------------- bonus/readline.h | 17 -- bonus/redirects.c | 91 ---------- bonus/redirects.h | 18 -- bonus/repl.c | 81 --------- bonus/repl.h | 18 -- bonus/shell.c | 151 ---------------- bonus/shell.h | 19 -- bonus/update_command.c | 53 ------ bonus/utils.h | 20 --- bonus/utils/cat_in_str.c | 43 ----- bonus/utils/free.c | 17 -- bonus/utils/insert_str.c | 29 --- bonus/utils/is_a_token.c | 20 --- bonus/utils/len_array.c | 17 -- bonus/utils/strn_to_ndup.c | 22 --- bonus/visit_condition.c | 77 -------- bonus/visitor.c | 206 --------------------- bonus/visitor.h | 26 --- bonus/vt100_esc_codes.h | 30 ---- src/handle_vars.c | 1 + src/readline.c | 32 +++- src/readline.h | 2 + 80 files changed, 27 insertions(+), 5538 deletions(-) delete mode 100644 bonus/alias.c delete mode 100644 bonus/alias.h delete mode 100644 bonus/args.c delete mode 100644 bonus/args.h delete mode 100644 bonus/ast.h delete mode 100644 bonus/ast/ast.c delete mode 100644 bonus/ast/ast_cap.c delete mode 100644 bonus/ast/ast_utils.c delete mode 100644 bonus/ast/conditions.c delete mode 100644 bonus/ast/tokeniser.c delete mode 100644 bonus/builtins.h delete mode 100644 bonus/builtins/break.c delete mode 100644 bonus/builtins/builtin_history.c delete mode 100644 bonus/builtins/builtins.c delete mode 100644 bonus/builtins/builtins_alias.c delete mode 100644 bonus/builtins/cd.c delete mode 100644 bonus/builtins/env.c delete mode 100644 bonus/builtins/exit.c delete mode 100644 bonus/builtins/expr/expr.h delete mode 100644 bonus/builtins/expr/expr_applicators.c delete mode 100644 bonus/builtins/expr/expr_eval.c delete mode 100644 bonus/builtins/expr/expr_main.c delete mode 100644 bonus/builtins/fg.c delete mode 100644 bonus/builtins/funny_double_dot.c delete mode 100644 bonus/builtins/get_loop_cmd.c delete mode 100644 bonus/builtins/history.c delete mode 100644 bonus/builtins/if.c delete mode 100644 bonus/builtins/local.c delete mode 100644 bonus/builtins/loop.c delete mode 100644 bonus/builtins/repeat.c delete mode 100644 bonus/builtins/set.c delete mode 100644 bonus/builtins/unset.c delete mode 100644 bonus/builtins/where.c delete mode 100644 bonus/builtins/which.c delete mode 100644 bonus/builtins/yes.c delete mode 100644 bonus/common.h delete mode 100644 bonus/ctx.h delete mode 100644 bonus/debug.h delete mode 100644 bonus/env.c delete mode 100644 bonus/env.h delete mode 100644 bonus/exec.c delete mode 100644 bonus/exec.h delete mode 100644 bonus/handle_quotes.c delete mode 100644 bonus/handle_vars.c delete mode 100644 bonus/history.h delete mode 100644 bonus/init_history.c delete mode 100644 bonus/job.c delete mode 100644 bonus/job.h delete mode 100644 bonus/local.h delete mode 100644 bonus/loop.h delete mode 100644 bonus/magic_quotes.c delete mode 100644 bonus/main.c delete mode 100644 bonus/parse_history.c delete mode 100644 bonus/path.c delete mode 100644 bonus/path.h delete mode 100644 bonus/readline.c delete mode 100644 bonus/readline.h delete mode 100644 bonus/redirects.c delete mode 100644 bonus/redirects.h delete mode 100644 bonus/repl.c delete mode 100644 bonus/repl.h delete mode 100644 bonus/shell.c delete mode 100644 bonus/shell.h delete mode 100644 bonus/update_command.c delete mode 100644 bonus/utils.h delete mode 100644 bonus/utils/cat_in_str.c delete mode 100644 bonus/utils/free.c delete mode 100644 bonus/utils/insert_str.c delete mode 100644 bonus/utils/is_a_token.c delete mode 100644 bonus/utils/len_array.c delete mode 100644 bonus/utils/strn_to_ndup.c delete mode 100644 bonus/visit_condition.c delete mode 100644 bonus/visitor.c delete mode 100644 bonus/visitor.h delete mode 100644 bonus/vt100_esc_codes.h diff --git a/FIX.md b/FIX.md index 9055a29..ac8b00b 100644 --- a/FIX.md +++ b/FIX.md @@ -6,6 +6,6 @@ - [x] Alias loop - [ ] All AFL crashes - [ ] Fix CTRL+E and -> -- [ ] Multi line editing +- [x] Multi line editing - [ ] Foreach in if - [x] Output flushing when open an other shell with 42sh diff --git a/Makefile b/Makefile index 9666c33..0a52544 100644 --- a/Makefile +++ b/Makefile @@ -24,14 +24,6 @@ SRC += $(wildcard src/utils/*.c) SRC += $(wildcard src/local/*.c) SRC += $(wildcard src/repl/*.c) -BONUS_SRC := $(wildcard bonus/*.c) -BONUS_SRC += $(wildcard bonus/builtins/*.c) -BONUS_SRC += $(wildcard bonus/builtins/expr/*.c) -BONUS_SRC += $(wildcard bonus/ast/*.c) -BONUS_SRC += $(wildcard bonus/utils/*.c) -BONUS_SRC += $(wildcard bonus/local/*.c) -BONUS_SRC += $(wildcard bonus/repl/*.c) - LIB_SRC := $(wildcard ulib/*.c) LIB_SRC += $(wildcard ulib/write/printf/*.c) LIB_SRC += $(wildcard ulib/math/*.c) @@ -91,7 +83,6 @@ $(eval $(call mk-profile, debug, SRC, -iquote src -D U_DEBUG_MODE \ -fanalyzer -g3, debug)) $(eval $(call mk-profile, test, SRC, -iquote src --coverage, test)) $(eval $(call mk-profile, afl, SRC, -iquote src -D AFL_MODE, afl_runner)) -$(eval $(call mk-profile, bonus, BONUS_SRC, -iquote bonus, 42sh_job)) all: $(NAME_release) diff --git a/bonus/alias.c b/bonus/alias.c deleted file mode 100644 index 786d4e5..0000000 --- a/bonus/alias.c +++ /dev/null @@ -1,111 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** parse_alias -*/ - -#include -#include -#include -#include -#include - -#include "alias.h" -#include "common.h" -#include "history.h" -#include "utils.h" - -static -int skip_blank(const char *buffer, int i) -{ - for (; buffer[i] != 0 && isblank(buffer[i]); i++); - return i; -} - -static -int skip_to_next_token(char *buffer, int i) -{ - for (; buffer[i] != 0 && !is_a_token(buffer, i); i++); - return i; -} - -static -char *find_alias(his_variable_t *variable, alias_t *alias, char *buffer) -{ - char *cmd = malloc(sizeof(char) * (variable->size_variable + 1)); - char *new_cmd = nullptr; - - if (cmd == NULL) - return nullptr; - for (int i = variable->coord_variable; i != - variable->coord_variable + variable->size_variable; i++) - cmd[i - variable->coord_variable] = buffer[i]; - cmd[variable->size_variable] = '\0'; - for (size_t i = 0; i != alias->size; i++){ - if (alias->alias_array[i] == NULL) - return nullptr; - if (strcmp(cmd, alias->alias_array[i]) == 0){ - new_cmd = cat_in_str(variable, buffer, alias->alias_to_replace[i]); - buffer = new_cmd; - } - } - free(cmd); - return new_cmd; -} - -static -char *get_alias(char *buffer, int i, alias_t *alias) -{ - int coord = i; - int size = 0; - his_variable_t variable = {0, 0, 0, nullptr, 0}; - - for (; buffer[i] != 0 && !isblank(buffer[i]) - && !is_a_token(buffer, i); i++) - size++; - variable.coord_variable = coord; - variable.size_variable = size; - buffer = find_alias(&variable, alias, buffer); - return buffer; -} - -static -bool replace_alias(char **buffer, alias_t *alias) -{ - char *tmp_buff = *buffer; - - for (int i = skip_blank(tmp_buff, 0); tmp_buff[i] != 0; i++){ - i = skip_blank(tmp_buff, i); - tmp_buff = get_alias(tmp_buff, i, alias); - if (tmp_buff == NULL) - return false; - i = skip_to_next_token(tmp_buff, i); - } - *buffer = tmp_buff; - return true; -} - -int parse_alias(char **buffer, size_t *buffer_len, alias_t *alias) -{ - bool need_to_replace = true; - - while (need_to_replace) - need_to_replace = replace_alias(buffer, alias); - return RETURN_SUCCESS; -} - -alias_t init_alias(void) -{ - alias_t alias; - - alias.size = 1; - alias.alias_array = malloc(sizeof(char *) * alias.size); - alias.alias_to_replace = malloc(sizeof(char *) * alias.size); - if (!alias.alias_array || !alias.alias_to_replace) - return alias; - alias.alias_array[0] = nullptr; - alias.alias_to_replace[0] = nullptr; - alias.size = 0; - return alias; -} diff --git a/bonus/alias.h b/bonus/alias.h deleted file mode 100644 index bd19a51..0000000 --- a/bonus/alias.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef ALIAS_H - #define ALIAS_H - #include - -typedef struct alias_s { - size_t size; - char **alias_array; - char **alias_to_replace; -} alias_t; - -void free_alias(alias_t *alias); -int parse_alias(char **buffer, size_t *buffer_len, alias_t *alias); -alias_t init_alias(void); -#endif /* ALIAS*/ diff --git a/bonus/args.c b/bonus/args.c deleted file mode 100644 index eed180e..0000000 --- a/bonus/args.c +++ /dev/null @@ -1,90 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** globbing -*/ - -#include -#include -#include -#include -#include -#include - -#include "args.h" -#include "debug.h" -#include "exec.h" -#include "utils.h" - -bool check_glob_result(int val, char *bin_name) -{ - if (val != 0){ - if (val == GLOB_NOMATCH) - dprintf(STDERR_FILENO, "%s: No match.\n", bin_name); - return false; - } - return true; -} - -bool process_globbing(char *pattern, args_t *args, size_t *toks_i) -{ - glob_t globs; - int glob_result; - char *vl; - - U_DEBUG("Globbing pattern [%s]\n", pattern); - glob_result = glob(pattern, GLOB_ERR, nullptr, &globs); - if (!check_glob_result(glob_result, args->args[0])) - return false; - for (size_t i = 0; i < globs.gl_pathc; i++) { - ensure_args_capacity(args); - vl = strdup(globs.gl_pathv[i]); - if (vl == NULL) - return globfree(&globs), false; - args->args[args->sz] = vl; - args->sz++; - } - globfree(&globs); - return true; -} - -static -bool handle_tilde(ef_t *ef, token_t *tok, args_t *args) -{ - char *home; - char *final_str; - size_t tilde_pos = strcspn(tok->str, "~"); - - tok->str[tok->sz] = '\0'; - home = get_env_value(ef->env, "HOME"); - if (home != NULL) - final_str = get_env_value(ef->env, "HOME"); - else - final_str = strdup(""); - args->args[args->sz] = insert_str(tok->str, final_str, tilde_pos); - U_DEBUG("Tilde handling [%s] pos [%lu]\n", final_str, tilde_pos); - if (args->args[args->sz] == NULL) - return false; - args->sz++; - return true; -} - -bool process_args(ast_t *node, args_t *args, size_t *toks_i, ef_t *ef) -{ - token_t tok = node->vector.tokens[*toks_i]; - - if (!ensure_args_capacity(args)) - return false; - if (tok.type == T_STAR) { - tok.str[tok.sz] = '\0'; - return (process_globbing(tok.str, args, toks_i)); - } - if (tok.type == T_TILDE) - return handle_tilde(ef, &tok, args); - handle_var_case(node, ef->exec_ctx, toks_i, args); - if (args->args[args->sz] == NULL) - return false; - args->sz++; - return true; -} diff --git a/bonus/args.h b/bonus/args.h deleted file mode 100644 index 73a8ca6..0000000 --- a/bonus/args.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** globbing -*/ - -#ifndef GLOBBING_H - #define GLOBBING_H - #include - #include - - #include "ast.h" - #include "exec.h" - -typedef struct globs_s { - glob_t globs; - char **found_tab; - char **result_tab; - int val; -}globs_t; - -bool process_args(ast_t *node, args_t *args, size_t *toks_i, ef_t *ef); -#endif /* GLOBBING_H */ diff --git a/bonus/ast.h b/bonus/ast.h deleted file mode 100644 index 0e81557..0000000 --- a/bonus/ast.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef AST_H - #define AST_H - #include - #include - - #include "ctx.h" - - #define DEFAULT_AST_CAP 128 - #define DEFAULT_N_LST_CAP 2 - #define DEFAULT_N_CMD_CAP 2 - #define DEFAULT_N_COND_CAP 2 - #define T_ALL 0xff - -typedef enum size_t { - T_SEMICOLON = 1 << 0, // ; - T_QUOTES = 1 << 1, // " - T_DQUOTES = 1 << 2, // " - T_AND = 1 << 3, // && - T_OR = 1 << 4, // || - T_PIPE = 1 << 5, // | - T_BACKTICK = 1 << 6, // ` - T_LEFT_PARENT = 1 << 7, // ( - T_RIGHT_PARENT = 1 << 8, // ) - T_PREV_CMD = 1 << 9, // !! - T_VAR = 1 << 10, // $ - T_REDIRECT = 1 << 11, // > - T_APPEND = 1 << 12, // >> - T_HEREDOC = 1 << 13, // < - T_IN_REDIRECT = 1 << 14, // < - T_AT = 1 << 15, // < - T_WHILE = 1 << 16, // while - T_STAR = 1 << 18, // * - T_BACKSLASH = 1 << 19, - T_NEWLINE = 1 << 20, // \n - T_TILDE = 1 << 21, // ~ - T_EOF = 1 << 22, // \0 - T_ARG = 1 << 23, - T_INVALID = 1 << 24 -} token_type_t; - -typedef enum { - N_LST, - N_CMD, - N_BIN, - N_LOP, - N_COND -} node_type_t; - -typedef struct { - token_type_t type; - char *str; - size_t sz; -} token_t; - -typedef struct { - token_type_t type; - char const *str; - uint8_t sz; - char const *name; -} tokens_list_t; - -typedef struct ast_s ast_t; - -typedef struct ast_s { - node_type_t type; - union { - struct { - ast_t *left; - ast_t *right; - } binary; - struct { - size_t sz; - size_t cap; - token_t *tokens; - } vector; - struct { - size_t sz; - size_t cap; - ast_t **nodes; - } list; - struct { - size_t sz; - size_t cap; - char **buffers; - ast_t *condition; - } loop; - struct { - ast_t *exp; - size_t sz; - size_t sz2; - size_t cap; - size_t cap2; - ast_t **nodes; - ast_t **nodes2; - } cond; - }; - token_t tok; -} ast_t; - -typedef struct { - size_t i; - size_t sz; - char *str; - size_t cap; - ast_t *ast; - token_t act_tok; - ast_t *first_node; - size_t parsed_tok; -} ast_ctx_t; - - -extern const tokens_list_t TOKENS_LIST[]; - -// Main funcs -ast_t *parse_expression(ast_ctx_t *ctx); -token_t get_next_token(ast_ctx_t *ctx); - -// Utils funcs -int visitor(char *buffer, exec_ctx_t *exec_ctx); -ast_t *create_node(ast_ctx_t *ctx); -bool ensure_node_cap(ast_t *node); -bool ensure_list_cap(ast_t *node); -bool ensure_cond_cap(ast_t *node); -bool ensure_cond_cap2(ast_t *node); -bool parser_eat(ast_ctx_t *ctx, token_type_t expected); -ast_t *parse_loop(ast_ctx_t *ctx); -void free_ast(ast_ctx_t *ctx); -void print_ast(ast_t *ast, ast_ctx_t *ctx, size_t depth); -void skip_semi(ast_ctx_t *ctx); - -// Outside needed parser -ast_t *parse_cmd(ast_ctx_t *ctx); -ast_t *parse_semi(ast_ctx_t *ctx); -ast_t *parse_condition(ast_ctx_t *ctx); -ast_t *parse_and(ast_ctx_t *ctx, ast_t *l_node); -ast_t *parse_or(ast_ctx_t *ctx, ast_t *l_node); -ast_t *parse_if(ast_ctx_t *ctx); -ast_t *parse_condition_and(ast_ctx_t *ctx); -ast_t *parse_pipe(ast_ctx_t *ctx, ast_t *l_node); -#endif /* AST_H */ diff --git a/bonus/ast/ast.c b/bonus/ast/ast.c deleted file mode 100644 index 9abf6d6..0000000 --- a/bonus/ast/ast.c +++ /dev/null @@ -1,192 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include -#include -#include - -#include "ast.h" - -static -bool parse_special_args(ast_ctx_t *ctx) -{ - if (memchr(ctx->act_tok.str, '~', ctx->act_tok.sz) != NULL) - ctx->act_tok.type = T_TILDE; - if (memchr(ctx->act_tok.str, '*', ctx->act_tok.sz) != NULL) - ctx->act_tok.type = T_STAR; - return true; -} - -static -ast_t *parse_arg(ast_ctx_t *ctx, ast_t *node) -{ - ctx->act_tok = get_next_token(ctx); - if (ctx->act_tok.type & (T_SEMICOLON | T_NEWLINE)) - return node; - if (!parse_special_args(ctx)) - return nullptr; - if (ctx->act_tok.type == T_BACKSLASH) { - ctx->act_tok = get_next_token(ctx); - if (ctx->act_tok.type == T_EOF) - return node; - ctx->act_tok.type = T_ARG; - } - if (ctx->act_tok.type & (T_ARG | T_REDIRECT | T_APPEND | - T_IN_REDIRECT | T_HEREDOC | T_VAR | T_STAR | T_TILDE)) { - if (!ensure_node_cap(node)) - return nullptr; - node->vector.tokens[node->vector.sz] = ctx->act_tok; - node->vector.sz++; - return parse_arg(ctx, node); - } - return node; -} - -static -ast_t *fill_cmd_node(ast_ctx_t *ctx) -{ - ast_t *node = create_node(ctx); - - if (node == NULL) - return nullptr; - node->type = N_CMD; - node->vector.cap = DEFAULT_N_CMD_CAP; - node->vector.tokens = - malloc(sizeof *node->vector.tokens * node->vector.cap); - if (node->vector.tokens == NULL) - return nullptr; - if (!parse_special_args(ctx)) - return nullptr; - node->tok = ctx->act_tok; - node->vector.tokens[0] = ctx->act_tok; - node->vector.sz = 1; - return parse_arg(ctx, node); -} - -/* - * Removed this check to do && || if, nothing has changed, - * to be seen in case of trouble, - * putting it back this may solve the problem but will break the && || if - * if (ctx->act_tok.type == T_EOF) - * return ctx->ast; - */ -ast_t *parse_cmd(ast_ctx_t *ctx) -{ - if (ctx->act_tok.type != T_ARG) { - if (ctx->act_tok.type & (T_WHILE)) - return nullptr; - if (!parser_eat(ctx, T_ARG)) - return nullptr; - } - return fill_cmd_node(ctx); -} - -static -bool parse_pipe_childs(ast_ctx_t *ctx, ast_t *node) -{ - if (!ensure_list_cap(node)) - return false; - node->list.nodes[node->list.sz] = parse_cmd(ctx); - if (node->list.nodes[node->list.sz] == NULL) - return false; - node->list.sz++; - return true; -} - -ast_t *parse_pipe(ast_ctx_t *ctx, ast_t *l_node) -{ - ast_t *node = create_node(ctx); - - if (node == NULL) - return nullptr; - node->type = N_LST; - node->tok = ctx->act_tok; - node->list.cap = DEFAULT_N_LST_CAP; - node->list.nodes = (ast_t **)malloc(sizeof(ast_t *) * node->list.cap); - if ((void *)node->list.nodes == NULL) - return nullptr; - node->list.sz = 1; - node->list.nodes[0] = l_node; - if (!parser_eat(ctx, T_ARG)) - return nullptr; - while (ctx->act_tok.type & (T_ARG | T_PIPE)) - if (!parse_pipe_childs(ctx, node)) - return nullptr; - return node; -} - -ast_t *parse_semi(ast_ctx_t *ctx) -{ - ast_t *l_node = parse_condition_and(ctx); - - if (l_node == NULL) - return nullptr; - if (ctx->act_tok.type == T_OR) { - ctx->ast = parse_or(ctx, l_node); - return ctx->ast; - } - return l_node; -} - -static -ast_t *create_semi_node(ast_ctx_t *ctx, ast_t *l_node) -{ - ast_t *node = create_node(ctx); - - if (node == NULL) - return nullptr; - node->type = N_LST; - node->list.cap = DEFAULT_N_LST_CAP; - node->list.nodes = (ast_t **)malloc(sizeof(ast_t *) * node->list.cap); - if ((void *)node->list.nodes == NULL) - return nullptr; - node->list.sz = 1; - node->list.nodes[0] = l_node; - node->tok = ctx->act_tok; - return node; -} - -static -ast_t *fill_semi_node(ast_ctx_t *ctx, ast_t *node) -{ - while (ctx->act_tok.type & (T_SEMICOLON | T_NEWLINE)) { - ctx->act_tok = get_next_token(ctx); - if (ctx->act_tok.type & (T_SEMICOLON | T_NEWLINE)) - continue; - if (!ensure_list_cap(node)) - return nullptr; - node->list.nodes[node->list.sz] = parse_semi(ctx); - if (node->list.nodes[node->list.sz] == NULL) - return nullptr; - node->list.sz++; - } - return node; -} - -ast_t *parse_expression(ast_ctx_t *ctx) -{ - ast_t *l_node; - ast_t *node; - - if (ctx->act_tok.type == T_EOF) - return ctx->ast; - ctx->act_tok = get_next_token(ctx); - skip_semi(ctx); - l_node = parse_semi(ctx); - if (l_node == NULL) - return ctx->ast; - if (ctx->act_tok.type & (T_SEMICOLON | T_NEWLINE)) { - node = create_semi_node(ctx, l_node); - if (node == NULL) - return nullptr; - ctx->ast = fill_semi_node(ctx, node); - } - return parse_expression(ctx); -} diff --git a/bonus/ast/ast_cap.c b/bonus/ast/ast_cap.c deleted file mode 100644 index 871ba36..0000000 --- a/bonus/ast/ast_cap.c +++ /dev/null @@ -1,75 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include - -#include "ast.h" -#include "u_mem.h" - -bool ensure_node_cap(ast_t *node) -{ - token_t *temp; - - if (node->vector.sz + 1 < node->vector.cap) - return true; - temp = u_realloc(node->vector.tokens, - sizeof *node->vector.tokens * node->vector.sz, - sizeof *node->vector.tokens * node->vector.cap << 1); - if (temp == NULL) - return false; - node->vector.cap <<= 1; - node->vector.tokens = temp; - return true; -} - -bool ensure_list_cap(ast_t *node) -{ - ast_t **temp; - - if (node->list.sz + 1 < node->list.cap) - return true; - temp = (ast_t **)u_realloc((void *)node->list.nodes, - sizeof *node->list.nodes * node->list.sz, - sizeof *node->list.nodes * node->list.cap << 1); - if ((void *)temp == NULL) - return false; - node->list.cap <<= 1; - node->list.nodes = temp; - return true; -} - -bool ensure_cond_cap(ast_t *node) -{ - ast_t **temp; - - if (node->cond.sz + 1 < node->cond.cap) - return true; - temp = (ast_t **)u_realloc((void *)node->cond.nodes, - sizeof *node->cond.nodes * node->cond.sz, - sizeof *node->cond.nodes * node->cond.cap << 1); - if ((void *)temp == NULL) - return false; - node->cond.cap <<= 1; - node->cond.nodes = temp; - return true; -} - -bool ensure_cond_cap2(ast_t *node) -{ - ast_t **temp; - - if (node->cond.sz2 + 1 < node->cond.cap2) - return true; - temp = (ast_t **)u_realloc((void *)node->cond.nodes2, - sizeof *node->cond.nodes2 * node->cond.sz2, - sizeof *node->cond.nodes2 * node->cond.cap2 << 1); - if ((void *)temp == NULL) - return false; - node->cond.cap2 <<= 1; - node->cond.nodes2 = temp; - return true; -} diff --git a/bonus/ast/ast_utils.c b/bonus/ast/ast_utils.c deleted file mode 100644 index 35d5f5a..0000000 --- a/bonus/ast/ast_utils.c +++ /dev/null @@ -1,65 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include - -#include "ast.h" -#include "u_mem.h" - -void print_ast(ast_t *ast, ast_ctx_t *ctx, size_t depth) -{ - for (size_t i = 0; i < depth; i++) - fprintf(stderr, " "); - if (depth) - fprintf(stderr, "- "); - fprintf(stderr, "(%.*s)\n", (int)ast->tok.sz, ast->tok.str); - if (ast->type == N_BIN) { - print_ast(ast->binary.left, ctx, depth + 1); - print_ast(ast->binary.right, ctx, depth + 1); - } - if (ast->type == N_CMD) { - for (size_t i = 1; i < ast->vector.sz; i++) - fprintf(stderr, "%*s - (%.*s)\n", (int)depth, "", - (int)ast->vector.tokens[i].sz, ast->vector.tokens[i].str); - } - if (ast->type == N_LST) { - for (size_t i = 0; i < ast->list.sz; i++) - print_ast(ast->list.nodes[i], ctx, depth + 1); - } -} - -ast_t *create_node(ast_ctx_t *ctx) -{ - ast_t *new_ast; - - if (ctx->ast == NULL) - return NULL; - if (ctx->sz + 1 == ctx->cap) { - new_ast = u_realloc(ctx->ast, sizeof *ctx->ast * ctx->sz, - sizeof *ctx->ast * (ctx->cap << 1)); - if (new_ast == NULL) - return NULL; - ctx->ast = new_ast; - ctx->cap <<= 1; - } - ctx->ast[ctx->sz] = (ast_t){ 0 }; - ctx->sz++; - return ctx->ast + ctx->sz - 1; -} - -void free_ast(ast_ctx_t *ctx) -{ - for (size_t i = 0; i < ctx->sz; i++) { - if (ctx->first_node[i].type == N_LST) - free((void *)ctx->first_node[i].list.nodes); - if (ctx->first_node[i].type == N_CMD) - free(ctx->first_node[i].vector.tokens); - } - free(ctx->first_node); -} diff --git a/bonus/ast/conditions.c b/bonus/ast/conditions.c deleted file mode 100644 index 27df329..0000000 --- a/bonus/ast/conditions.c +++ /dev/null @@ -1,148 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include - -#include "ast.h" -#include "common.h" -#include "u_str.h" - -ast_t *parse_and(ast_ctx_t *ctx, ast_t *l_node) -{ - ast_t *node = create_node(ctx); - - if (node == NULL || l_node == NULL) - return nullptr; - node->tok = ctx->act_tok; - node->type = N_BIN; - node->binary.left = l_node; - node->binary.right = parse_condition_and(ctx); - if (node->binary.right == NULL) - return nullptr; - return node; -} - -ast_t *parse_or(ast_ctx_t *ctx, ast_t *l_node) -{ - ast_t *node = create_node(ctx); - - if (node == NULL || l_node == NULL) - return nullptr; - node->tok = ctx->act_tok; - node->type = N_BIN; - node->binary.left = l_node; - node->binary.right = parse_semi(ctx); - if (node->binary.right == NULL) - return nullptr; - return node; -} - -ast_t *parse_condition_and(ast_ctx_t *ctx) -{ - ast_t *l_node = parse_condition(ctx); - - if (l_node == NULL) - return nullptr; - if (ctx->act_tok.type == T_AND) { - ctx->ast = parse_and(ctx, l_node); - return ctx->ast; - } - return l_node; -} - -ast_t *parse_condition(ast_ctx_t *ctx) -{ - ast_t *l_node = parse_cmd(ctx); - - if (l_node == NULL) - return nullptr; - switch (ctx->act_tok.type) { - case T_PIPE: - ctx->ast = parse_pipe(ctx, l_node); - break; - default: - return l_node; - } - return ctx->ast; -} - -static -bool fill_else_node(ast_ctx_t *ctx, ast_t *node, buff_t *buff) -{ - ctx->str = buff->str; - node->cond.nodes2[node->cond.sz2] = parse_semi(ctx); - if (node->cond.nodes2[node->cond.sz2] == NULL) - return false; - node->cond.sz2++; - return ensure_cond_cap2(node); -} - -static -bool fill_if_node(ast_ctx_t *ctx, ast_t *node, bool fill_else, buff_t *buff) -{ - if (strncmp(buff->str, "else", 4) == 0) - return true; - if (fill_else) - return fill_else_node(ctx, node, buff); - ctx->str = buff->str; - node->cond.nodes[node->cond.sz] = parse_semi(ctx); - if (node->cond.nodes[node->cond.sz] == NULL) - return false; - node->cond.sz++; - return ensure_cond_cap(node); -} - -static -ast_t *fill_if(ast_ctx_t *ctx, ast_t *node) -{ - buff_t buff = { .str = nullptr, 0 }; - char *old_buff = ctx->str; - bool fill_else = false; - - while (true) { - if (isatty(STDIN_FILENO)) - WRITE_CONST(STDOUT_FILENO, IF_PROMPT); - if (getline(&buff.str, &buff.sz, stdin) < 0) - return nullptr; - buff.str[strlen(buff.str) - 1] = '\0'; - if (strncmp(buff.str, "endif", 5) == 0) - break; - if (strncmp(buff.str, "else", 4) == 0) - fill_else = true; - if (!fill_if_node(ctx, node, fill_else, &buff)) - return nullptr; - buff = (buff_t){ .str = nullptr, 0 }; - } - ctx->str = old_buff; - return node; -} - -ast_t *parse_if(ast_ctx_t *ctx) -{ - ast_t *node = create_node(ctx); - - if (node == NULL) - return nullptr; - node->tok = ctx->act_tok; - node->type = N_COND; - node->cond.cap = DEFAULT_N_COND_CAP; - node->cond.cap2 = DEFAULT_N_COND_CAP; - memset(&node->cond.sz, 0, sizeof node->cond.sz * 2); - node->cond.nodes = - (ast_t **)malloc(sizeof *node->cond.nodes * node->cond.cap); - node->cond.nodes2 = - (ast_t **)malloc(sizeof *node->cond.nodes * node->cond.cap2); - if ((void *)node->cond.nodes == NULL || (void *)node->cond.nodes2 == NULL) - return nullptr; - node->cond.exp = parse_semi(ctx); - if (node->cond.exp == NULL) - return WRITE_CONST(STDERR_FILENO, "if: Too few arguments.\n"), NULL; - return fill_if(ctx, node); -} diff --git a/bonus/ast/tokeniser.c b/bonus/ast/tokeniser.c deleted file mode 100644 index e83b247..0000000 --- a/bonus/ast/tokeniser.c +++ /dev/null @@ -1,175 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include - -#include "ast.h" -#include "debug.h" -#include "u_str.h" - -const tokens_list_t TOKENS_LIST[] = { - { T_SEMICOLON, ";", 1, "T_SEMICOLON" }, - { T_QUOTES, "\'", 1, "T_QUOTES"}, - { T_DQUOTES, "\"", 1, "T_DQUOTES"}, - { T_AND, "&&", 2, "T_AND" }, - { T_OR, "||", 2, "T_OR" }, - { T_PIPE, "|", 1, "T_PIPE" }, - { T_BACKTICK, "`", 1, "T_BACKTICK" }, - { T_LEFT_PARENT, "(", 1, "T_LEFT_PARENT" }, - { T_RIGHT_PARENT, ")", 1, "T_RIGHT_PARENT" }, - { T_PREV_CMD, "!!", 2, "T_PREV_CMD" }, - { T_APPEND, ">>", 2, "T_APPEND" }, - { T_REDIRECT, ">", 1, "T_REDIRECT" }, - { T_HEREDOC, "<<", 2, "T_HEREDOC" }, - { T_IN_REDIRECT, "<", 1, "T_IN_REDIRECT" }, - { T_BACKSLASH, "\\", 1, "T_BACKSLASH" }, - { T_NEWLINE, "\n", 1, "T_NEWLINE"}, - { T_EOF, "\0", 1, "T_EOF" } -}; - -const size_t TOKENS_LIST_SZ = sizeof TOKENS_LIST / sizeof *TOKENS_LIST; - -const tokens_list_t CLOSABLE[] = { - { T_RIGHT_PARENT, ")", 1, "T_RIGHT_PARENT" }, - { T_LEFT_PARENT, "(", 1, "T_LEFT_PARENT" }, - { T_BACKTICK, "`", 1, "T_BACKTICK" }, - { T_QUOTES, "\'", 1, "T_QUOTES"}, - { T_DQUOTES, "\"", 1, "T_DQUOTES"} -}; - -const size_t CLOSABLE_LIST_SZ = sizeof CLOSABLE / sizeof *CLOSABLE; - -void skip_semi(ast_ctx_t *ctx) -{ - while (ctx->act_tok.type == T_SEMICOLON) - ctx->act_tok = get_next_token(ctx); -} - -bool parser_eat(ast_ctx_t *ctx, token_type_t expected) -{ - token_type_t prev_tok_type = ctx->act_tok.type; - - ctx->act_tok = get_next_token(ctx); - if (!(ctx->act_tok.type & expected)) { - if (prev_tok_type == T_PIPE) - WRITE_CONST(STDERR_FILENO, "Invalid null command.\n"); - else - dprintf(STDERR_FILENO, "Parse error near \"%.*s\"\n", - (int)ctx->ast->tok.sz, ctx->ast->tok.str); - return false; - } - return true; -} - -static -bool check_closable(token_t actual_token) -{ - if (actual_token.type == 0) - return false; - for (size_t i = 0; i < CLOSABLE_LIST_SZ; i++) { - if (actual_token.type == CLOSABLE[i].type) - return true; - } - return false; -} - -static -token_t handle_token_type(ast_ctx_t *ctx) -{ - for (size_t i = 0; i < TOKENS_LIST_SZ; i++) { - if (u_strncmp(ctx->str, TOKENS_LIST[i].str, TOKENS_LIST[i].sz) == 0) { - U_DEBUG("Token %-14s [%.*s]\n", TOKENS_LIST[i].name, - (int)TOKENS_LIST[i].sz, ctx->str); - ctx->str += TOKENS_LIST[i].sz; - return (token_t){ TOKENS_LIST[i].type, - ctx->str - TOKENS_LIST[i].sz, TOKENS_LIST[i].sz }; - } - } - return (token_t){0, NULL, 0}; -} - -static -bool compare_to_close(ast_ctx_t *ctx, token_t acutal_tok) -{ - token_type_t token = 0; - - if (!*ctx->str && !(*ctx->str + 1)) - return false; - for (size_t i = 0; i < TOKENS_LIST_SZ; i++) { - if (u_strncmp(ctx->str, TOKENS_LIST[i].str, - TOKENS_LIST[i].sz) == 0) { - token = TOKENS_LIST[i].type; - break; - } - } - if (u_strncmp(ctx->str, acutal_tok.str, acutal_tok.sz) == 0){ - if (acutal_tok.type & (T_QUOTES | T_DQUOTES) - && !isblank(*(ctx->str + 1)) && token == 0) - return false; - return true; - } - return false; -} - -static -void get_arg_token(ast_ctx_t *ctx, int *found_token, token_t acutal_tok) -{ - if (check_closable(acutal_tok)){ - ctx->str++; - if (compare_to_close(ctx, acutal_tok)){ - *found_token = 1; - ctx->str++; - } - return; - } - for (size_t i = 0; i < TOKENS_LIST_SZ; i++) { - if (u_strncmp(ctx->str, TOKENS_LIST[i].str, - TOKENS_LIST[i].sz) == 0) { - *found_token = 1; - break; - } - } - if (!*found_token) - ctx->str++; -} - -void format_for_closable(ast_ctx_t *ctx, token_t *actual_token) -{ - if (actual_token->type == T_RIGHT_PARENT) - *actual_token = handle_token_type(ctx); - if (actual_token->type == T_LEFT_PARENT && - ctx->parsed_tok == 1) - *actual_token = (token_t){ 0, NULL, 0 }; - if (actual_token->type == T_LEFT_PARENT - && ctx->parsed_tok != 1) - *actual_token = (token_t){ T_RIGHT_PARENT, ")", 1}; - if (check_closable(*actual_token)) - ctx->str -= actual_token->sz; -} - -token_t get_next_token(ast_ctx_t *ctx) -{ - char *start; - int found_token = 0; - token_t actual_token; - - ctx->parsed_tok++; - while (*ctx->str != '\0' && isblank(*ctx->str)) - ctx->str++; - actual_token = handle_token_type(ctx); - format_for_closable(ctx, &actual_token); - if (actual_token.type != 0 && !check_closable(actual_token)) - return actual_token; - start = ctx->str; - while ((*ctx->str && !found_token && (!isblank(*ctx->str) || - check_closable(actual_token)))) - get_arg_token(ctx, &found_token, actual_token); - U_DEBUG("Token T_ARG [%.*s]\n", (int)(ctx->str - start), start); - return (token_t){ .type = T_ARG, .str = start, - .sz = (size_t)(ctx->str - start) }; -} diff --git a/bonus/builtins.h b/bonus/builtins.h deleted file mode 100644 index 213638e..0000000 --- a/bonus/builtins.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - - -#ifndef BUILTINS_H - #define BUILTINS_H - #include "exec.h" - #include "u_str.h" - -typedef struct { - char **cmds; - size_t size; - size_t cap; -} cmd_block_t; - -typedef struct { - buff_t *buff; - bool in_else; - ef_t *ef; -} if_ctx_t; - -typedef struct { - char const *name; - int (*ptr)(ef_t *ef, char **args); -} builtins_funcs_t; - -extern const builtins_funcs_t BUILTINS[]; -extern const size_t BUILTINS_SZ; - -int builtins_exit(ef_t *ef, char **args); -int builtins_env(ef_t *ef, char **args); -int builtins_setenv(ef_t *ef, char **args); -int builtins_unsetenv(ef_t *ef, char **args); -int builtins_cd(ef_t *ef, char **args); -int builtins_builtins(ef_t *ef, char **args); -int builtins_funny_double_dot(ef_t *ef, char **args); -int builtins_history(ef_t *ef, char **args); -int builtins_alias(ef_t *ef, char **args); -int builtins_display_alias(alias_t *alias); -int builtins_repeat(ef_t *ef, char **args); -int builtins_yes(ef_t *ef, char **args); -int builtins_foreach(ef_t *ef, char **args); -int builtins_while(ef_t *ef, char **args); -int builtins_set(ef_t *ef, char **args); -int builtins_unset(ef_t *ef, char **args); -int builtins_where(ef_t *ef, char **args); -int builtins_which(ef_t *ef, char **args); -int builtins_break(ef_t *ef, char **args); -int builtins_expr(ef_t *ef, char **args); -int builtins_if(ef_t *ef, char **args); -int builtins_fg(ef_t *ef, char **args); -#endif /* BUILTIND_H */ diff --git a/bonus/builtins/break.c b/bonus/builtins/break.c deleted file mode 100644 index a105c68..0000000 --- a/bonus/builtins/break.c +++ /dev/null @@ -1,33 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** break -*/ -#include -#include -#include - -#include "ast.h" -#include "builtins.h" -#include "common.h" -#include "exec.h" -#include "u_str.h" - -bool checking_error(ef_t *ef, char **args) -{ - if (args[1]) - return (WRITE_CONST(STDERR_FILENO, "break: Too many arguments.\n"), - RETURN_FAILURE); - if (!ef->exec_ctx->local->in_a_loop) - return (WRITE_CONST(STDERR_FILENO, "break: Not in while/foreach.\n"), - RETURN_FAILURE); - return RETURN_SUCCESS; -} - -int builtins_break(ef_t *ef, char **args) -{ - if (ef->exec_ctx->local->in_a_loop) - exit(checking_error(ef, args)); - return checking_error(ef, args); -} diff --git a/bonus/builtins/builtin_history.c b/bonus/builtins/builtin_history.c deleted file mode 100644 index 8389433..0000000 --- a/bonus/builtins/builtin_history.c +++ /dev/null @@ -1,172 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** history_42sh -** File description: -** builtin_history -*/ - -#include -#include -#include -#include -#include - -#include "history.h" -#include "u_str.h" -#include "utils.h" - -/* -**Il faut deux \0 parce que dans le gettokeniser -** y un truc qui regarde -**après le premier \0 -*/ - -/* -**cat in str prend un -** his_variable_t en -** parametre pour -** connaitre la coord -** d' ou commencer a concaténer -** mais aussi le nombre de charactère a retiré -** il vas free le buffer -*/ - -static char *concat_cmd_arg(char *dest, char *src) -{ - int l; - int i; - char *r_value = nullptr; - - if (!src) { - r_value = u_strdup(dest); - return r_value; - } - l = strlen(dest); - i = strlen(src); - r_value = malloc(sizeof(char)* (i + l + 2)); - if (r_value != NULL) { - strcpy(r_value, dest); - r_value[l] = ' '; - r_value[l +1] = '\0'; - strcat(r_value, src); - } - return r_value; -} - -char *his_last_command(char *line, - his_variable_t *his_variable, his_command_t *his_command) -{ - char *new_line = nullptr; - char *new_str = nullptr; - - if (his_command->sz == 0){ - fprintf(stderr, "%d: Event not found.\n", his_command->sz); - return nullptr; - } - new_line = concat_cmd_arg(his_command[his_command->sz - 1].command, - his_command[his_command->sz - 1].arg); - new_str = cat_in_str(his_variable, line, new_line); - printf("%s\n", new_line); - return new_str; -} - -char *his_last_same_command(char *line, - his_variable_t *his_variable, his_command_t *his_command) -{ - char *new_line = &line[his_variable->coord_variable + 1]; - char *new_str = nullptr; - - for (int i = his_command->sz - 1; i > 0; i--) { - if (his_command[i].command == NULL) { - fprintf(stderr, "%s: Event not found.\n", new_line); - return new_str; - } - if (strncmp(his_command[i].command, new_line, strlen(new_line)) == 0) { - new_line = concat_cmd_arg(his_command[i].command, - his_command[i].arg); - new_str = cat_in_str(his_variable, line, new_line); - free(line); - return new_str; - } - } - fprintf(stderr, "%s: Event not found.\n", new_line); - return new_str; -} - -char *his_id_command(char *line, - his_variable_t *his_variable, his_command_t *his_command) -{ - int id = -1 + atoi(&line[his_variable->coord_variable + 1]); - char *new_line; - char *new_str = nullptr; - - if (id < 0 || id > 100 || his_command[id].command == NULL){ - fprintf(stderr, "%d: Event not found.\n", id + 1); - return new_str; - } - new_line = concat_cmd_arg(his_command[id].command, his_command[id].arg); - new_str = cat_in_str(his_variable, line, new_line); - printf("%s\n", new_str); - free(new_line); - free(line); - return new_str; -} - -static char *get_last_word(char *str) -{ - char *last_word = nullptr; - int last_space = 0; - int x = 0; - - if (!str) - return nullptr; - while (str[x] != '\0') { - if (isblank(str[x])) - last_space = x + 1; - x++; - } - last_word = malloc(sizeof(char) * ((x - last_space) + 1)); - if (last_word != NULL) { - last_word = strncpy(last_word, &str[last_space], x - last_space); - last_word[x - last_space] = '\0'; - } - return last_word; -} - -char *his_last_word(char *line, - his_variable_t *his_variable, his_command_t *his_command) -{ - char *new_line = nullptr; - char *new_str = nullptr; - - if (his_command[his_command->sz - 1].arg == NULL){ - new_line = get_last_word(his_command[his_command->sz - 1].command); - } else - new_line = get_last_word(his_command[his_command->sz - 1].arg); - if (!new_line) - return nullptr; - new_str = cat_in_str(his_variable, line, new_line); - printf("%s\n", new_str); - free(new_line); - free(line); - return new_str; -} - -char *his_last_arg(char *line, - his_variable_t *his_variable, his_command_t *his_command) -{ - int id = his_command->sz - 1; - char *new_line = nullptr; - char *new_str = nullptr; - - if (!his_command[id].arg) - new_line = " "; - else - new_line = u_strdup(his_command[id].arg); - new_str = cat_in_str(his_variable, line, new_line); - printf("%s\n", new_line); - if (his_command[id].arg) - free(new_line); - free(line); - return new_str; -} diff --git a/bonus/builtins/builtins.c b/bonus/builtins/builtins.c deleted file mode 100644 index d5614d2..0000000 --- a/bonus/builtins/builtins.c +++ /dev/null @@ -1,23 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include - -#include "builtins.h" -#include "common.h" -#include "exec.h" -#include "u_str.h" - -int builtins_builtins(ef_t *ef, char **args[[gnu::unused]]) -{ - for (size_t i = 0; i < BUILTINS_SZ; i++) { - write(ef->out_fd, BUILTINS[i].name, u_strlen(BUILTINS[i].name)); - WRITE_CONST(ef->out_fd, "\n"); - } - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/builtins_alias.c b/bonus/builtins/builtins_alias.c deleted file mode 100644 index 65d8906..0000000 --- a/bonus/builtins/builtins_alias.c +++ /dev/null @@ -1,124 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** history -*/ - -#include -#include -#include - -#include "alias.h" -#include "common.h" -#include "exec.h" -#include "utils.h" - -void free_alias(alias_t *alias) -{ - for (size_t i = 0; i != alias->size; i++){ - free(alias->alias_array[i]); - free(alias->alias_to_replace[i]); - } - free(alias->alias_array); - free(alias->alias_to_replace); - return; -} - -int builtins_display_alias(alias_t *alias) -{ - for (size_t i = 0; i != alias->size; i++){ - printf("|| Alias: %s || ", alias->alias_array[i]); - printf("Command: %s ||\n", alias->alias_to_replace[i]); - } - return RETURN_SUCCESS; -} - -static -int size_str_in_narray(int i, char **array) -{ - int size_str = 0; - - for (int cp_i = i; array[cp_i] != NULL; cp_i++) - size_str += strlen(array[cp_i]) + 1; - return size_str; -} - -static -char *array_nto_strdup(char **array, int i) -{ - char *new_str = NULL; - int size_str = 0; - int letter = 0; - - if (len_array(array) < i) - return NULL; - size_str = size_str_in_narray(i, array); - new_str = malloc(size_str + 1); - if (new_str == NULL) - return NULL; - for (int j = i; array[j] != NULL; j++){ - for (int k = 0; array[j][k] != '\0'; k++){ - new_str[letter] = array[j][k]; - letter++; - } - new_str[letter] = ' '; - letter++; - } - new_str[letter] = '\0'; - return new_str; -} - -static -int add_alias_array(alias_t *alias, char **args) -{ - char **new_alias_array = - realloc(alias->alias_array, sizeof(char *) * alias->size); - char **new_replace = - realloc(alias->alias_to_replace, sizeof(char *) * alias->size); - - if (!new_alias_array || !new_replace){ - free(new_alias_array); - free(new_replace); - return RETURN_FAILURE; - } - alias->alias_array = new_alias_array; - alias->alias_to_replace = new_replace; - alias->alias_array[alias->size - 1] = strdup(args[1]); - alias->alias_to_replace[alias->size - 1] = array_nto_strdup(args, 2); - return RETURN_SUCCESS; -} - -int add_alias(alias_t *alias, char **args) -{ - int replace = -1; - - for (size_t i = 0; i != alias->size - 1; i++) - if (!strcmp(args[1], alias->alias_array[i])) - replace = (int)(i); - if (replace == -1) - return add_alias_array(alias, args); - alias->size--; - free(alias->alias_to_replace[replace]); - alias->alias_to_replace[replace] = array_nto_strdup(args, 2); - return RETURN_SUCCESS; -} - -int builtins_alias(ef_t *ef, char **args) -{ - alias_t *alias = ef->exec_ctx->alias; - char *first_arg = args[1]; - - if (first_arg != NULL && strcmp(args[1], "-h") == 0){ - fprintf(stderr, "alias [cpy] [command]\n"); - return RETURN_FAILURE; - } - if (len_array(args) < 3){ - builtins_display_alias(alias); - return RETURN_SUCCESS; - } - alias->size++; - if (add_alias(alias, args) == RETURN_FAILURE) - return RETURN_FAILURE; - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/cd.c b/bonus/builtins/cd.c deleted file mode 100644 index dd330e6..0000000 --- a/bonus/builtins/cd.c +++ /dev/null @@ -1,95 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include - -#include "common.h" -#include "env.h" -#include "exec.h" -#include "u_mem.h" -#include "u_str.h" - - -static -void cd_print_error(void) -{ - switch (errno) { - case EACCES: - WRITE_CONST(STDERR_FILENO, ": Permission denied.\n"); - break; - case ENOENT: - WRITE_CONST(STDERR_FILENO, ": No such file or directory.\n"); - break; - case ENOTDIR: - WRITE_CONST(STDERR_FILENO, ": Not a directory.\n"); - break; - default: - WRITE_CONST(STDERR_FILENO, ": Unknown error.\n"); - } -} - -static -char *get_current_dir(void) -{ - size_t size = 64; - char *buffer = malloc(size); - char *new_buffer; - size_t max_it = 100; - - if (!buffer) - return nullptr; - while (getcwd(buffer, size) == NULL && max_it > 0) { - if (errno != ERANGE) - return (free(buffer), NULL); - size <<= 1; - new_buffer = u_realloc(buffer, u_strlen(buffer) + 1, size); - if (!new_buffer) - return (free(buffer), NULL); - buffer = new_buffer; - max_it--; - } - return buffer; -} - -static -int builtins_cd_chdir(ef_t *ef, char **args, char *path) -{ - char *act_pwd; - - if (ef->exec_ctx->history->last_chdir != NULL && args[1] != NULL - && u_strcmp(args[1], "-") == 0) - path = ef->exec_ctx->history->last_chdir; - act_pwd = get_current_dir(); - if (chdir(path) < 0) { - write(STDERR_FILENO, path, u_strlen(path)); - cd_print_error(); - return RETURN_FAILURE; - } - free(ef->exec_ctx->history->last_chdir); - ef->exec_ctx->history->last_chdir = act_pwd; - set_env(ef->env, "PWD", path); - return RETURN_SUCCESS; -} - -int builtins_cd(ef_t *ef, char **args) -{ - char *path = args[1]; - - if (!(ef->out_fd == STDOUT_FILENO || ef->p_i == ef->p_sz - 1)) - return RETURN_SUCCESS; - if (path == NULL) - path = get_env_value(ef->env, "HOME"); - if (path == NULL) - return RETURN_FAILURE; - if (args[1] != NULL && args[2] != NULL) { - WRITE_CONST(STDERR_FILENO, "cd: Too many arguments.\n"); - return RETURN_FAILURE; - } - return builtins_cd_chdir(ef, args, path); -} diff --git a/bonus/builtins/env.c b/bonus/builtins/env.c deleted file mode 100644 index 3665aab..0000000 --- a/bonus/builtins/env.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include - -#include "common.h" -#include "env.h" -#include "exec.h" -#include "u_str.h" - -int builtins_env(ef_t *ef, char **args __attribute__((unused))) -{ - for (size_t i = 0; i < ef->env->sz; i++) { - if (ef->env->env[i] == NULL) - continue; - write(ef->out_fd, ef->env->env[i], u_strlen(ef->env->env[i])); - WRITE_CONST(ef->out_fd, "\n"); - } - return RETURN_SUCCESS; -} - -int builtins_setenv(ef_t *ef, char **args) -{ - if (args[1] == NULL) - return builtins_env(ef, args); - if (args[2] != NULL && args[3] != NULL) { - WRITE_CONST(STDERR_FILENO, "setenv: Too many arguments.\n"); - return RETURN_FAILURE; - } - if (!isalpha(args[1][0])) - return (WRITE_CONST(STDERR_FILENO, "setenv: Variable name must begin" - " with a letter.\n"), RETURN_FAILURE); - if (!u_str_is_only_alnum(args[1])) - return (WRITE_CONST(STDERR_FILENO, "setenv: Variable name must contain" - " alphanumeric characters.\n"), RETURN_FAILURE); - if (!set_env(ef->env, args[1], args[2])) - return RETURN_FAILURE; - return RETURN_SUCCESS; -} - -int builtins_unsetenv(ef_t *ef, char **args) -{ - if (args[1] == NULL) - return (WRITE_CONST(STDERR_FILENO, "unsetenv: Too few arguments.\n"), - RETURN_FAILURE); - for (int i = 0; args[i]; i++) - unset_env(ef->env, args[1]); - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/exit.c b/bonus/builtins/exit.c deleted file mode 100644 index 6324891..0000000 --- a/bonus/builtins/exit.c +++ /dev/null @@ -1,27 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include - -#include "common.h" -#include "env.h" -#include "exec.h" - -int builtins_exit(ef_t *ef, char **args[[gnu::unused]]) -{ - if (ef->flags & F_PIPE && - !(ef->out_fd == STDOUT_FILENO || ef->p_i == ef->p_sz - 1)) - return RETURN_SUCCESS; - if (!(ef->flags & F_EXIT)) { - ef->flags |= F_EXIT; - return RETURN_SUCCESS; - } - free_env(ef->env); - free(ef->buffer); - exit(ef->exec_ctx->history->last_exit_code); -} diff --git a/bonus/builtins/expr/expr.h b/bonus/builtins/expr/expr.h deleted file mode 100644 index 1cfd16b..0000000 --- a/bonus/builtins/expr/expr.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef EXPR_H - #define EXPR_H - - #include - #include - - #define FIRST_TOKEN_BATCH_SIZE 64 - #define IS_CHAR(s, c) ((s)[0] == (c) && (s)[1] == '\0') - - #define COUNT_OF(arr) (sizeof (arr) / (sizeof *(arr))) - -typedef unsigned char uchar_t; - -typedef enum { - E_VAL_INT = 'd', - E_VAL_STR = 's', - E_VAL_ERR = 'e', -} expr_val_type_t; - -typedef struct { - char *p; - union { - long val; - char const *str; - }; - char type; -} expr_val_t; - -typedef struct { - char name[4]; - unsigned int prec; - expr_val_t (*apply)(expr_val_t *, expr_val_t *); -} expr_op_precedence_t; - -typedef struct { - char **args; -} expr_state_t; - -expr_val_t expr_run(expr_state_t *state, uchar_t depth, int prec); - -extern const expr_op_precedence_t OPERATOR_PRECEDENCE[]; -extern const size_t OPERATOR_PRECEDENCE_COUNT; - -#endif diff --git a/bonus/builtins/expr/expr_applicators.c b/bonus/builtins/expr/expr_applicators.c deleted file mode 100644 index 1137d77..0000000 --- a/bonus/builtins/expr/expr_applicators.c +++ /dev/null @@ -1,138 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include - -#include "expr.h" - -static -expr_val_t apply_add(expr_val_t *left, expr_val_t *right) -{ - expr_val_t res; - - if (left->type != E_VAL_INT || right->type != E_VAL_INT) { - res.str = "non-integer argument"; - res.type = E_VAL_ERR; - } else { - res.val = left->val + right->val; - res.type = E_VAL_INT; - } - return res; -} - -static -expr_val_t apply_sub(expr_val_t *left, expr_val_t *right) -{ - expr_val_t res; - - if (left->type != E_VAL_INT || right->type != E_VAL_INT) { - res.str = "non-integer argument"; - res.type = E_VAL_ERR; - } else { - res.val = left->val - right->val; - res.type = E_VAL_INT; - } - return res; -} - -static -expr_val_t apply_mul(expr_val_t *left, expr_val_t *right) -{ - expr_val_t res; - - if (left->type != E_VAL_INT || right->type != E_VAL_INT) { - res.str = "non-integer argument"; - res.type = E_VAL_ERR; - } else { - res.val = left->val * right->val; - res.type = E_VAL_INT; - } - return res; -} - -static -expr_val_t apply_div(expr_val_t *left, expr_val_t *right) -{ - expr_val_t res = { .type = E_VAL_ERR }; - - if (left->type != E_VAL_INT || right->type != E_VAL_INT) { - res.str = "non-integer argument"; - res.type = E_VAL_ERR; - return res; - } - if (right->val == 0) { - res.str = "division by zero"; - res.type = E_VAL_ERR; - return res; - } - res.val = left->val / right->val; - res.type = E_VAL_INT; - return res; -} - -static -expr_val_t apply_lt(expr_val_t *left, expr_val_t *right) -{ - expr_val_t res = { .type = E_VAL_INT }; - - if (left->type == E_VAL_INT && right->type == E_VAL_INT) - res.val = left->val < right->val; - else - res.val = strcmp(left->p, right->p) < 0; - return res; -} - -static -expr_val_t apply_gt(expr_val_t *left, expr_val_t *right) -{ - expr_val_t res = { .type = E_VAL_INT }; - - if (left->type == E_VAL_INT && right->type == E_VAL_INT) - res.val = left->val > right->val; - else - res.val = strcmp(left->p, right->p) > 0; - return res; -} - -static -expr_val_t apply_eq(expr_val_t *left, expr_val_t *right) -{ - expr_val_t res = { .type = E_VAL_INT }; - - if (left->type == E_VAL_INT && right->type == E_VAL_INT) - res.val = left->val == right->val; - else - res.val = !strcmp(left->p, right->p); - return res; -} - -static -expr_val_t apply_neq(expr_val_t *left, expr_val_t *right) -{ - expr_val_t res = { .type = E_VAL_INT }; - - if (left->type == E_VAL_INT && right->type == E_VAL_INT) - res.val = left->val != right->val; - else - res.val = strcmp(left->p, right->p); - return res; -} - -const expr_op_precedence_t OPERATOR_PRECEDENCE[] = { - { .name = "+", .prec = 2, apply_add }, - { .name = "-", .prec = 2, apply_sub }, - { .name = "*", .prec = 3, apply_mul }, - { .name = "/", .prec = 3, apply_div }, - { .name = "<", .prec = 1, apply_lt }, - { .name = ">", .prec = 1, apply_gt }, - { .name = "=", .prec = 1, apply_eq }, - { .name = "==", .prec = 1, apply_eq }, - { .name = "!=", .prec = 1, apply_neq }, -}; - -const size_t OPERATOR_PRECEDENCE_COUNT = COUNT_OF(OPERATOR_PRECEDENCE); diff --git a/bonus/builtins/expr/expr_eval.c b/bonus/builtins/expr/expr_eval.c deleted file mode 100644 index cd9076f..0000000 --- a/bonus/builtins/expr/expr_eval.c +++ /dev/null @@ -1,100 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include -#include - -#include "expr.h" - -static -const expr_op_precedence_t *op_precedence(char *op) -{ - for (size_t i = 0; i < OPERATOR_PRECEDENCE_COUNT; i++) - if (!strcmp(op, OPERATOR_PRECEDENCE[i].name)) - return OPERATOR_PRECEDENCE + i; - return NULL; -} - -static -expr_val_t expr_parse_paren(expr_state_t *state, uchar_t depth) -{ - expr_val_t out; - - state->args++; - out = expr_run(state, depth, 0); - if (out.type == E_VAL_ERR) - return out; - if (*state->args == NULL || !IS_CHAR(*state->args, ')')) { - out.str = "syntax error: missing ')'"; - out.type = E_VAL_ERR; - return out; - } - state->args++; - return out; -} - -static -void expr_solve_precedence( - expr_val_t *out, - expr_state_t *state, uchar_t depth, unsigned int prec) -{ - const expr_op_precedence_t *op_prec; - expr_val_t tmp; - - while (*state->args != NULL && !IS_CHAR(*state->args, ')')) { - op_prec = op_precedence(*state->args); - if (op_prec == NULL) { - out->type = E_VAL_ERR; - out->str = "syntax error: unexpected argument"; - break; - } - if (op_prec->prec == 0 || op_prec->prec <= prec) - return; - state->args++; - tmp = expr_run(state, depth, op_prec->prec); - if (tmp.type == E_VAL_ERR) { - *out = tmp; - break; - } - *out = op_prec->apply(out, &tmp); - } -} - -expr_val_t expr_parse_val(expr_state_t *state) -{ - expr_val_t out; - char *chk; - - out.val = strtol(*state->args, &chk, 10); - out.p = *state->args; - if (chk != *state->args && *chk == '\0') - out.type = E_VAL_INT; - else - out.type = E_VAL_STR; - state->args++; - return out; -} - -expr_val_t expr_run(expr_state_t *state, uchar_t depth, int prec) -{ - expr_val_t out = { - .type = E_VAL_ERR, - .str = "syntax error: missing argument" - }; - - if (*state->args == NULL) - return out; - if (IS_CHAR(*state->args, '(')) - out = expr_parse_paren(state, depth + 1); - else - out = expr_parse_val(state); - expr_solve_precedence(&out, state, depth, prec); - return out; -} diff --git a/bonus/builtins/expr/expr_main.c b/bonus/builtins/expr/expr_main.c deleted file mode 100644 index 785905b..0000000 --- a/bonus/builtins/expr/expr_main.c +++ /dev/null @@ -1,37 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include - -#include "common.h" -#include "exec.h" -#include "expr.h" - -int builtins_expr(ef_t *ef[[gnu::unused]], char **args) -{ - int argc = 0; - expr_state_t state; - expr_val_t ret; - - for (; args[argc] != nullptr; argc++); - if (argc < 2) - return fprintf(stderr, "%s: missing operand\nTry 'expr --help' for" - " more information.", args[0]), -1; - state = (expr_state_t){ .args = &args[1] }; - ret = expr_run(&state, 0, 0); - if (ret.type == E_VAL_ERR) - return printf("%s: %s\n", args[0], ret.str), -1; - if (ret.type == E_VAL_INT && (strcmp("if", args[0]) == 0 || - strcmp("while", args[0]) == 0)) - return ret.val; - if (ret.type == E_VAL_INT) - printf("%ld\n", ret.val); - if (ret.type == E_VAL_STR) - printf("%s\n", ret.p); - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/fg.c b/bonus/builtins/fg.c deleted file mode 100644 index abb9121..0000000 --- a/bonus/builtins/fg.c +++ /dev/null @@ -1,27 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include - -#include "common.h" -#include "exec.h" -#include "job.h" - -int builtins_fg(ef_t *ef, char **args) -{ - int status; - - if (!set_child_fg(ef->exec_ctx, ef->exec_ctx->jobs.sz - 1)) - return RETURN_FAILURE; - waitpid(ef->exec_ctx->jobs.jobs[ef->exec_ctx->jobs.sz - 1].pgid, &status, - WUNTRACED); - if (WIFEXITED(status)) - ef->exec_ctx->history->last_exit_code = - ef->exec_ctx->history->last_exit_code ?: WEXITSTATUS(status); - tcsetpgrp(ef->exec_ctx->read_fd, ef->exec_ctx->jobs.jobs[0].pgid); - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/funny_double_dot.c b/bonus/builtins/funny_double_dot.c deleted file mode 100644 index 5e9d4a6..0000000 --- a/bonus/builtins/funny_double_dot.c +++ /dev/null @@ -1,17 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include - -#include "common.h" -#include "exec.h" - -int builtins_funny_double_dot(ef_t *c[[gnu::unused]], - char **args[[gnu::unused]]) -{ - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/get_loop_cmd.c b/bonus/builtins/get_loop_cmd.c deleted file mode 100644 index 88d16d3..0000000 --- a/bonus/builtins/get_loop_cmd.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** get_loop_cmd -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "loop.h" -#include "repl.h" -#include "u_mem.h" -#include "u_str.h" - -static -usr_cmd_t *buffers_realloc(usr_cmd_t *usr) -{ - char **new_buffers = (char **)u_realloc((void *)usr->cmds, sizeof - *usr->cmds * usr->sz, sizeof - *usr->cmds * (usr->cap << 1)); - - if ((void *)new_buffers == NULL) - return nullptr; - usr->cmds = new_buffers; - usr->cap <<= 1; - return usr; -} - -static -usr_cmd_t *increase_buffers(usr_cmd_t *usr, size_t *buffer_len) -{ - usr->cmds[usr->sz] = nullptr; - getline(&(usr->cmds[usr->sz]), buffer_len, stdin); - *buffer_len = u_strlen(usr->cmds[usr->sz]); - usr->cmds[usr->sz][*buffer_len - 1] = '\0'; - usr->sz++; - return usr; -} - -static -usr_cmd_t *handle_end(usr_cmd_t *us, char const *prompt) -{ - us->sz--; - if (!us->cmds[us->sz] || strcmp("end", us->cmds[us->sz]) != 0){ - printf("%s: end not found.\n", prompt); - free_array(us->cmds); - us->cmds = nullptr; - exit(RETURN_FAILURE); - return nullptr; - } - free(us->cmds[us->sz]); - us->cmds[us->sz] = nullptr; - return us; -} - -static -usr_cmd_t *get_first_cmd(exec_ctx_t *exec_ctx, usr_cmd_t *usr, - char const *prompt, size_t *bf_len) -{ - if (isatty(exec_ctx->read_fd)) - printf("%s? ", prompt); - usr->cmds[usr->sz] = nullptr; - getline(&(usr->cmds[usr->sz]), bf_len, stdin); - *bf_len = u_strlen(usr->cmds[usr->sz]); - usr->cmds[usr->sz][*bf_len - 1] = '\0'; - usr->sz += 1; - return usr; -} - -usr_cmd_t *get_usr_loop_cmd(exec_ctx_t *exec_ctx, usr_cmd_t *usr_cmd, - char const *prompt) -{ - size_t buffer_len; - - if (usr_cmd == NULL) - return nullptr; - usr_cmd->cmds = (char **)malloc(sizeof(char *) * usr_cmd->cap); - if ((void *)usr_cmd->cmds == NULL) - return nullptr; - usr_cmd = get_first_cmd(exec_ctx, usr_cmd, prompt, &buffer_len); - while (strcmp("end", usr_cmd->cmds[usr_cmd->sz - 1]) != 0){ - if (isatty(exec_ctx->read_fd)) - printf("%s? ", prompt); - if (usr_cmd->sz >= usr_cmd->cap) - usr_cmd = buffers_realloc(usr_cmd); - if (usr_cmd == NULL) - return nullptr; - increase_buffers(usr_cmd, &buffer_len); - } - usr_cmd = handle_end(usr_cmd, prompt); - return usr_cmd; -} diff --git a/bonus/builtins/history.c b/bonus/builtins/history.c deleted file mode 100644 index a070bc6..0000000 --- a/bonus/builtins/history.c +++ /dev/null @@ -1,25 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** history -*/ - -#include - -#include "common.h" -#include "exec.h" - -int builtins_history(ef_t *ef, char **args __attribute__((unused))) -{ - his_command_t *cmd_history = ef->exec_ctx->history_command; - - for (int i = 0; i < cmd_history->sz; i++){ - if (cmd_history[i].arg) { - printf("%d %s %s\n", i + 1, cmd_history[i].command, - cmd_history[i].arg); - } else - printf("%d %s\n", i + 1, cmd_history[i].command); - } - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/if.c b/bonus/builtins/if.c deleted file mode 100644 index aa115ea..0000000 --- a/bonus/builtins/if.c +++ /dev/null @@ -1,165 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include - -#include "builtins.h" -#include "common.h" -#include "debug.h" -#include "exec.h" -#include "repl.h" -#include "u_str.h" - -static -int get_argc(char **args) -{ - int i = 0; - - for (; args[i] != nullptr; i++); - return i; -} - -static -bool ensure_cmds_cap(char ***cmd, size_t sz, size_t *cap) -{ - char **tmp; - - if (sz + 1 < *cap) - return true; - tmp = (char **)realloc(*cmd, sizeof(char *) * (*cap << 1)); - if (!tmp) - return false; - *cap <<= 1; - *cmd = tmp; - return true; -} - -static -bool init_block(cmd_block_t *blk) -{ - blk->size = 0; - blk->cap = DEFAULT_N_CMD_CAP; - blk->cmds = (char **)malloc(sizeof(char *) * blk->cap); - return blk->cmds != NULL; -} - -static -void free_block(cmd_block_t *blk) -{ - for (size_t i = 0; i < blk->size; i++) - free(blk->cmds[i]); - free((void *)blk->cmds); -} - -static -bool append_block(cmd_block_t *blk, const char *line) -{ - if (!ensure_cmds_cap(&blk->cmds, blk->size, &blk->cap)) - return false; - blk->cmds[blk->size] = strdup(line); - blk->size++; - return true; -} - -static -bool handle_if_buff(if_ctx_t *ctx, cmd_block_t *then_blk, - cmd_block_t *else_blk, bool *in_else) -{ - if (strcmp(ctx->buff->str, "else") == 0) { - *in_else = true; - return true; - } - if (strcmp(ctx->buff->str, "endif") == 0) - return false; - if (!*in_else) { - if (!append_block(then_blk, ctx->buff->str)) - return false; - } else - if (!append_block(else_blk, ctx->buff->str)) - return false; - return true; -} - -static -bool read_if_blocks(ef_t *ef, if_ctx_t *ctx, cmd_block_t *then_blk, - cmd_block_t *else_blk) -{ - bool in_else = false; - - while (true) { - if (isatty(ef->exec_ctx->read_fd)) - WRITE_CONST(ctx->ef->out_fd, IF_PROMPT); - if (getline(&ctx->buff->str, &ctx->buff->sz, stdin) == -1) - return false; - ctx->buff->str[strcspn(ctx->buff->str, "\n")] = '\0'; - if (strcmp(ctx->buff->str, "else") == 0) { - in_else = true; - continue; - } - if (strcmp(ctx->buff->str, "endif") == 0) - break; - if (!handle_if_buff(ctx, then_blk, else_blk, &in_else)) - return false; - } - return true; -} - -static -void exec_block(cmd_block_t *blk, ef_t *ef) -{ - for (size_t i = 0; i < blk->size; i++) - visitor(blk->cmds[i], ef->exec_ctx); -} - -static -bool handle_if_logic(ef_t *ef, bool cond, char *last) -{ - if_ctx_t ctx = {.buff = &(buff_t){ .str = nullptr, .sz = 0 }, .ef = ef}; - cmd_block_t then_blk; - cmd_block_t else_blk; - - if (strcmp("then", last) != 0) - return cond ? visitor(last, ef->exec_ctx), true : true; - if (!init_block(&then_blk) || !init_block(&else_blk)) - return false; - if (!read_if_blocks(ef, &ctx, &then_blk, &else_blk)) - return false; - if (cond) - exec_block(&then_blk, ef); - else - exec_block(&else_blk, ef); - free_block(&then_blk); - free_block(&else_blk); - free(ctx.buff->str); - return true; -} - -int builtins_if(ef_t *ef, char **args) -{ - int result; - char *last; - - if (args[1] == NULL) - return WRITE_CONST(STDERR_FILENO, "if: Too few arguments.\n"), - RETURN_FAILURE; - if (args[2] == NULL) - return WRITE_CONST(STDERR_FILENO, "if: Empty if.\n"), RETURN_FAILURE; - last = strdup(args[get_argc(args) - 1]); - if (!last) - return RETURN_FAILURE; - args[get_argc(args) - 1] = nullptr; - result = builtins_expr(ef, args); - U_DEBUG("If expr result [%d]\n", result); - if (result == -1) - return free(last), RETURN_FAILURE; - if (!handle_if_logic(ef, result != 0, last)) - return free(last), RETURN_FAILURE; - return free(last), RETURN_SUCCESS; -} diff --git a/bonus/builtins/local.c b/bonus/builtins/local.c deleted file mode 100644 index d6086ab..0000000 --- a/bonus/builtins/local.c +++ /dev/null @@ -1,123 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** local -*/ - -#include -#include -#include -#include -#include - -#include "ctx.h" -#include "common.h" -#include "u_mem.h" -#include "u_str.h" - -bool check_local_var(char *var, char *func_name) -{ - if (!isalpha(var[0])) - return (fprintf(stderr, "%s: Variable name must begin" - " with a letter.\n", func_name), RETURN_FAILURE); - if (!u_str_is_only_alnum(var)) - return (fprintf(stderr, "%s: Variable name must contain" - " alphanumeric characters.\n", func_name), RETURN_FAILURE); - return RETURN_SUCCESS; -} - -char *get_local_value(local_t *local, char const *key) -{ - int key_len = u_strlen(key); - - for (size_t i = 0; i < local->sz; i++) { - if (local->local_var[i] == nullptr) - continue; - if (u_strcspn(local->local_var[i], '\t') != key_len) - continue; - if (u_strcmp(local->local_var[i], key) == 0) - return local->local_var[i] + key_len + 1; - } - return nullptr; -} - -local_t create_local(void) -{ - local_t local = {.sz = 0, .cap = 2}; - - local.local_var = (char **)malloc(sizeof(char *) * local.cap); - if (local.local_var == nullptr) - return (local_t){.sz = 0, .cap = 2, .local_var = nullptr}; - local.local_var[local.sz] = nullptr; - local.sz++; - return local; -} - -static -bool ensure_local_capacity(local_t *local) -{ - char **new_ptr = nullptr; - - if (local->sz < local->cap) - return true; - new_ptr = (char **)u_realloc((void *)local->local_var, - sizeof *local->local_var * local->sz, - sizeof *local->local_var * local->cap << 1); - if (!new_ptr) - return false; - local->cap <<= 1; - local->local_var = new_ptr; - return true; -} - -bool set_local(local_t *local, char *var, char *value) -{ - char *new_loc = nullptr; - size_t key_len = u_strlen(var); - size_t value_len = u_strlen(value); - - if (get_local_value(local, var) != nullptr) - unset_local(local, var); - local->sz++; - if (!ensure_local_capacity(local)) - return false; - new_loc = malloc(sizeof(char) * (key_len + value_len + 2)); - if (new_loc == nullptr) - return false; - u_bzero(new_loc, key_len + value_len + 2); - u_strcpy(new_loc, var); - new_loc[key_len] = '\t'; - if (value_len > 0) - u_strcpy(new_loc + key_len + 1, value); - local->local_var[local->sz - 1] = new_loc; - local->local_var[local->sz] = nullptr; - return true; -} - -static -void unset_local_move(local_t *local, size_t i) -{ - while (local->local_var[i]) { - local->local_var[i] = local->local_var[i + 1]; - i++; - } -} - -bool unset_local(local_t *local, char *var) -{ - int key_len = u_strlen(var); - - for (size_t i = 0; i < local->sz; i++) { - if (local->local_var[i] == nullptr) - continue; - if (u_strcspn(local->local_var[i], '\t') != key_len) - continue; - if (u_strcmp(local->local_var[i], var) == 0) { - unset_local_move(local, i); - local->sz--; - return true; - } - } - return false; -} diff --git a/bonus/builtins/loop.c b/bonus/builtins/loop.c deleted file mode 100644 index 7925195..0000000 --- a/bonus/builtins/loop.c +++ /dev/null @@ -1,174 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** foreach -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ast.h" -#include "builtins.h" -#include "common.h" -#include "debug.h" -#include "exec.h" -#include "local.h" -#include "loop.h" -#include "u_str.h" - -void exit_child(int sig[[gnu::unused]]) -{ - _exit(sig); -} - -static -bool checking_for_error(char **args) -{ - if (my_array_len(args) < 3) - return (WRITE_CONST(STDERR_FILENO, "foreach: Too few arguments.\n"), - true); - if (check_local_var(args[1], args[0])) - return true; - return false; -} - -static -bool checking_while_error(char **args) -{ - if (my_array_len(args) < 2) - return (WRITE_CONST(STDERR_FILENO, "while: Too few arguments.\n"), - true); - if (my_array_len(args) > 2) - return (WRITE_CONST(STDERR_FILENO, "while: Expression Syntax.\n"), - true); - return false; -} - -static -int do_a_lap(ef_t *ef, char **args) -{ - int status = 0; - - for (int i = 0; args[i]; i++) - status = visitor(args[i], ef->exec_ctx); - return status; -} - -static -int foreach_loop(ef_t *ef, char **args, usr_cmd_t *usr_cmds) -{ - int status = 0; - char **save_cmds = arraydup(usr_cmds->cmds); - - if ((void *)save_cmds == nullptr) - exit(84); - for (int i = 2; args[i]; i++){ - if (!set_local(ef->exec_ctx->local, args[1], args[i])) - exit(84); - status = do_a_lap(ef, usr_cmds->cmds); - free_array(usr_cmds->cmds); - usr_cmds->cmds = arraydup(save_cmds); - } - free_array(save_cmds); - return status; -} - -static -int while_loop(ef_t *ef, usr_cmd_t *usr_cmds, char **args) -{ - int status = 0; - char **save_cmds = arraydup(usr_cmds->cmds); - int expr_result; - - if ((void *)save_cmds == nullptr) - exit(84); - expr_result = builtins_expr(ef, args); - if (expr_result == -1) - return RETURN_FAILURE; - while (expr_result != 0) { - U_DEBUG("While expr result [%d]\n", expr_result); - status = do_a_lap(ef, usr_cmds->cmds); - free_array(usr_cmds->cmds); - usr_cmds->cmds = arraydup(save_cmds); - expr_result = builtins_expr(ef, args); - if (expr_result == -1) - return RETURN_FAILURE; - } - free_array(save_cmds); - return status; -} - -static -int choose_loop(ef_t *ef, char **args, usr_cmd_t *usr_cmd, char const *prompt) -{ - if (strcmp(prompt, "foreach") == 0) - return foreach_loop(ef, args, usr_cmd); - return while_loop(ef, usr_cmd, args); -} - -static -void launch_loop(ef_t *ef, char **args, char const *prompt) -{ - int status = RETURN_FAILURE; - usr_cmd_t *usr_cmds = malloc(sizeof(usr_cmd_t)); - - ef->exec_ctx->local->in_a_loop = true; - if (usr_cmds == nullptr) - exit(84); - usr_cmds->cap = 2; - usr_cmds->sz = 0; - signal(SIGINT, exit_child); - signal(EOF, exit_child); - usr_cmds = get_usr_loop_cmd(ef->exec_ctx, usr_cmds, prompt); - if (usr_cmds == nullptr) - exit(84); - status = choose_loop(ef, args, usr_cmds, prompt); - free_array(usr_cmds->cmds); - free(usr_cmds); - exit(status); -} - -int builtins_foreach(ef_t *ef, char **args) -{ - int status = 0; - pid_t pid; - - if (checking_for_error(args)) - return RETURN_FAILURE; - pid = fork(); - if (pid == 0) - launch_loop(ef, args, "foreach"); - else - wait(&status); - if (WIFEXITED(status)) - ef->history->last_exit_code = - ef->history->last_exit_code ?: WEXITSTATUS(status); - return status; -} - -int builtins_while(ef_t *ef, char **args) -{ - int status = 0; - pid_t pid; - - if (checking_while_error(args)) - return RETURN_FAILURE; - pid = fork(); - if (pid == 0) - launch_loop(ef, args, "while"); - else - wait(&status); - if (WIFEXITED(status)) - ef->history->last_exit_code = - ef->history->last_exit_code ?: WEXITSTATUS(status); - return status; -} diff --git a/bonus/builtins/repeat.c b/bonus/builtins/repeat.c deleted file mode 100644 index 2affa22..0000000 --- a/bonus/builtins/repeat.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** repeat -*/ - -#include -#include -#include -#include -#include - -#include "builtins.h" -#include "common.h" -#include "exec.h" -#include "u_str.h" - -static -bool checking_error(char **args, long *nb_loop) -{ - char *end; - - if (my_array_len(args) < 3) - return (WRITE_CONST(STDERR_FILENO, "repeat: Too few arguments.\n"), - true); - *nb_loop = strtol(args[1], &end, 10); - if (end[0] != '\0'){ - return (WRITE_CONST(STDERR_FILENO, "repeat: Badly formed number.\n"), - true); - } - return false; -} - -int builtins_repeat(ef_t *ef, char **args) -{ - long nb_loop = 0; - int status = 0; - pid_t pid; - - if (checking_error(args, &nb_loop)) - return RETURN_FAILURE; - pid = fork(); - if (pid == 0){ - signal(SIGINT, exit_child); - for (int i = 0; i < nb_loop; i++) - status = exec_the_args(ef, &args[2]); - exit(status); - } else - wait(&status); - if (WIFEXITED(status)) - ef->history->last_exit_code = - ef->history->last_exit_code ?: WEXITSTATUS(status); - return status; -} diff --git a/bonus/builtins/set.c b/bonus/builtins/set.c deleted file mode 100644 index d2ec61a..0000000 --- a/bonus/builtins/set.c +++ /dev/null @@ -1,73 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** set -*/ - -#include -#include -#include -#include -#include - -#include "common.h" -#include "env.h" -#include "exec.h" -#include "u_str.h" - -void print_local(ef_t *ef) -{ - for (size_t i = 0; i < ef->exec_ctx->local->sz; i++) { - if (ef->exec_ctx->local->local_var[i] == NULL) - continue; - write(ef->out_fd, ef->exec_ctx->local->local_var[i], - u_strlen(ef->exec_ctx->local->local_var[i])); - WRITE_CONST(ef->out_fd, "\n"); - } -} - -int special_case(ef_t *ef, char **args) -{ - int piv = 0; - char *key = NULL; - char *val = NULL; - - if (args[1] == NULL) - return print_local(ef), RETURN_SUCCESS; - for (; args[1][piv] && args[1][piv] != '='; piv++); - key = strndup(args[1], piv); - if (key == NULL) - return RETURN_FAILURE; - if (check_local_var(key, args[0])) - return free(key), RETURN_FAILURE; - if (args[1][piv] != '\0') - val = &args[1][piv + 1]; - if (!set_local(ef->exec_ctx->local, key, val)) - return free(key), RETURN_FAILURE; - free(key); - return RETURN_SUCCESS; -} - -int builtins_set(ef_t *ef, char **args) -{ - char *var = NULL; - - if (my_array_len(args) < 3) - return special_case(ef, args); - for (int i = 1; args[i]; i++){ - if (check_local_var(args[i], args[0])) - return RETURN_FAILURE; - var = args[i]; - i++; - if (!args[i]) - return (set_local(ef->exec_ctx->local, var, NULL) - , RETURN_SUCCESS); - if (strcmp(args[i], "=")) - return RETURN_FAILURE; - i++; - if (!set_local(ef->exec_ctx->local, var, args[i])) - return RETURN_FAILURE; - } - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/unset.c b/bonus/builtins/unset.c deleted file mode 100644 index 9944e6c..0000000 --- a/bonus/builtins/unset.c +++ /dev/null @@ -1,26 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** unset -*/ - -#include -#include -#include -#include - -#include "common.h" -#include "exec.h" -#include "u_str.h" - - -int builtins_unset(ef_t *ef, char **args) -{ - if (args[1] == NULL) - return (WRITE_CONST(STDERR_FILENO, "unset: Too few arguments.\n"), - RETURN_FAILURE); - for (int i = 1; args[i]; i++) - unset_local(ef->exec_ctx->local, args[i]); - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/where.c b/bonus/builtins/where.c deleted file mode 100644 index 75e9383..0000000 --- a/bonus/builtins/where.c +++ /dev/null @@ -1,74 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include - -#include "alias.h" -#include "builtins.h" -#include "common.h" -#include "exec.h" -#include "path.h" -#include "u_str.h" - -const char *OTHER_BUILTINS[] = { - "echo" -}; - -const size_t OTHER_BUILTINS_SZ = sizeof OTHER_BUILTINS -/ sizeof *OTHER_BUILTINS; - -static -void search_builtins(ef_t *ef, char *arg) -{ - for (size_t i = 0; i < BUILTINS_SZ; i++) { - if (u_strlen(BUILTINS[i].name) != (int)strlen(arg)) - continue; - if (u_strcmp(BUILTINS[i].name, arg) == 0) - dprintf(ef->out_fd, "%s is a shell built-in\n", arg); - } - for (size_t i = 0; i < OTHER_BUILTINS_SZ; i++) { - if (u_strlen(OTHER_BUILTINS[i]) != (int)strlen(arg)) - continue; - if (u_strcmp(OTHER_BUILTINS[i], arg) == 0) - dprintf(ef->out_fd, "%s is a shell built-in\n", arg); - } -} - -static -bool search_cmd(ef_t *ef, char *arg) -{ - char *bin_path = parse_full_bin_path(ef->env, arg); - buff_t alias_path = { .str = strdup(arg), strlen(arg) }; - - if (alias_path.str == NULL) - return false; - if (bin_path == NULL) - return free(alias_path.str), NULL; - parse_alias(&alias_path.str, &alias_path.sz, ef->exec_ctx->alias); - if (strcmp(arg, alias_path.str) != 0) - dprintf(ef->out_fd, "%s is aliased to %s\n", arg, alias_path.str); - search_builtins(ef, arg); - if (strcmp(arg, bin_path) != 0) - dprintf(ef->out_fd, "%s\n", bin_path); - free(alias_path.str); - return true; -} - -int builtins_where(ef_t *ef, char **args) -{ - if (args[1] == NULL) - return dprintf(STDERR_FILENO, "%s: Too few arguments\n", args[0]), - RETURN_FAILURE; - for (size_t i = 1; args[i] != NULL; i++) { - if (!search_cmd(ef, args[i])) - return RETURN_FAILURE; - } - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/which.c b/bonus/builtins/which.c deleted file mode 100644 index fa0f3da..0000000 --- a/bonus/builtins/which.c +++ /dev/null @@ -1,80 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include - -#include "alias.h" -#include "builtins.h" -#include "common.h" -#include "exec.h" -#include "path.h" -#include "u_str.h" - -const char *OOTHER_BUILTINS[] = { - "echo" -}; - -const size_t OOTHER_BUILTINS_SZ = sizeof OOTHER_BUILTINS -/ sizeof *OOTHER_BUILTINS; - -static -bool search_builtin(ef_t *ef, char *arg) -{ - for (size_t i = 0; i < BUILTINS_SZ; i++) { - if (u_strlen(BUILTINS[i].name) != (int)strlen(arg)) - continue; - if (u_strcmp(BUILTINS[i].name, arg) == 0) - return dprintf(ef->out_fd, "%s: shell built-in command.\n", arg), - true; - } - for (size_t i = 0; i < OOTHER_BUILTINS_SZ; i++) { - if (u_strlen(OOTHER_BUILTINS[i]) != (int)strlen(arg)) - continue; - if (u_strcmp(OOTHER_BUILTINS[i], arg) == 0) - return dprintf(ef->out_fd, "%s: shell built-in command.\n", arg), - true; - } - return false; -} - -static -bool search_cmd(ef_t *ef, char *arg) -{ - char *bin_path = parse_full_bin_path(ef->env, arg); - buff_t alias_path = { .str = strdup(arg), strlen(arg) }; - - if (alias_path.str == NULL) - return false; - if (bin_path == NULL) - return free(alias_path.str), NULL; - parse_alias(&alias_path.str, &alias_path.sz, ef->exec_ctx->alias); - if (strcmp(arg, alias_path.str) != 0) - return dprintf(ef->out_fd, "%s:\t aliased to %s\n", arg, - alias_path.str), true; - if (search_builtin(ef, arg)) - return true; - if (strcmp(arg, bin_path) != 0) - return dprintf(ef->out_fd, "%s\n", bin_path), true; - fprintf(stderr, "%s: Command not found.\n", arg); - free(alias_path.str); - return true; -} - -int builtins_which(ef_t *ef, char **args) -{ - if (args[1] == NULL) - return dprintf(STDERR_FILENO, "%s: Too few arguments\n", args[0]), - RETURN_FAILURE; - for (size_t i = 1; args[i] != NULL; i++) { - if (!search_cmd(ef, args[i])) - return RETURN_FAILURE; - } - return RETURN_SUCCESS; -} diff --git a/bonus/builtins/yes.c b/bonus/builtins/yes.c deleted file mode 100644 index 58e37ea..0000000 --- a/bonus/builtins/yes.c +++ /dev/null @@ -1,70 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** yes -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "builtins.h" -#include "common.h" -#include "exec.h" -#include "u_mem.h" -#include "u_str.h" - -static -int len_buffer(char **args) -{ - int len_buffer = 0; - - for (int i = 0; args[i]; i++) - len_buffer += strlen(args[i]) + 1; - return len_buffer; -} - -static -char *define_prompt(char **args) -{ - char *buffer = nullptr; - - if (args[1] == NULL) - return u_strdup("y\n"); - buffer = malloc(sizeof(char) * (len_buffer(args) + 1)); - if (buffer == NULL) - return nullptr; - u_bzero(buffer, len_buffer(args) + 1); - strcpy(buffer, args[1]); - buffer[strlen(buffer)] = ' '; - for (int i = 2; args[i]; i++){ - strcat(buffer, args[i]); - if (args[i + 1] != NULL) - buffer[strlen(buffer)] = ' '; - } - buffer[strlen(buffer)] = '\n'; - return buffer; -} - -int builtins_yes(ef_t *ef, char **args) -{ - char *buffer = define_prompt(args); - pid_t pid; - - if (buffer == NULL) - return RETURN_FAILURE; - pid = fork(); - if (pid == 0) { - signal(SIGINT, exit_child); - while (true) - write(ef->out_fd, buffer, strlen(buffer)); - } else - wait(nullptr); - free(buffer); - return RETURN_SUCCESS; -} diff --git a/bonus/common.h b/bonus/common.h deleted file mode 100644 index 7959c82..0000000 --- a/bonus/common.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef COMMON_H - #define COMMON_H - #include - - #define PROMPT_HEADER "┌─[" - #define IF_PROMPT "if? " - -enum { - RETURN_SUCCESS = 0, - RETURN_FAILURE = 1 -}; - -typedef struct { - uint8_t flags; - char *script_file; - char *cmd; -} opt_t; -#endif /* COMMON_H */ diff --git a/bonus/ctx.h b/bonus/ctx.h deleted file mode 100644 index 273244a..0000000 --- a/bonus/ctx.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - - -#ifndef BUILTINS_HANDLER_H - #define BUILTINS_HANDLER_H - #include - - #include "alias.h" - #include "env.h" - #include "history.h" - #include "local.h" - #include "shell.h" - -typedef struct { - pid_t pgid; - bool running; - bool foreground; -} job_t; - -typedef struct { - job_t *jobs; - size_t sz; - size_t cap; -} jobs_t; - -typedef struct { - env_t *env; - history_t *history; - his_command_t *history_command; - alias_t *alias; - bool is_running; - struct termios saved_term_settings; - local_t *local; - opt_t *opt; - int read_fd; - int isatty; - jobs_t jobs; -} exec_ctx_t; - -size_t update_command(char **buffer, - size_t *buffer_sz, exec_ctx_t *exec_ctx); -#endif /* BUILTINS_HANDLER_H */ diff --git a/bonus/debug.h b/bonus/debug.h deleted file mode 100644 index 1aaa72b..0000000 --- a/bonus/debug.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef DEBUG_H - #define DEBUG_H - #include "vt100_esc_codes.h" - #include - - #define OMIT - - #ifdef U_DEBUG_MODE - #define HEAD __FILE_NAME__, __LINE__ - - #define HEAD_FMT_FILE BOLD BLUE "%s" RESET - #define HEAD_FMT_LINE ":" BOLD PURPLE "%d" RESET - - #define HEAD_FMT HEAD_FMT_FILE HEAD_FMT_LINE " " - - #define ERR(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) - #define DEBUG_INTERNAL(fmt, ...) ERR(HEAD_FMT fmt, HEAD, __VA_ARGS__) - - #define U_DEBUG(fmt, ...) DEBUG_INTERNAL(fmt, __VA_ARGS__) - #define U_DEBUG_MSG(msg) DEBUG_INTERNAL("%s", msg) - - #define U_DEBUG_CALL(func, ...) func(__VA_ARGS__) - #else - #define U_DEBUG_CALL(func, ...) OMIT - #define U_DEBUG_MSG(msg) OMIT - #define U_DEBUG(fmt, ...) OMIT - #endif - -#endif /* DEBUG_H */ diff --git a/bonus/env.c b/bonus/env.c deleted file mode 100644 index 7ad831c..0000000 --- a/bonus/env.c +++ /dev/null @@ -1,149 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include -#include - -#include "debug.h" -#include "env.h" -#include "u_mem.h" -#include "u_str.h" - -[[gnu::unused]] -static -void debug_env_entries(env_t *env) -{ - for (size_t i = 0; i < env->sz; i++) { - if (env->env[i] == NULL) - continue; - U_DEBUG("Env entry [%lu] [%s]\n", i, env->env[i]); - } -} - -char *get_env_value(env_t *env, char const *key) -{ - int key_len = u_strlen(key); - - for (size_t i = 0; i < env->sz; i++) { - if (env->env[i] == NULL) - continue; - if (u_strcspn(env->env[i], '=') != key_len) - continue; - if (u_strcmp(env->env[i], key) == 0) - return env->env[i] + key_len + 1; - } - return nullptr; -} - -static -void unset_env_move(env_t *env, size_t i) -{ - while (env->env[i]) { - env->env[i] = env->env[i + 1]; - i++; - } -} - -bool unset_env(env_t *env, char *key) -{ - int key_len = u_strlen(key); - - for (size_t i = 0; i < env->sz; i++) { - if (env->env[i] == NULL) - continue; - if (u_strcspn(env->env[i], '=') != key_len) - continue; - if (u_strcmp(env->env[i], key) == 0) { - unset_env_move(env, i); - env->sz--; - return true; - } - } - return false; -} - -void free_env(env_t *env) -{ - for (size_t i = 0; i < env->sz; i++) { - if (env->env[i] == NULL) - continue; - free(env->env[i]); - } - free((void *)env->env); -} - -static __attribute__((nonnull)) -bool ensure_env_capacity(env_t *env) -{ - char **new_ptr; - - if (env->sz < env->cap) - return true; - new_ptr = (char **)u_realloc((void *)env->env, sizeof *env->env * env->sz, - sizeof *env->env * env->cap << 1); - if (!new_ptr) - return false; - env->cap <<= 1; - env->env = new_ptr; - return true; -} - -static -void env_bzero(char **env, size_t sz) -{ - for (size_t i = 0; i < sz; i++) - env[i] = nullptr; -} - -bool set_env(env_t *env, char *key, char *value) -{ - char *new_env = nullptr; - size_t key_len = u_strlen(key); - size_t value_len = u_strlen(value); - - if (get_env_value(env, key) != NULL) - unset_env(env, key); - env->sz++; - if (!ensure_env_capacity(env)) - return false; - new_env = malloc(sizeof(char) * (key_len + value_len + 2)); - if (new_env == NULL) - return false; - u_bzero(new_env, key_len + value_len + 2); - u_strcpy(new_env, key); - new_env[key_len] = '='; - if (value_len > 0) - u_strcpy(new_env + key_len + 1, value); - env->env[env->sz - 1] = new_env; - return true; -} - -env_t parse_env(char **env) -{ - env_t new_env = { 0, .cap = BASE_ENV_CAP }; - - new_env.env = (char **)malloc(sizeof(char *) * new_env.cap); - if (!new_env.env) - return (env_t){ 0, .env = nullptr }; - env_bzero(new_env.env, new_env.sz); - for (; *env != NULL; env++) { - if (!ensure_env_capacity(&new_env)) - return (free((void *)new_env.env), (env_t){ 0 }); - new_env.env[new_env.sz] = u_strdup(*env); - if (new_env.env[new_env.sz] == NULL) - return (free((void *)new_env.env), (env_t){ 0 }); - new_env.sz++; - } - if (!ensure_env_capacity(&new_env)) - return (free((void *)new_env.env), (env_t){ 0 }); - new_env.env[new_env.sz] = nullptr; - U_DEBUG_CALL(debug_env_entries, &new_env); - return new_env; -} diff --git a/bonus/env.h b/bonus/env.h deleted file mode 100644 index 9eaec00..0000000 --- a/bonus/env.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef ENV_H - #define ENV_H - #include - #include - #define BASE_ENV_CAP 128 - -typedef struct { - size_t sz; - size_t cap; - char **env; -} env_t; - -__attribute__((unused)) -void free_env(env_t *env); -__attribute__((unused)) -env_t parse_env(char **env); -__attribute__((unused)) -char *get_env_value(env_t *env, char const *key); -__attribute__((unused)) -bool unset_env(env_t *env, char *key); -__attribute__((nonnull(1, 2))) -bool set_env(env_t *env, char *key, char *value); -#endif diff --git a/bonus/exec.c b/bonus/exec.c deleted file mode 100644 index a53b734..0000000 --- a/bonus/exec.c +++ /dev/null @@ -1,236 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "args.h" -#include "ast.h" -#include "builtins.h" -#include "common.h" -#include "debug.h" -#include "env.h" -#include "exec.h" -#include "job.h" -#include "path.h" -#include "repl.h" -#include "u_mem.h" -#include "u_str.h" - -const builtins_funcs_t BUILTINS[] = { - { "builtins", &builtins_builtins }, - { "cd", &builtins_cd }, - { "chdir", &builtins_cd }, - { "env", &builtins_env }, - { "printenv", &builtins_env }, - { "setenv", &builtins_setenv }, - { "unsetenv", &builtins_unsetenv }, - { ":", &builtins_funny_double_dot }, - { "repeat", &builtins_repeat }, - { "exit", &builtins_exit }, - { "history", &builtins_history}, - { "alias", &builtins_alias}, - { "yes", &builtins_yes }, - { "foreach", &builtins_foreach }, - { "while", &builtins_while }, - { "set", &builtins_set }, - { "unset", &builtins_unset }, - { "where", &builtins_where }, - { "which", &builtins_which }, - { "expr", &builtins_expr }, - { "if", &builtins_if }, - { "fg", &builtins_fg }, - { "break", &builtins_break } -}; - -const size_t BUILTINS_SZ = sizeof BUILTINS / sizeof *BUILTINS; - -__attribute__((nonnull)) -bool ensure_args_capacity(args_t *args) -{ - char **new_ptr; - - if (args->sz + 1 < args->cap) - return true; - new_ptr = (char **)u_realloc((void *)args->args, sizeof *args->args * - args->sz, sizeof *args->args * args->cap << 1); - if (!new_ptr) - return false; - args->cap <<= 1; - args->args = new_ptr; - return true; -} - -static -char **parse_args(ef_t *ef, ast_t *node) -{ - args_t args = { .args = (char **)malloc(sizeof *args.args - * DEFAULT_ARGS_CAP), .sz = 0, .cap = DEFAULT_ARGS_CAP }; - - if (!args.args) - return nullptr; - for (size_t i = 0; i < node->vector.sz; i++) { - if (ef->skip_sz > 0 && i >= ef->skip_i && i < ef->skip_i + ef->skip_sz) - continue; - if (!process_args(node, &args, &i, ef)) - return free((void *)args.args), NULL; - } - if (!ensure_args_capacity(&args)) - return nullptr; - args.args[args.sz] = nullptr; - return args.args; -} - -static -int command_error(char *cmd, char **args, int error) -{ - struct stat st; - - if (access(cmd, F_OK) == -1) { - write(STDERR_FILENO, args[0], u_strlen(args[0])); - WRITE_CONST(STDERR_FILENO, ": Command not found.\n"); - return 84; - } - stat(cmd, &st); - if (S_ISDIR(st.st_mode) || access(cmd, X_OK)) { - write(STDERR_FILENO, args[0], u_strlen(args[0])); - WRITE_CONST(STDERR_FILENO, ": Permission denied.\n"); - return 84; - } - if (error == ENOEXEC) { - write(STDERR_FILENO, args[0], u_strlen(args[0])); - WRITE_CONST(STDERR_FILENO, ": Exec format error." - " Binary file not executable.\n"); - return 0; - } - return 84; -} - -static -void set_fd(ef_t *ef) -{ - U_DEBUG("In fd [%d] out fd [%d]\n", ef->in_fd, ef->out_fd); - if (ef->in_fd != STDIN_FILENO) { - dup2(ef->in_fd, STDIN_FILENO); - close(ef->in_fd); - } - if (ef->out_fd != STDOUT_FILENO) { - dup2(ef->out_fd, STDOUT_FILENO); - close(ef->out_fd); - } -} - -static -int exec(char *full_bin_path, char **args, ef_t *ef) -{ - execve(full_bin_path, args, ef->env->env); - return command_error(full_bin_path, args, errno); -} - -static -int launch_bin(char *full_bin_path, char **args, ef_t *ef) -{ - int status; - pid_t pid = fork(); - int nohang; - - if (pid == 0) { - restore_term_flags(ef->exec_ctx); - set_fd(ef); - init_child_job(ef->exec_ctx, pid); - status = exec(full_bin_path, args, ef); - exit(RETURN_FAILURE); - } - init_child_job(ef->exec_ctx, pid); - nohang = ef->flags & F_PIPE || ef->p_i != ef->p_sz - 1; - waitpid(pid, &status, nohang ? WUNTRACED : WNOHANG); - if (WIFSTOPPED(status)) { - ef->exec_ctx->jobs.jobs[ef->exec_ctx->jobs.sz - 1].running = true; - ef->exec_ctx->jobs.jobs[ef->exec_ctx->jobs.sz - 1].foreground = false; - printf("\n[%lu]+ Continued &\n", ef->exec_ctx->jobs.sz); - } - if (WIFEXITED(status)) - ef->exec_ctx->history->last_exit_code = - ef->exec_ctx->history->last_exit_code ?: WEXITSTATUS(status); - tcsetpgrp(ef->exec_ctx->read_fd, ef->exec_ctx->jobs.jobs[0].pgid); - return status; -} - -static -void status_handler(int status) -{ - if (!WIFEXITED(status) && WIFSIGNALED(status) && WTERMSIG(status)) { - if (WTERMSIG(status) == SIGSEGV) - WRITE_CONST(STDERR_FILENO, "Segmentation fault"); - if (WTERMSIG(status) == SIGTRAP) - WRITE_CONST(STDERR_FILENO, "Trace/BPT trap"); - if (WTERMSIG(status) == SIGFPE) - WRITE_CONST(STDERR_FILENO, "Floating exception"); - if (WCOREDUMP(status) && (WTERMSIG(status) == SIGSEGV || - WTERMSIG(status) == SIGFPE || WTERMSIG(status) == SIGTRAP)) - WRITE_CONST(STDERR_FILENO, " (core dumped)"); - if (WTERMSIG(status) == SIGSEGV || WTERMSIG(status) == SIGFPE || - WTERMSIG(status) == SIGTRAP) - WRITE_CONST(STDERR_FILENO, "\n"); - } -} - -static -bool builtins_launcher(ef_t *ef, char **args) -{ - int bin_l = u_strlen(args[0]); - - U_DEBUG("In fd [%d] out fd [%d]\n", ef->in_fd, ef->out_fd); - for (size_t i = 0; i < BUILTINS_SZ; i++) { - if (u_strlen(BUILTINS[i].name) != bin_l) - continue; - if (u_strcmp(BUILTINS[i].name, args[0]) == 0) { - restore_term_flags(ef->exec_ctx); - ef->exec_ctx->history->last_exit_code = - BUILTINS[i].ptr(ef, args); - return true; - } - } - return false; -} - -int exec_the_args(ef_t *ef, char **args) -{ - char *full_bin_path; - int status; - - if (builtins_launcher(ef, args)) - return RETURN_SUCCESS; - full_bin_path = parse_full_bin_path(ef->env, args[0]); - if (full_bin_path == NULL) - return (free((void *)args), RETURN_FAILURE); - U_DEBUG("Found bin [%s]\n", full_bin_path); - status = launch_bin(full_bin_path, args, ef); - status_handler(status); - U_DEBUG("Exit code [%d]\n", ef->history->last_exit_code); - free(full_bin_path); - return status; -} - -int execute(ef_t *ef) -{ - char **args; - - args = parse_args(ef, ef->act_node); - if (!args) - return RETURN_FAILURE; - exec_the_args(ef, args); - free((void *)args); - init_shell_repl(ef->exec_ctx); - return ef->exec_ctx->history->last_exit_code - != 0 ? RETURN_FAILURE : RETURN_SUCCESS; -} diff --git a/bonus/exec.h b/bonus/exec.h deleted file mode 100644 index a3cb66c..0000000 --- a/bonus/exec.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef EXEC_H - #define EXEC_H - #include "ast.h" - #include "env.h" - #include "shell.h" - - #define DEFAULT_ARGS_CAP 1 - -typedef struct { - char **args; - size_t sz; - size_t cap; -} args_t; - -enum flags { - F_PIPE = 1 << 0, - F_RED = 1 << 1, - F_EXIT = 1 << 2 -}; - -typedef struct { - char *buffer; - env_t *env; - history_t *history; - ast_ctx_t *ctx; - ast_t *act_node; - size_t skip_i; - size_t skip_sz; - uint8_t flags; - size_t p_i; - size_t p_sz; - int rin_fd; - int rout_fd; - int pipes[2]; - int pin_fd; - int pout_fd; - int in_fd; - int out_fd; - exec_ctx_t *exec_ctx; -} ef_t; - -__attribute__((nonnull)) -int execute(ef_t *ef); -bool ensure_args_capacity(args_t *args); -int exec_the_args(ef_t *ef, char **args); -void exit_child(int sig __attribute__((unused))); -int visit_loop(ef_t *ef, ast_t *node); -void handle_var_case(ast_t *node, exec_ctx_t *ctx, size_t *i, args_t *args); -bool handle_magic_quotes(ast_t *node, exec_ctx_t *ctx, - size_t *i, args_t *args); -bool handle_var(ast_t *node, size_t *i, exec_ctx_t *ctx, args_t *args); -char *get_values(exec_ctx_t *ctx, char *key); -#endif /* EXEC_H */ diff --git a/bonus/handle_quotes.c b/bonus/handle_quotes.c deleted file mode 100644 index fc4571a..0000000 --- a/bonus/handle_quotes.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** handle_quotes -*/ -#include -#include -#include -#include -#include - -#include "ast.h" -#include "env.h" -#include "local.h" -#include "exec.h" -#include "u_str.h" - -static -char *set_f_part(char *node_str) -{ - char *f_part = strdup(node_str); - int i = 0; - - if (f_part == NULL) - return NULL; - for (; f_part[i] && f_part[i] != '$'; i++); - f_part[i] = '\0'; - return f_part; -} - -static -char *set_s_part(char *node_str, int len_f_part, ast_t *node, size_t *i) -{ - int pointer_rank = len_f_part; - - for (; pointer_rank < node->vector.tokens[*i].sz && node_str[pointer_rank] - && !isblank(node_str[pointer_rank]); pointer_rank++); - return strndup(&node_str[pointer_rank], - node->vector.tokens[*i].sz - pointer_rank); -} - -static -bool concat_and_free(char *var, char *f_part, char *s_part, args_t *args) -{ - args->args[args->sz] = malloc(sizeof(char) * - (strlen(f_part) + strlen(s_part) + strlen(var) + 1)); - if (args->args[args->sz] == NULL) - return free(f_part), true; - strcpy(args->args[args->sz], f_part); - strcat(args->args[args->sz], var); - strcat(args->args[args->sz], s_part); - free(s_part); - free(f_part); - return false; -} - -static -bool concat_var(char *var, args_t *args, ast_t *node, size_t *i) -{ - char *f_part = set_f_part(node->vector.tokens[*i].str); - char *s_part = NULL; - - args->args[args->sz] = var; - if (f_part == NULL) - return true; - s_part = set_s_part(node->vector.tokens[*i].str, strlen(f_part), node, i); - if (s_part == NULL) - return free(f_part), true; - return concat_and_free(var, f_part, s_part, args); -} - -char *get_key(ast_t *node, size_t *i) -{ - size_t id = 0; - - for (; node->vector.tokens[*i].str && - id < node->vector.tokens[*i].sz; id++) - if (node->vector.tokens[*i].str[id] == '$'){ - id++; - return strndup(&node->vector.tokens[*i].str[id], - node->vector.tokens[*i].sz - id); - } - return NULL; -} - -bool handle_var(ast_t *node, size_t *i, exec_ctx_t *ctx, args_t *args) -{ - char *key = get_key(node, i); - char *var = NULL; - int end_key = 0; - - if (key == NULL){ - args->args[args->sz] = strndup(node->vector.tokens[*i].str, - node->vector.tokens[*i].sz); - return false; - } - if (key == NULL) - return true; - for (; key[end_key] && !isblank(key[end_key]); end_key++); - key[end_key] = '\0'; - var = get_values(ctx, key); - free(key); - if (var == NULL) - return true; - return concat_var(var, args, node, i); -} diff --git a/bonus/handle_vars.c b/bonus/handle_vars.c deleted file mode 100644 index aee6efa..0000000 --- a/bonus/handle_vars.c +++ /dev/null @@ -1,147 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** handle_vars -*/ - -#include -#include -#include -#include -#include - -#include "ast.h" -#include "env.h" -#include "local.h" -#include "exec.h" - -char *get_values(exec_ctx_t *ctx, char *key) -{ - char *r_char = NULL; - - r_char = get_env_value(ctx->env, key); - if (r_char == NULL) - r_char = get_local_value(ctx->local, key); - if (r_char == NULL) { - fprintf(stderr, "%s: Undefined variable.\n", key); - return NULL; - } - return r_char; -} - -static -char *take_next_parenthese_arg(ast_t *node, size_t *in_str, size_t *i) -{ - size_t end = 0; - char *buff; - - while (node->vector.tokens[*i].sz > *in_str && - isblank(node->vector.tokens[*i].str[*in_str])) - *in_str = *in_str + 1; - for (; node->vector.tokens[*i].sz > *in_str + end && - !isblank(node->vector.tokens[*i].str[*in_str + end]); end++); - buff = strndup(&node->vector.tokens[*i].str[*in_str], end); - *in_str += end; - return buff; -} - -static -bool handle_parentheses(ast_t *node, exec_ctx_t *ctx, size_t *i, args_t *args) -{ - size_t in_str = 0; - char *vl; - - while (in_str < node->vector.tokens[*i].sz){ - if (!ensure_args_capacity(args)) - return false; - vl = take_next_parenthese_arg(node, &in_str, i); - if (vl == NULL) - return free((void *)args->args), false; - args->args[args->sz] = vl; - args->sz++; - } - args->args[args->sz] = NULL; - args->sz--; - return true; -} - -static -bool check_parentheses(ast_t *node, size_t *i, exec_ctx_t *ctx, args_t *args) -{ - if (!strchr("()", node->vector.tokens[*i].str[0])) - return true; - if (strlen(node->vector.tokens[*i].str) == 1 || - (node->vector.tokens[*i].str[0] == '(' && - node->vector.tokens[*i].str[node->vector.tokens[*i].sz - 1] != ')')) - return (fprintf(stderr, "Too many ('s.\n"), true); - if (node->vector.tokens[*i].str[0] == ')') - return (fprintf(stderr, "Too many )'s.\n"), true); - node->vector.tokens[*i].str[node->vector.tokens[*i].sz - 1] = '\0'; - node->vector.tokens[*i].str = &node->vector.tokens[*i].str[1]; - node->vector.tokens[*i].sz -= 2; - if (!handle_parentheses(node, ctx, i, args)) - return true; - return false; -} - -static -bool format_quotes(ast_t *node, char be_matched, size_t *i) -{ - char *last_quote = strchr(node->vector.tokens[*i].str, be_matched); - - if (last_quote == NULL) - return (fprintf(stderr, "Unmatched \'%c\'.\n", be_matched), false); - node->vector.sz -= 2; - if (isblank(last_quote[1] || be_matched == '`')){ - last_quote[0] = '\0'; - return true; - } else - node->vector.tokens[*i].str[node->vector.tokens[*i].sz - 1] = '\0'; - memmove(&last_quote[0], &last_quote[1], strlen(last_quote)); - last_quote = strchr(node->vector.tokens[*i].str, be_matched); - if (strchr(node->vector.tokens[*i].str, be_matched)) - return (fprintf(stderr, "Unmatched \'%c\'.\n", be_matched), false); - node->vector.tokens[*i].str[node->vector.tokens[*i].sz - 2] = '\0'; - return true; -} - -static -bool check_quotes(ast_t *node, size_t *i, exec_ctx_t *ctx, args_t *args) -{ - char be_matched = node->vector.tokens[*i].str[0]; - - if (!strchr("\'\"`", node->vector.tokens[*i].str[0])) - return true; - if (node->vector.tokens[*i].sz == 1) - return (fprintf(stderr, "Unmatched \'%c\'.\n", be_matched), true); - memmove(&node->vector.tokens[*i].str[0], - &node->vector.tokens[*i].str[1], node->vector.tokens[*i].sz); - if (!format_quotes(node, be_matched, i)) - return true; - if (be_matched == '`') - return handle_magic_quotes(node, ctx, i, args); - if (be_matched == '\"') - return handle_var(node, i, ctx, args); - args->args[args->sz] = strdup(node->vector.tokens[*i].str); - return false; -} - -bool check_for_closable(ast_t *node, exec_ctx_t *ctx, size_t *i, args_t *args) -{ - if (!strchr("\'\"`()", node->vector.tokens[*i].str[0])) - return false; - if (!check_parentheses(node, i, ctx, args)) - return true; - else if (!check_quotes(node, i, ctx, args)) - return true; - args->args[args->sz] = NULL; - return true; -} - -void handle_var_case(ast_t *node, exec_ctx_t *ctx, size_t *i, args_t *args) -{ - if (check_for_closable(node, ctx, i, args)) - return; - handle_var(node, i, ctx, args); -} diff --git a/bonus/history.h b/bonus/history.h deleted file mode 100644 index 9226af2..0000000 --- a/bonus/history.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef HISTORY_H - #define HISTORY_H - #define CHAR_HIST '!' - #define TWO_CHAR_CMD 3 - - #include - - - -typedef struct history_variable_s { - int coord_variable; - int size_variable; - int type; - char *str; - int id; -} his_variable_t; - -typedef struct history_command_s { - int id; - char *command; - char *arg; - int sz; -} his_command_t; - -typedef struct parsing_history_s { - char const *name; - char *(*funct)(char *, his_variable_t *, his_command_t *); -} parsing_history_t; - -extern const parsing_history_t tab_fnct[]; - -int parse_history(char **pointer_line, - size_t *buffer_len, size_t *buffer_sz, his_command_t **cmd_history); -char *his_last_command(char *line, - his_variable_t *his_variable, his_command_t *his_command); -char *his_last_same_command(char *line, - his_variable_t *his_variable, his_command_t *his_command); -char *his_id_command(char *line, - his_variable_t *his_variable, his_command_t *his_command); -char *his_last_word(char *line, - his_variable_t *his_variable, his_command_t *his_command); -char *his_last_arg(char *line, - his_variable_t *his_variable, his_command_t *his_command); -his_command_t *fill_cmd_history(his_command_t *cmd_history); -int save_cmd_history(his_command_t *cmd_history); -his_command_t set_cmd(char *line, his_command_t cmd_struct); -#endif /* HISTORY_H */ diff --git a/bonus/init_history.c b/bonus/init_history.c deleted file mode 100644 index 99b2d5b..0000000 --- a/bonus/init_history.c +++ /dev/null @@ -1,46 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** init_history -*/ - -#include -#include -#include "stdlib.h" -#include "stdio.h" -#include "string.h" -#include "history.h" -#include "ctype.h" - -static char *get_arg(char *line, int x, int end_cmd) -{ - char *tmp = malloc(sizeof(char) * ((x - end_cmd) + 1)); - - if (tmp != NULL) { - tmp = strncpy(tmp, &line[end_cmd], x - end_cmd); - tmp[x - end_cmd] = '\0'; - } - return tmp; -} - -his_command_t set_cmd(char *line, his_command_t cmd_struct) -{ - int x = 0; - int end_cmd; - - while (line[x] != '\0' && !isblank(line[x])) - x++; - cmd_struct.command = malloc((sizeof(char) * x + 1)); - if (cmd_struct.command != NULL) { - cmd_struct.command = strncpy(cmd_struct.command, line, x); - cmd_struct.command[x] = '\0'; - } - end_cmd = x + 1; - while (line[x] != '\0') - x++; - if (x <= end_cmd) - return cmd_struct; - cmd_struct.arg = get_arg(line, x, end_cmd); - return cmd_struct; -} diff --git a/bonus/job.c b/bonus/job.c deleted file mode 100644 index 81dd89d..0000000 --- a/bonus/job.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include - -#include "debug.h" -#include "ctx.h" -#include "job.h" - -static -void set_ignored_signals(int child) -{ - signal(SIGTTOU, child ? SIG_DFL : SIG_IGN); - signal(SIGTTIN, child ? SIG_DFL : SIG_IGN); -} - -bool ensure_jobs_capacity(jobs_t *jobs) -{ - job_t *tmp; - - if (jobs->sz + 1 < jobs->cap) - return true; - tmp = realloc(jobs->jobs, sizeof *jobs->jobs * jobs->cap << 1); - if (tmp == nullptr) - return false; - jobs->jobs = tmp; - jobs->cap <<= 1; - return true; -} - -bool set_child_fg(exec_ctx_t *ec, size_t idx) -{ - if (tcsetpgrp(ec->read_fd, ec->jobs.jobs[idx].pgid) < 0) - return false; - kill(-ec->jobs.jobs[idx].pgid, SIGCONT); - return true; -} - -bool init_child_job(exec_ctx_t *ec, pid_t pid) -{ - if (pid == 0) { - setpgid(0, 0); - if (tcsetpgrp(ec->read_fd, getpid()) < 0) - return false; - set_ignored_signals(1); - } else { - setpgid(pid, pid); - if (!ensure_jobs_capacity(&ec->jobs)) - return false; - ec->jobs.jobs[ec->jobs.sz].pgid = pid; - ec->jobs.jobs[ec->jobs.sz].running = true; - ec->jobs.jobs[ec->jobs.sz].foreground = true; - ec->jobs.sz++; - if (tcsetpgrp(ec->read_fd, pid) < 0) - return false; - } - return true; -} - -bool init_jobs(exec_ctx_t *ec) -{ - if (ec->read_fd != STDIN_FILENO || !isatty(ec->read_fd)) - return true; - ec->jobs.cap = DEFAULT_JOBS_CAP; - ec->jobs.jobs = malloc(sizeof *ec->jobs.jobs * ec->jobs.cap); - if (ec->jobs.jobs == nullptr) - return false; - ec->jobs.jobs[0].pgid = getpid(); - ec->jobs.jobs[0].running = true; - ec->jobs.sz = 1; - if (setpgid(ec->jobs.jobs[0].pgid, ec->jobs.jobs[0].pgid) < 0) - return false; - if (tcsetpgrp(STDIN_FILENO, ec->jobs.jobs[0].pgid) < 0) - return false; - set_ignored_signals(0); - return true; -} diff --git a/bonus/job.h b/bonus/job.h deleted file mode 100644 index 4a0712d..0000000 --- a/bonus/job.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef JOB_H - #define JOB_H - #include - - #include "ctx.h" - #define DEFAULT_JOBS_CAP 4 - -bool ensure_jobs_capacity(jobs_t *jobs); -bool init_jobs(exec_ctx_t *ec); -bool init_child_job(exec_ctx_t *ec, pid_t pid); -bool set_child_fg(exec_ctx_t *ec, size_t idx); -#endif /* JOB_H */ diff --git a/bonus/local.h b/bonus/local.h deleted file mode 100644 index 9864b19..0000000 --- a/bonus/local.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef LOCAL_H - #define LOCAL_H - #include - #include - -typedef struct { - size_t sz; - size_t cap; - char **local_var; - bool in_a_loop; -} local_t; - -bool set_local(local_t *local, char *var, char *value); -bool check_local_var(char *var, char *func_name); -bool unset_local(local_t *local, char *var); -char *get_local_value(local_t *local, char const *key); -local_t create_local(void); -#endif /* LOCAL_H */ diff --git a/bonus/loop.h b/bonus/loop.h deleted file mode 100644 index 3832047..0000000 --- a/bonus/loop.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef LOOP_H - #define LOOP_H - #include - #include - - #include "exec.h" - -typedef struct { - size_t sz; - size_t cap; - char **cmds; -} usr_cmd_t; - -usr_cmd_t *get_usr_loop_cmd(exec_ctx_t *exec_ctx, usr_cmd_t *usr_cmd, - char const *prompt); -#endif /* LOOP_H */ diff --git a/bonus/magic_quotes.c b/bonus/magic_quotes.c deleted file mode 100644 index 11ed5a0..0000000 --- a/bonus/magic_quotes.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** magic_quotes -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "exec.h" -#include "u_mem.h" - -static -void exec_magic(ast_t *node, exec_ctx_t *ctx, size_t *i, int fd[2]) -{ - pid_t pid = 0; - - node->vector.tokens[*i].str[node->vector.tokens[*i].sz - 1] = '\0'; - pid = fork(); - if (pid == 0){ - close(fd[0]); - dup2(fd[1], STDOUT_FILENO); - visitor(node->vector.tokens[*i].str, ctx); - close(fd[1]); - exit(ctx->history->last_exit_code); - } - wait(&ctx->history->last_exit_code); -} - -char *realloc_buffer(char *to_return, size_t *sz, size_t *i) -{ - char *temp; - - if (to_return == NULL){ - *sz = 2; - *i = 0; - to_return = malloc(sizeof(char) * *sz); - } - if (*i >= *sz){ - temp = realloc(to_return, *sz << 1); - *sz = *sz << 1; - if (temp == NULL) - return free(to_return), NULL; - to_return = temp; - } - return to_return; -} - -char *add_to_args(char *to_return, args_t *args, size_t *sz, size_t i) -{ - to_return = realloc_buffer(to_return, sz, &i); - if (to_return == NULL) - return NULL; - to_return[i] = '\0'; - if (!ensure_args_capacity(args)) - return (free(to_return), NULL); - args->args[args->sz] = to_return; - args->sz++; - return NULL; -} - -char *handle_buffer(char *to_return, size_t *sz, size_t *i, char buf) -{ - to_return = realloc_buffer(to_return, sz, i); - if (to_return == NULL) - return NULL; - to_return[*i] = buf; - return to_return; -} - -static -void put_output(int fd[2], args_t *args, char *to_return, size_t sz) -{ - char buf; - - for (size_t i = 0; read(fd[0], &buf, 1) > 0; i++){ - if (strchr("$'", buf)){ - i--; - continue; - } - if (buf == '\n'){ - to_return = add_to_args(to_return, args, &sz, i); - continue; - } - to_return = handle_buffer(to_return, &sz, &i, buf); - } - args->sz--; -} - -static -void get_output(int fd[2], args_t *args) -{ - size_t sz = 2; - char *to_return = malloc(sizeof(char) * sz); - - if (to_return == NULL) - return; - put_output(fd, args, to_return, sz); -} - -bool handle_magic_quotes(ast_t *node, exec_ctx_t *ctx, - size_t *i, args_t *args) -{ - int fd[2]; - - if (pipe(fd) == -1) - return true; - exec_magic(node, ctx, i, fd); - close(fd[1]); - get_output(fd, args); - close(fd[0]); - return false; -} diff --git a/bonus/main.c b/bonus/main.c deleted file mode 100644 index 8d6ad83..0000000 --- a/bonus/main.c +++ /dev/null @@ -1,57 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include - -#include "common.h" -#include "debug.h" -#include "shell.h" - -const char OPT_FLAGS[] = "hc:"; - -static -void print_usages(FILE *file, char *bin) -{ - fprintf(file, "Usage: %s [-c command] [-dixv]" - " [file]\n", bin); -} - -static -bool parse_args(opt_t *opt, int ac, char **av) -{ - for (int o = getopt(ac, av, OPT_FLAGS); o != -1; - o = getopt(ac, av, OPT_FLAGS)) { - switch (o) { - case 'h': - exit((print_usages(stdout, av[0]), RETURN_SUCCESS)); - case 'c': - opt->cmd = strdup(optarg); - break; - default: - return print_usages(stderr, av[0]), false; - } - } - if (optind < ac) { - opt->script_file = av[optind]; - U_DEBUG("Script file [%s]\n", opt->script_file); - } else { - U_DEBUG_MSG("No script file provided.\n"); - } - return true; -} - -int main(int ac, char **av, char **env) -{ - opt_t opt = { 0, .script_file = nullptr, .cmd = nullptr }; - - U_DEBUG_MSG("Debug mode altivated.\n"); - if (!parse_args(&opt, ac, av)) - return RETURN_FAILURE; - return shell(&opt, env); -} diff --git a/bonus/parse_history.c b/bonus/parse_history.c deleted file mode 100644 index e3dd38d..0000000 --- a/bonus/parse_history.c +++ /dev/null @@ -1,129 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** history_42sh -** File description: -** his for history -*/ - -#include -#include -#include -#include -#include - -#include "history.h" -#include "u_str.h" -#include "utils.h" - -const parsing_history_t tab_fnct[] = { - {"!!", &his_last_command}, - {"!$", &his_last_word}, - {"!*", &his_last_arg}, - {"![command]", &his_last_same_command}, - {"![number]", &his_id_command}, -}; - -static -int cmd_history_is_in(char *line) -{ - for (int i = 0; line[i] != 0; i++) - if (line[i] == CHAR_HIST && - (line[i + 1] != ' ' && line[i + 1] != '\t' - && line[i + 1] != '\0')) - return 0; - return 1; -} - -static -int is_two_char_cmd(char *line, int coord_x) -{ - if (line[coord_x] != CHAR_HIST) - return -1; - coord_x++; - switch (line[coord_x]){ - case '!': - return 0; - case '$': - return 1; - case '*': - return 2; - default: - return -1; - } -} - -static -int choose_id_or_last(his_variable_t *his_variable, int index_str, char *str) -{ - int mode = 0; - const int cpy_index = index_str; - - if (str[index_str] != CHAR_HIST && is_a_token(str, index_str + 1) == false) - return -1; - index_str++; - for (; str[index_str] != 0; index_str++){ - if (is_a_token(str, index_str) == true || isblank(str[index_str])) - break; - if (!isdigit(str[index_str])) - mode = 1; - } - his_variable->coord_variable = cpy_index; - his_variable->size_variable = index_str - cpy_index; - his_variable->str = strn_to_ndup(cpy_index, (index_str - cpy_index), str); - if (his_variable->str == NULL) - return 3; - his_variable->id = atoi(his_variable->str + 1); - free(his_variable->str); - return (mode == 1) ? 3 : 4; -} - -static -int which_his_cmd(his_variable_t *his_variable, char const *line) -{ - for (int i = 0; line[i] != '\0'; i++){ - his_variable->type = is_two_char_cmd(line, i); - if (his_variable->type != -1){ - his_variable->coord_variable = i; - his_variable->size_variable = 2; - return 0; - } - his_variable->type = choose_id_or_last(his_variable, i, line); - if (his_variable->type != -1) - return 0; - } - return 0; -} - -static -char *replace_history(char *line, his_command_t *cmd_history) -{ - his_variable_t his_variable = {.coord_variable = 0, - .id = 0, .size_variable = 0, .str = NULL, .type = -1}; - - which_his_cmd(&his_variable, line); - while (his_variable.type != -1){ - line = tab_fnct[his_variable.type].funct(line, &his_variable, - cmd_history); - if (line == NULL) - return NULL; - which_his_cmd(&his_variable, line); - } - return line; -} - -int parse_history(char **pointer_line, - size_t *buffer_len, size_t *buffer_sz, his_command_t **cmd_history) -{ - char *line = *pointer_line; - - *buffer_sz = 0; - if (cmd_history_is_in(line) == 0){ - line = replace_history(line, *cmd_history); - if (line == NULL) - return 84; - *buffer_len = u_strlen(line) + 1; - *pointer_line = line; - return 0; - } - return 0; -} diff --git a/bonus/path.c b/bonus/path.c deleted file mode 100644 index 84a8447..0000000 --- a/bonus/path.c +++ /dev/null @@ -1,68 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include - -#include "env.h" -#include "path.h" -#include "u_str.h" - -static -char *build_full_path(const char *token, const char *binary) -{ - size_t len_token = u_strlen(token); - size_t len_bin = u_strlen(binary); - char *full_path = malloc(len_token + len_bin + 2); - - if (!full_path) - return nullptr; - u_strcpy(full_path, token); - full_path[len_token] = '/'; - u_strcpy(full_path + len_token + 1, binary); - full_path[len_token + len_bin + 1] = '\0'; - return full_path; -} - -static -char *find_binary(const char *path_env, const char *binary, char **dup_path) -{ - static char *saveptr = nullptr; - char *token; - char *full_path; - - if (path_env) { - *dup_path = u_strdup(path_env); - if (!*dup_path) - return nullptr; - token = strtok_r(*dup_path, ":", &saveptr); - } else - token = strtok_r(nullptr, ":", &saveptr); - if (!token) - return u_strdup(binary); - full_path = build_full_path(token, binary); - if (!full_path) - return nullptr; - return access(full_path, X_OK) == 0 ? full_path : (free(full_path), - find_binary(nullptr, binary, dup_path)); -} - -char *parse_full_bin_path(env_t *env, char *bin_name) -{ - char const *path = get_env_value(env, "PATH"); - char *dup_path = nullptr; - char *full_bin_path; - - if (path == nullptr) - path = DEFAULT_PATH; - full_bin_path = find_binary(path, bin_name, &dup_path); - if (full_bin_path == nullptr) - return nullptr; - free(dup_path); - return full_bin_path; -} diff --git a/bonus/path.h b/bonus/path.h deleted file mode 100644 index 5cbc6e3..0000000 --- a/bonus/path.h +++ /dev/null @@ -1,15 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef PATH_H - #define PATH_H - #include "env.h" - - #define DEFAULT_PATH "/usr/bin:." - -char *parse_full_bin_path(env_t *env, char *bin_name); -#endif diff --git a/bonus/readline.c b/bonus/readline.c deleted file mode 100644 index f6a845f..0000000 --- a/bonus/readline.c +++ /dev/null @@ -1,119 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "readline.h" -#include "debug.h" -#include "repl.h" -#include "u_str.h" - -static -bool str_printable(char const *str, size_t size) -{ - for (size_t i = 0; i < size; i++) - if (!isprint(str[i])) - return false; - return true; -} - -static -bool ensure_buff_av_capacity(buff_t *buff, size_t requested) -{ - char *new_str; - size_t endsize = BUFF_INIT_SZ; - - if ((buff->sz + requested) < buff->cap) - return true; - for (; endsize < buff->sz + requested; endsize <<= 1); - if (endsize > buff->cap) { - new_str = realloc(buff->str, (sizeof *buff->str) * endsize); - if (new_str == NULL) - return false; - buff->str = new_str; - buff->cap = endsize; - } - return true; -} - -static -bool ensure_buff_capacity(buff_t *buff) -{ - char *new_str; - - if (buff->str == NULL) { - new_str = malloc((sizeof *buff->str) * BUFF_INIT_SZ); - if (new_str == NULL) - return false; - buff->str = new_str; - buff->cap = BUFF_INIT_SZ; - } - if (buff->sz == buff->cap) { - new_str = realloc(buff->str, (sizeof *buff->str) * buff->cap << 1); - if (new_str == NULL) - return false; - buff->str = new_str; - buff->cap <<= 1; - } - return true; -} - -static -bool append_null_terminator(buff_t *buff, exec_ctx_t *exec_ctx) -{ - if (!ensure_buff_av_capacity(buff, 1)) - return false; - buff->str[buff->sz - 1] = '\0'; - buff->sz++; - if (isatty(exec_ctx->read_fd)) - WRITE_CONST(STDOUT_FILENO, "\n"); - return true; -} - -static -int8_t handle_line_buff(exec_ctx_t *exec_ctx, buff_t *buff, char *read_buff, - ssize_t read_size) -{ - if (handle_keys(exec_ctx, buff, read_buff)) - return RETURN_SUCCESS; - if (isatty(exec_ctx->read_fd) && str_printable(read_buff, read_size)) - write(STDOUT_FILENO, read_buff, read_size); - if (!ensure_buff_av_capacity(buff, read_size)) - return RETURN_FAILURE; - strncpy(buff->str + buff->sz, - read_buff, read_size); - buff->sz += read_size; - return -1; -} - -bool readline(exec_ctx_t *exec_ctx, buff_t *buff, int fd) -{ - char read_buff[2] = ""; - ssize_t read_size = 0; - - if (!ensure_buff_capacity(buff)) - return false; - while (strchr(read_buff, '\n') == NULL && *read_buff != '\r') { - memset(read_buff, '\0', sizeof read_buff); - read_size = read(fd, &read_buff, sizeof read_buff - 1); - if (read_size < 0) - return false; - if (read_size == 0) - return true; - if (handle_line_buff(exec_ctx, buff, read_buff, read_size) > -1) - return true; - } - return append_null_terminator(buff, exec_ctx); -} diff --git a/bonus/readline.h b/bonus/readline.h deleted file mode 100644 index ada2c11..0000000 --- a/bonus/readline.h +++ /dev/null @@ -1,17 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef READLINE - #define READLINE - #define BUFF_INIT_SZ 16 - #include - - #include "exec.h" - #include "u_str.h" - -bool readline(exec_ctx_t *exec_ctx, buff_t *buff, int fd); -#endif /* READLINE */ diff --git a/bonus/redirects.c b/bonus/redirects.c deleted file mode 100644 index ffe55b1..0000000 --- a/bonus/redirects.c +++ /dev/null @@ -1,91 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include -#include -#include - -#include "exec.h" -#include "u_str.h" - -#include "debug.h" - -bool handle_out_redirect(ef_t *ef, ast_t *node, size_t i, size_t sz) -{ - if (!(node->vector.tokens[i].type & (T_REDIRECT | T_APPEND))) - return true; - U_DEBUG("Redirect sz [%lu] i [%lu]\n", sz, i); - if (i + 1 >= sz || node->vector.tokens[i + 1].type != T_ARG) - return (WRITE_CONST(STDERR_FILENO, - "Missing name for redirect.\n"), false); - ef->skip_i = ef->skip_i ?: i; - ef->skip_sz += 2; - node->vector.tokens[i + 1].str[node->vector.tokens[i + 1].sz] = '\0'; - ef->rout_fd = open(node->vector.tokens[i + 1].str, O_CREAT | O_WRONLY | - (node->vector.tokens[i].type == T_APPEND ? O_APPEND : O_TRUNC), 0644); - if (ef->rout_fd < 0) - return (puterror(node->vector.tokens[i + 1].str), false); - ef->out_fd = ef->rout_fd; - return true; -} - -bool handle_in_redirect(ef_t *ef, ast_t *node, size_t i, size_t sz) -{ - if (node->vector.tokens[i].type != T_IN_REDIRECT) - return true; - if (i + 1 >= sz || node->vector.tokens[i + 1].type != T_ARG) - return (WRITE_CONST(STDERR_FILENO, - "Missing name for redirect.\n"), false); - ef->skip_i = ef->skip_i ?: i; - ef->skip_sz += 2; - node->vector.tokens[i + 1].str[node->vector.tokens[i + 1].sz] = '\0'; - ef->rin_fd = open(node->vector.tokens[i + 1].str, O_RDONLY); - if (ef->rin_fd < 0) - return (puterror(node->vector.tokens[i + 1].str), false); - ef->in_fd = ef->rin_fd; - return true; -} - -int handle_heredoc_loop(ast_t *node, size_t i) -{ - int fds[2]; - buff_t buffer = { .str = NULL }; - - if (pipe(fds) < 0) - return (puterror("pipe"), -1); - node->vector.tokens[i + 1].str[node->vector.tokens[i + 1].sz] = '\0'; - WRITE_CONST(STDOUT_FILENO, "? "); - while (getline(&buffer.str, &buffer.sz, stdin) != -1) { - buffer.str[u_strlen(buffer.str) - 1] = '\0'; - if (u_strcmp(buffer.str, node->vector.tokens[i + 1].str) == 0) - break; - write(fds[1], buffer.str, u_strlen(buffer.str)); - write(fds[1], "\n", 1); - WRITE_CONST(STDOUT_FILENO, "? "); - } - free(buffer.str); - close(fds[1]); - return fds[0]; -} - -bool handle_heredoc(ef_t *ef, ast_t *node, size_t i, size_t sz) -{ - if (node->vector.tokens[i].type != T_HEREDOC) - return true; - if (i + 1 >= sz || node->vector.tokens[i + 1].type != T_ARG) - return (WRITE_CONST(STDERR_FILENO, - "Missing name for redirect.\n"), false); - ef->skip_i = ef->skip_i ?: i; - ef->skip_sz += 2; - ef->in_fd = handle_heredoc_loop(node, i); - if (ef->in_fd == -1) - return false; - return true; -} diff --git a/bonus/redirects.h b/bonus/redirects.h deleted file mode 100644 index 9845802..0000000 --- a/bonus/redirects.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef REDIRECTS_H - #define REDIRECTS_H - #include - - #include "exec.h" - -bool handle_out_redirect(ef_t *ef, ast_t *node, size_t i, size_t sz); -bool handle_in_redirect(ef_t *ef, ast_t *node, size_t i, size_t sz); -int handle_heredoc_loop(ast_t *node, size_t i); -bool handle_heredoc(ef_t *ef, ast_t *node, size_t i, size_t sz); -#endif /* REDIRECTS_H */ diff --git a/bonus/repl.c b/bonus/repl.c deleted file mode 100644 index 71912e2..0000000 --- a/bonus/repl.c +++ /dev/null @@ -1,81 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include - -#include "common.h" -#include "exec.h" -#include "repl.h" -#include "u_str.h" -#include "vt100_esc_codes.h" - - -void print_shell_prompt(exec_ctx_t *exec_ctx) -{ - env_t *env_ptr = exec_ctx->env; - char const *ps1 = get_env_value(env_ptr, "PS1"); - char hostname[64]; - - if (ps1 == nullptr) { - if (gethostname(hostname, 64) < 0) - return; - printf(BLUE PROMPT_HEADER GREEN "%s" RESET "@" CYAN "%s" BLUE "] " - RESET "-" BLUE " [" RESET "%s" BLUE - "] " RESET "-" BLUE " [" YELLOW "%d" BLUE - "]\n└─[" PURPLE "$" BLUE "] " RESET, - get_env_value(env_ptr, "USER"), - hostname, - get_env_value(env_ptr, "PWD"), - exec_ctx->history_command->sz); - } else - printf("%s", ps1); -} - -void init_shell_repl(exec_ctx_t *exec_ctx) -{ - struct termios repl_settings; - - tcgetattr(STDIN_FILENO, &repl_settings); - exec_ctx->saved_term_settings = repl_settings; - exec_ctx->is_running = true; - if (isatty(exec_ctx->read_fd)) { - setvbuf(stdout, nullptr, _IONBF, 0); - signal(SIGINT, SIG_IGN); - WRITE_CONST(STDOUT_FILENO, BLINKING_VERTICAL_CURSOR); - repl_settings.c_iflag = IXON; - repl_settings.c_lflag = ~(ECHO | ICANON); - tcsetattr(STDIN_FILENO, TCSANOW, &repl_settings); - } -} - -void restore_term_flags(exec_ctx_t *exec_ctx) -{ - tcsetattr(STDIN_FILENO, TCSANOW, &exec_ctx->saved_term_settings); -} - -void ignore_sigint(exec_ctx_t *exec_ctx) -{ - WRITE_CONST(STDIN_FILENO, "\n"); - print_shell_prompt(exec_ctx); -} - -bool handle_keys(exec_ctx_t *exec_ctx, buff_t *buff, char const *read_buff) -{ - switch (*read_buff) { - case CTRL('d'): - buff->sz = 0; - return true; - case CTRL('c'): - ignore_sigint(exec_ctx); - return false; - default: - return false; - } -} diff --git a/bonus/repl.h b/bonus/repl.h deleted file mode 100644 index 655fe5a..0000000 --- a/bonus/repl.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef REPL_H - #define REPL_H - #include "exec.h" - #include "u_str.h" - -void init_shell_repl(exec_ctx_t *exec_ctx); -void restore_term_flags(exec_ctx_t *exec_ctx); -bool handle_keys(exec_ctx_t *exec_ctx, buff_t *buff, char const *read_buff); -void print_shell_prompt(exec_ctx_t *exec_ctx); -void ignore_sigint(exec_ctx_t *exec_ctx); -#endif /* REPL_H */ diff --git a/bonus/shell.c b/bonus/shell.c deleted file mode 100644 index 8d58439..0000000 --- a/bonus/shell.c +++ /dev/null @@ -1,151 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include -#include - -#include "common.h" -#include "ctx.h" -#include "debug.h" -#include "env.h" -#include "history.h" -#include "job.h" -#include "local.h" -#include "readline.h" -#include "repl.h" -#include "shell.h" -#include "u_str.h" -#include "utils.h" - -static -void check_basic_error(char const *buffer) -{ - if (buffer == NULL) - return; - if (*buffer == '|') - WRITE_CONST(STDERR_FILENO, "Invalid null command.\n"); - if (*buffer == '>' || *buffer == '<') - WRITE_CONST(STDERR_FILENO, "Missing name for redirect.\n"); -} - -static -void write_prompt(int is_a_tty, exec_ctx_t *exec_ctx) -{ - if (is_a_tty) - print_shell_prompt(exec_ctx); -} - -static -bool change_shell_command(buff_t *buff, exec_ctx_t *exec_ctx) -{ - char *tmp_buff = nullptr; - size_t buffer_len; - - buff->sz = 0; - if (!readline(exec_ctx, buff, exec_ctx->read_fd)) - return false; - if (!buff->sz) - return false; - tmp_buff = buff->str; - buffer_len = update_command(&tmp_buff, &buff->sz, exec_ctx); - if (buffer_len == 0) - return true; - if (buffer_len < 1 || !u_str_is_alnum(tmp_buff)) - return check_basic_error(tmp_buff), true; - U_DEBUG("Buffer [%lu] [%s]\n", buffer_len, tmp_buff); - if (visitor(tmp_buff, exec_ctx) == RETURN_FAILURE - && !exec_ctx->history->last_exit_code) - exec_ctx->history->last_exit_code = RETURN_FAILURE; - return true; -} - -static -int shell_loop(int is_a_tty, exec_ctx_t *exec_ctx) -{ - buff_t buff = { .str = nullptr, 0, .cap = BUFF_INIT_SZ }; - - init_shell_repl(exec_ctx); - if (exec_ctx->opt->cmd != nullptr) - return visitor(exec_ctx->opt->cmd, exec_ctx); - while (true) { - write_prompt(is_a_tty, exec_ctx); - if (!change_shell_command(&buff, exec_ctx)) - return exec_ctx->history->last_exit_code; - } - return free(buff.str), exec_ctx->history->last_exit_code; -} - -static -his_command_t *init_cmd_history(void) -{ - his_command_t *cmd_history = malloc(sizeof(his_command_t) * 100); - - if (cmd_history == NULL) - return nullptr; - for (int i = 0; i < 100; i++){ - cmd_history[i].arg = nullptr; - cmd_history[i].command = nullptr; - cmd_history[i].id = i; - } - cmd_history->sz = 0; - return cmd_history; -} - -static -bool error_in_init(exec_ctx_t *exec_ctx) -{ - if (!exec_ctx->history_command || !exec_ctx->env->env - || !exec_ctx->alias->alias_array || - !exec_ctx->alias->alias_to_replace) { - free(exec_ctx->alias->alias_array); - free(exec_ctx->alias->alias_to_replace); - free(exec_ctx->history_command); - free(exec_ctx->env->env); - return true; - } - return false; -} - -static -int get_read_fd(opt_t *opt) -{ - int fd; - - if (opt->script_file == NULL) - return STDIN_FILENO; - fd = open(opt->script_file, O_RDONLY); - if (fd < 0) - return perror(opt->script_file), -1; - return fd; -} - -int shell(opt_t *opt, char **env_ptr) -{ - alias_t alias = init_alias(); - env_t env = parse_env(env_ptr); - history_t history = { .cmd_history = nullptr, .last_exit_code = 0, - .last_chdir = nullptr}; - his_command_t *cmd_history = init_cmd_history(); - local_t local = create_local(); - exec_ctx_t exec_ctx = {.env = &env, .local = &local, .opt = opt, - .read_fd = get_read_fd(opt), .history = &history, - .history_command = cmd_history, .alias = &alias}; - int shell_result; - - if (exec_ctx.read_fd == -1 || (int)error_in_init(&exec_ctx) - || !(int)init_jobs(&exec_ctx)) - return RETURN_FAILURE; - shell_result = shell_loop(isatty(exec_ctx.read_fd), &exec_ctx); - if (opt->cmd == NULL && isatty(exec_ctx.read_fd)) { - WRITE_CONST(STDOUT_FILENO, "exit\n"); - restore_term_flags(&exec_ctx); - } - return free_everything(&exec_ctx), shell_result; -} diff --git a/bonus/shell.h b/bonus/shell.h deleted file mode 100644 index eea4258..0000000 --- a/bonus/shell.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef SHELL_H - #define SHELL_H - #include "common.h" - -typedef struct { - char **cmd_history; - int last_exit_code; - char *last_chdir; -} history_t; - -int shell(opt_t *opt, char **env); -#endif /* SHELL_H */ diff --git a/bonus/update_command.c b/bonus/update_command.c deleted file mode 100644 index 15ea8e1..0000000 --- a/bonus/update_command.c +++ /dev/null @@ -1,53 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** update_command -*/ - -#include "common.h" -#include "ctx.h" -#include "history.h" -#include "u_str.h" - -static -int check_cmd(char *cmd) -{ - if (!cmd) - return 84; - for (int i = 0; cmd[i] != 0; i++) - if (cmd[i] == CHAR_HIST && - (cmd[i + 1] != ' ' && cmd[i + 1] != '\t' - && cmd[i + 1] != '\0')) - return 84; - return 0; -} - -his_command_t *save_command(char *cmd, his_command_t *cmd_history) -{ - if (check_cmd(cmd) == 84) - return cmd_history; - if (cmd_history->sz < 100) { - cmd_history[cmd_history->sz] = set_cmd(cmd, - cmd_history[cmd_history->sz]); - } - cmd_history->sz++; - return cmd_history; -} - -size_t update_command(char **buffer, - size_t *buffer_sz, exec_ctx_t *exec_ctx) -{ - size_t buffer_len = 0; - - buffer_len = u_strlen(*buffer); - if (buffer_len < 2) - return RETURN_FAILURE; - if (parse_history(buffer, &buffer_len, - buffer_sz, &exec_ctx->history_command) == 84) - return RETURN_SUCCESS; - parse_alias(buffer, &buffer_len, exec_ctx->alias); - exec_ctx->history_command = save_command(*buffer, - exec_ctx->history_command); - return buffer_len; -} diff --git a/bonus/utils.h b/bonus/utils.h deleted file mode 100644 index 703c7cb..0000000 --- a/bonus/utils.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - - -#ifndef UTILS_H - #define UTILS_H - #include "history.h" - #include "exec.h" - -char *strn_to_ndup(int start, int size, char *str); -bool is_a_token(char *str, int index_str); -char *cat_in_str(his_variable_t *his_variable, char *str, char *cpy); -int len_array(char **array); -char *insert_str(const char *base, const char *insert, size_t pos); -void free_everything(exec_ctx_t *exec_ctx); -#endif /* UTILS_H */ diff --git a/bonus/utils/cat_in_str.c b/bonus/utils/cat_in_str.c deleted file mode 100644 index c1379e2..0000000 --- a/bonus/utils/cat_in_str.c +++ /dev/null @@ -1,43 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** cat_in_str -*/ -#include "history.h" -#include -#include - -static -int insert_in_str(char *dest, char *cpy, int start) -{ - for (int j = 0; cpy[j] != '\0'; j++){ - dest[start] = cpy[j]; - start++; - } - return start; -} - -char *cat_in_str(his_variable_t *his_variable, char *str, char *cpy) -{ - int i = 0; - int len_str = strlen(str); - int size_right = len_str - - his_variable->coord_variable - his_variable->size_variable; - int size_left = (len_str - size_right) - his_variable->size_variable; - char *new_str = malloc(sizeof(char) * - (size_right + size_left + strlen(cpy) + 2)); - - if (new_str == NULL) - return NULL; - for (; i < size_left; i++) - new_str[i] = str[i]; - i = insert_in_str(new_str, cpy, i); - for (int k = 0; k < size_right; k++){ - new_str[i] = str[k + size_left + his_variable->size_variable]; - i++; - } - new_str[i] = '\0'; - new_str[i + 1] = '\0'; - return new_str; -} diff --git a/bonus/utils/free.c b/bonus/utils/free.c deleted file mode 100644 index d448768..0000000 --- a/bonus/utils/free.c +++ /dev/null @@ -1,17 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include - -#include "exec.h" - -void free_everything(exec_ctx_t *exec_ctx) -{ - free_env(exec_ctx->env); - free_alias(exec_ctx->alias); - free(exec_ctx->history_command); -} diff --git a/bonus/utils/insert_str.c b/bonus/utils/insert_str.c deleted file mode 100644 index baf6f51..0000000 --- a/bonus/utils/insert_str.c +++ /dev/null @@ -1,29 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include - -char *insert_str(const char *base, const char *insert, size_t pos) -{ - size_t base_len = strlen(base); - size_t insert_len = strlen(insert); - size_t new_len; - char *res; - - if (pos >= base_len) - pos = base_len; - new_len = base_len - 1 + insert_len; - res = malloc(sizeof(char) * (new_len + 1)); - if (res == nullptr) - return nullptr; - memcpy(res, base, pos); - strncpy(res + pos, insert, insert_len); - memcpy(res + pos + insert_len, base + pos + 1, base_len - pos - 1 + 1); - return res; -} diff --git a/bonus/utils/is_a_token.c b/bonus/utils/is_a_token.c deleted file mode 100644 index 2f68e37..0000000 --- a/bonus/utils/is_a_token.c +++ /dev/null @@ -1,20 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** is_a_token -*/ -#include "string.h" -#include "u_str.h" -#include "ast.h" - -bool is_a_token(char *str, int index_str) -{ - str += index_str; - for (size_t i = 0; i < 16; i++) { - if (strncmp(str, TOKENS_LIST[i].str, TOKENS_LIST[i].sz) == 0){ - return true; - } - } - return false; -} diff --git a/bonus/utils/len_array.c b/bonus/utils/len_array.c deleted file mode 100644 index 7c9d807..0000000 --- a/bonus/utils/len_array.c +++ /dev/null @@ -1,17 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** len_array -*/ - -#include - -int len_array(char **array) -{ - int i = 0; - - while (array[i] != NULL) - i++; - return i; -} diff --git a/bonus/utils/strn_to_ndup.c b/bonus/utils/strn_to_ndup.c deleted file mode 100644 index 29f2379..0000000 --- a/bonus/utils/strn_to_ndup.c +++ /dev/null @@ -1,22 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** 42sh -** File description: -** strn_to_ndup -*/ -#include - -char *strn_to_ndup(int start, int size, char *str) -{ - char *new_str = malloc(sizeof(char) * (size + 1)); - int count = 0; - - if (new_str == NULL) - return NULL; - new_str[size] = '\0'; - for (int i = start; i != start + size; i++){ - new_str[count] = str[i]; - count++; - } - return new_str; -} diff --git a/bonus/visit_condition.c b/bonus/visit_condition.c deleted file mode 100644 index fcf78fa..0000000 --- a/bonus/visit_condition.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include - -#include "ast.h" -#include "common.h" -#include "debug.h" -#include "exec.h" -#include "u_str.h" -#include "visitor.h" - -int visit_and(ef_t *ef, ast_t *node) -{ - int result = RETURN_FAILURE; - - if (!node->binary.left || !node->binary.right) - return WRITE_CONST(STDERR_FILENO, "Invalid null l/r command.\n"), - RETURN_FAILURE; - result = visit_condition(ef, node->binary.left); - if (!result) - result = visit_condition(ef, node->binary.right); - return result; -} - -int visit_or(ef_t *ef, ast_t *node) -{ - int result = RETURN_FAILURE; - - if (!node->binary.left || !node->binary.right) - return WRITE_CONST(STDERR_FILENO, "Invalid null l/r command.\n"), - RETURN_FAILURE; - result = visit_condition(ef, node->binary.left); - if (result) { - ef->history->last_exit_code = 0; - result = visit_condition(ef, node->binary.right); - } - return result; -} - -static -int visit_then(ef_t *ef, ast_t *node) -{ - int result = RETURN_FAILURE; - - for (size_t i = 0; i < node->cond.sz; i++) - result = visit_expression(ef, node->cond.nodes[i]); - return result; -} - -static -int visit_else(ef_t *ef, ast_t *node) -{ - int result = RETURN_FAILURE; - - for (size_t i = 0; i < node->cond.sz2; i++) - result = visit_expression(ef, node->cond.nodes2[i]); - return result; -} - -int visit_if(ef_t *ef, ast_t *node) -{ - int result = RETURN_FAILURE; - - if (node->cond.sz < 1) - return WRITE_CONST(STDERR_FILENO, "Empty if.\n"), - RETURN_FAILURE; - result = visit_expression(ef, node->cond.exp); - U_DEBUG("If exp result [%d]\n", result); - if (result == RETURN_FAILURE) - return visit_else(ef, node); - return visit_then(ef, node); -} diff --git a/bonus/visitor.c b/bonus/visitor.c deleted file mode 100644 index 4c4217a..0000000 --- a/bonus/visitor.c +++ /dev/null @@ -1,206 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#include -#include -#include -#include - -#include "ast.h" -#include "builtins.h" -#include "common.h" -#include "exec.h" -#include "redirects.h" -#include "u_str.h" -#include "visitor.h" - -#include "debug.h" - -/* - * ef->in_fd = ef->pin_fd; - * ef->out_fd = ef->out_fd; - * set used fds, to not close the wrong fd in visit pipe or handle redirect -*/ -static -int visit_cmd(ef_t *ef) -{ - int result; - - ef->in_fd = ef->pin_fd; - ef->out_fd = ef->pout_fd; - ef->skip_i = 0; - ef->skip_sz = 0; - ef->rout_fd = 0; - ef->rin_fd = 0; - for (size_t i = 0; i < ef->act_node->vector.sz; i++) { - if (!handle_in_redirect(ef, ef->act_node, i, ef->act_node->vector.sz) - || !handle_out_redirect(ef, ef->act_node, i, ef->act_node->vector.sz) - || !handle_heredoc(ef, ef->act_node, i, ef->act_node->vector.sz)) - return -1; - } - result = execute(ef); - if (ef->rout_fd) - close(ef->rout_fd); - if (ef->rin_fd) - close(ef->rin_fd); - return result; -} - -static -int visit_pipe(ef_t *ef, size_t i, ast_t *node) -{ - int result = RETURN_FAILURE; - - if (i < node->list.sz - 1) - if (pipe(ef->pipes) < 0) - return (puterror("pipe"), -1); - ef->pout_fd = i == node->list.sz - 1 ? STDOUT_FILENO : ef->pipes[1]; - ef->act_node = node->list.nodes[i]; - if (!ef->act_node) - return -1; - result = visit_cmd(ef); - if (result == -1) - return RETURN_FAILURE; - if (ef->pin_fd != STDIN_FILENO) - close(ef->pin_fd); - if (i < node->list.sz - 1) { - close(ef->pipes[1]); - ef->pin_fd = ef->pipes[0]; - } - return result; -} - -static -int visit_pipes(ef_t *ef) -{ - ast_t *node = ef->act_node; - int result = RETURN_FAILURE; - - ef->p_i = 0; - ef->p_sz = node->list.sz; - ef->pin_fd = STDIN_FILENO; - ef->flags |= F_PIPE; - for (size_t i = 0; i < node->list.sz; i++) { - ef->p_i = i; - result = visit_pipe(ef, i, node); - if (result == -1) - break; - } - return result; -} - -int visit_list(ef_t *ef, ast_t *node) -{ - int result = RETURN_FAILURE; - - if (node->type == N_CMD) { - ef->act_node = node; - return visit_cmd(ef); - } - if (node->tok.type == T_PIPE) { - ef->act_node = node; - return visit_pipes(ef); - } - return result; -} - -int visit_condition(ef_t *ef, ast_t *node) -{ - switch (node->tok.type) { - case T_AND: - return visit_and(ef, node); - case T_OR: - return visit_or(ef, node); - default: - return visit_list(ef, node); - } -} - -static -int visit_semi(ef_t *ef, ast_t *node) -{ - int result = RETURN_FAILURE; - - for (size_t i = 0; i < node->list.sz; i++) { - ef->flags &= ~F_PIPE; - ef->act_node = node->list.nodes[i]; - if (node->list.nodes[i]->tok.type & (T_AND | T_OR)) - result = visit_condition(ef, node->list.nodes[i]); - if (node->list.nodes[i]->type == N_LST) - result = visit_list(ef, node->list.nodes[i]); - ef->pin_fd = STDIN_FILENO; - ef->pout_fd = STDOUT_FILENO; - if (node->list.nodes[i]->type == N_CMD) - result = visit_cmd(ef); - } - return result; -} - -int visit_expression(ef_t *ef, ast_t *node) -{ - int result = RETURN_FAILURE; - - if (node->tok.type & (T_SEMICOLON | T_NEWLINE)) - result = visit_semi(ef, node); - if (node->tok.type & (T_AND | T_OR)) - result = visit_condition(ef, node); - if (node->tok.type == T_PIPE) - result = visit_list(ef, node); - if (node->type == N_CMD) { - ef->act_node = node; - result = visit_cmd(ef); - } - return result; -} - -//TODO: visit loop befor a visit list with a loop -static -int visitor_launcher(ef_t *ef) -{ - ef->ctx->ast = parse_expression(ef->ctx); - if (ef->ctx->ast == NULL) - return RETURN_FAILURE; - U_DEBUG_CALL(print_ast, ef->ctx->ast, ef->ctx, 0); - return visit_expression(ef, ef->ctx->ast); -} - -static -void remove_trailing_semi(char *str) -{ - for (size_t len = u_strlen(str); len > 0; len--) { - if (str[len] != '\0' && str[len] != '\n' && str[len] != ';') - break; - if (str[len] == ';') - str[len] = '\0'; - if (str[len] == '\n') - str[len] = '\0'; - } -} - -int visitor(char *buffer, exec_ctx_t *exec_ctx) -{ - ast_ctx_t ctx = { 0, .str = buffer, - .cap = u_strlen(buffer) + 10 + DEFAULT_AST_CAP, - .ast = malloc(sizeof *ctx.ast * - (u_strlen(buffer) + 10 + DEFAULT_AST_CAP)), .parsed_tok = 0 }; - ef_t ef = { .buffer = buffer, .env = exec_ctx->env, - .history = exec_ctx->history, .ctx - = &ctx, .pout_fd = STDOUT_FILENO, .flags = 0, - .exec_ctx = exec_ctx}; - int result = RETURN_FAILURE; - - ctx.first_node = ctx.ast; - remove_trailing_semi(ctx.str); - exec_ctx->history->last_exit_code = 0; - if (ctx.ast == NULL) - return RETURN_FAILURE; - result = visitor_launcher(&ef); - if (ef.flags & F_EXIT) - builtins_exit(&ef, nullptr); - free_ast(&ctx); - return result == -1 ? RETURN_FAILURE : result; -} diff --git a/bonus/visitor.h b/bonus/visitor.h deleted file mode 100644 index e9fc0db..0000000 --- a/bonus/visitor.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef VISITOR_H - #define VISITOR_H - #include "ast.h" - #include "exec.h" - - -// Main -int visit_expression(ef_t *ef, ast_t *node); - - -// List (pipe, ...) -int visit_list(ef_t *ef, ast_t *node); - -// Conditions -int visit_if(ef_t *ef, ast_t *node); -int visit_and(ef_t *ef, ast_t *node); -int visit_or(ef_t *ef, ast_t *node); -int visit_condition(ef_t *ef, ast_t *node); -#endif /* VISITOR_H */ diff --git a/bonus/vt100_esc_codes.h b/bonus/vt100_esc_codes.h deleted file mode 100644 index 24dd8f3..0000000 --- a/bonus/vt100_esc_codes.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -** EPITECH PROJECT, 2025 -** __ -** File description: -** _ -*/ - -#ifndef CR_VT100_ESC_CODES_H - #define CR_VT100_ESC_CODES_H - - #define ESC "\033" - #define CFMT(n) ESC "[" #n "m" - - // special - #define BLINKING_VERTICAL_CURSOR ESC "[5 q" - - // move - #define MOVE_RIGHT(n) ESC "[" #n "C" - - // colors - #define RESET CFMT(0) - #define BOLD CFMT(1) - - #define RED CFMT(31) - #define GREEN CFMT(32) - #define YELLOW CFMT(33) - #define BLUE CFMT(34) - #define PURPLE CFMT(35) - #define CYAN CFMT(36) -#endif diff --git a/src/handle_vars.c b/src/handle_vars.c index a4257f8..7f41857 100644 --- a/src/handle_vars.c +++ b/src/handle_vars.c @@ -158,6 +158,7 @@ bool check_for_closable(ast_t *node, exec_ctx_t *ctx, size_t *i, args_t *args) void handle_var_case(ast_t *node, exec_ctx_t *ctx, size_t *i, args_t *args) { + args->args[args->sz] = nullptr; if (check_for_closable(node, ctx, i, args)) return; handle_var(node, i, ctx, args); diff --git a/src/readline.c b/src/readline.c index e3c764b..b46614a 100644 --- a/src/readline.c +++ b/src/readline.c @@ -14,10 +14,10 @@ #include #include -#include "debug.h" #include "readline.h" #include "repl.h" #include "u_str.h" +#include "vt100_esc_codes.h" bool ensure_buff_av_capacity(buff_t *buff, size_t requested) { @@ -96,18 +96,12 @@ void write_buff(readline_helper_t *rh) write(STDOUT_FILENO, move_back, strlen(move_back)); } -void refresh_line(readline_helper_t *rh) +static +void print_buff(readline_helper_t *rh) { size_t target = rh->cursor + rh->ec->prompt_len; char move_cursor[32]; - if (!rh->ec->isatty) - return; - append_null_terminator(rh->out); - if (rh->out->sz > 1 && *rh->cpy == '\n') { - WRITE_CONST(STDOUT_FILENO, "\n"); - return; - } WRITE_CONST(STDOUT_FILENO, "\r"); if (rh->ec->prompt_len > 0) print_second_shell_prompt(rh->ec); @@ -117,6 +111,22 @@ void refresh_line(readline_helper_t *rh) write(STDOUT_FILENO, move_cursor, strlen(move_cursor)); } +void refresh_line(readline_helper_t *rh) +{ + if (!rh->ec->isatty) + return; + append_null_terminator(rh->out); + if (rh->cursor + rh->ec->prompt_len > rh->winsz.ws_col) { + write(STDOUT_FILENO, rh->out->str + rh->cursor - 1, 1); + return; + } + if (rh->out->sz > 1 && *rh->cpy == '\n') { + WRITE_CONST(STDOUT_FILENO, "\n"); + return; + } + print_buff(rh); +} + static bool populate_copy_buff( readline_helper_t *rh, ssize_t rd, @@ -150,6 +160,8 @@ bool read_until_line_ending( text_parse_info_t tpi; for (;;) { + if (ec->isatty) + ioctl(STDOUT_FILENO, TIOCGWINSZ, &rh->winsz); memset(&tpi, '\0', sizeof tpi); if (!ensure_buff_av_capacity(rh->out, BULK_READ_BUFF_SZ)) return false; @@ -174,6 +186,8 @@ bool readline(exec_ctx_t *ec, buff_t *out) bool is_empty = true; ssize_t rd = 0; + if (ec->isatty) + ioctl(STDOUT_FILENO, TIOCGWINSZ, &rh.winsz); for (size_t i = 0; i < sizeof read_buff; i++) is_empty &= read_buff[i] == '\0'; if (is_empty) { diff --git a/src/readline.h b/src/readline.h index d2f4b39..5712c16 100644 --- a/src/readline.h +++ b/src/readline.h @@ -8,6 +8,7 @@ #ifndef READLINE #define READLINE #include + #include #include "builtins_handler.h" #include "u_str.h" @@ -22,6 +23,7 @@ typedef struct { char cpy[BULK_READ_BUFF_SZ]; size_t cursor; int history_idx; + struct winsize winsz; } readline_helper_t; typedef struct {