diff --git a/Makefile b/Makefile index 22fcba6..f3a87c1 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ LIB_NAME := libu.a SRC := $(wildcard src/*.c) SRC += $(wildcard src/builtins/*.c) +SRC += $(wildcard src/utils/*.c) LIB_SRC := $(wildcard ulib/*.c) LIB_SRC += $(wildcard ulib/write/printf/*.c) diff --git a/src/ast.h b/src/ast.h index 8caa200..94e1c96 100644 --- a/src/ast.h +++ b/src/ast.h @@ -9,9 +9,8 @@ #define AST_H #include #include - #include "shell.h" - #include "env.h" + #include "builtins_handler.h" #define DEFAULT_AST_CAP 128 #define T_ALL 0xff @@ -96,7 +95,7 @@ extern const tokens_list_t TOKENS_LIST[]; ast_t *parse_expression(ast_ctx_t *ctx); void print_ast(ast_ctx_t *ctx, ast_t *ast, size_t depth); token_t get_next_token(ast_ctx_t *ctx); -int visitor(char *buffer, env_t *env, history_t *history); +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); diff --git a/src/builtins.h b/src/builtins.h index 1e44fcb..2ee4fb0 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -13,9 +13,9 @@ typedef struct { char const *name; int (*ptr)(ef_t *ef, char **args); -} builtins_t; +} builtins_funcs_t; -extern const builtins_t BUILTINS[]; +extern const builtins_funcs_t BUILTINS[]; extern const size_t BUILTINS_SZ; int builtins_exit(ef_t *ef, char **args); @@ -25,4 +25,5 @@ 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); #endif /* BUILTIND_H */ diff --git a/src/builtins/builtin_history.c b/src/builtins/builtin_history.c new file mode 100644 index 0000000..39421e0 --- /dev/null +++ b/src/builtins/builtin_history.c @@ -0,0 +1,176 @@ +/* +** EPITECH PROJECT, 2025 +** history_42sh +** File description: +** builtin_history +*/ + +#include +#include + +#include "history.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 +*/ + +#include +#include "utils.h" +#include +#include +#include + +static char *concat_cmd_arg(char *dest, char *src) +{ + int l; + int i; + char *r_value = NULL; + + if (!src) { + r_value = u_strdup(dest); + return r_value; + } else { + 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 = NULL; + char *new_str = NULL; + + if (his_command->sz == 0){ + printf("%d: Event not found\n", his_command->sz); + return NULL; + } + 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); + free(new_line); + free(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 = NULL; + + for (int i = his_command->sz - 1; i > 0; i--) { + if (his_command[i].command == NULL) { + printf("%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; + } + } + printf("%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 = NULL; + + if (id < 0 || id > 100 || his_command[id].command == NULL){ + printf("%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 = NULL; + int last_space = 0; + int x = 0; + + if (!str) + return NULL; + 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 = NULL; + char *new_str = NULL; + + 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 NULL; + 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 = NULL; + char *new_str = NULL; + + 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/src/builtins/cd.c b/src/builtins/cd.c index d5e0b14..f888618 100644 --- a/src/builtins/cd.c +++ b/src/builtins/cd.c @@ -62,17 +62,17 @@ int builtins_cd_chdir(ef_t *ef, char **args, char *path) { char *act_pwd; - if (ef->history->last_chdir != NULL && args[1] != NULL + if (ef->exec_ctx->history->last_chdir != NULL && args[1] != NULL && u_strcmp(args[1], "-") == 0) - path = ef->history->last_chdir; + 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->history->last_chdir); - ef->history->last_chdir = act_pwd; + free(ef->exec_ctx->history->last_chdir); + ef->exec_ctx->history->last_chdir = act_pwd; return RETURN_SUCCESS; } diff --git a/src/builtins/exit.c b/src/builtins/exit.c index b7bd6b2..881909a 100644 --- a/src/builtins/exit.c +++ b/src/builtins/exit.c @@ -23,5 +23,5 @@ int builtins_exit(ef_t *ef, char **args __attribute__((unused))) } free_env(ef->env); free(ef->buffer); - exit(ef->history->last_exit_code); + exit(ef->exec_ctx->history->last_exit_code); } diff --git a/src/builtins/history.c b/src/builtins/history.c new file mode 100644 index 0000000..ccc1754 --- /dev/null +++ b/src/builtins/history.c @@ -0,0 +1,25 @@ +/* +** EPITECH PROJECT, 2025 +** 42sh +** File description: +** history +*/ + +#include +#include "common.h" +#include "env.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/src/builtins_handler.h b/src/builtins_handler.h new file mode 100644 index 0000000..a47f2dc --- /dev/null +++ b/src/builtins_handler.h @@ -0,0 +1,23 @@ +/* +** EPITECH PROJECT, 2025 +** __ +** File description: +** _ +*/ + + +#ifndef BUILTINS_HANDLER_H + #define BUILTINS_HANDLER_H + #include "env.h" + #include "history.h" + #include "shell.h" + +typedef struct { + env_t *env; + history_t *history; + his_command_t *history_command; +} 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/src/exec.c b/src/exec.c index 716b042..65f042f 100644 --- a/src/exec.c +++ b/src/exec.c @@ -23,7 +23,7 @@ #include "u_mem.h" #include "u_str.h" -const builtins_t BUILTINS[] = { +const builtins_funcs_t BUILTINS[] = { { "builtins", &builtins_builtins }, { "cd", &builtins_cd }, { "chdir", &builtins_cd }, @@ -32,7 +32,8 @@ const builtins_t BUILTINS[] = { { "setenv", &builtins_setenv }, { "unsetenv", &builtins_unsetenv }, { ":", &builtins_funny_double_dot }, - { "exit", &builtins_exit } + { "exit", &builtins_exit }, + { "history", &builtins_history} }; const size_t BUILTINS_SZ = sizeof BUILTINS / sizeof *BUILTINS; @@ -137,8 +138,8 @@ int launch_bin(char *full_bin_path, char **args, ef_t *ef) else waitpid(pid, &status, WNOHANG); if (WIFEXITED(status)) - ef->history->last_exit_code = - ef->history->last_exit_code ?: WEXITSTATUS(status); + ef->exec_ctx->history->last_exit_code = + ef->exec_ctx->history->last_exit_code ?: WEXITSTATUS(status); return status; } @@ -171,7 +172,7 @@ bool builtins_launcher(ef_t *ef, char **args) if (u_strlen(BUILTINS[i].name) != bin_l) continue; if (u_strcmp(BUILTINS[i].name, args[0]) == 0) { - ef->history->last_exit_code = + ef->exec_ctx->history->last_exit_code = BUILTINS[i].ptr(ef, args); return true; } @@ -199,5 +200,6 @@ int execute(ef_t *ef) U_DEBUG("Exit code [%d]\n", ef->history->last_exit_code); free(full_bin_path); free((void *)args); - return ef->history->last_exit_code != 0 ? RETURN_FAILURE : RETURN_SUCCESS; + return ef->exec_ctx->history->last_exit_code + != 0 ? RETURN_FAILURE : RETURN_SUCCESS; } diff --git a/src/exec.h b/src/exec.h index 68fc9d6..4bb4a2c 100644 --- a/src/exec.h +++ b/src/exec.h @@ -43,6 +43,7 @@ typedef struct { int pout_fd; int in_fd; int out_fd; + exec_ctx_t *exec_ctx; } ef_t; __attribute__((nonnull)) diff --git a/src/history.h b/src/history.h new file mode 100644 index 0000000..ac2eabe --- /dev/null +++ b/src/history.h @@ -0,0 +1,54 @@ +/* +** 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 *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/src/init_history.c b/src/init_history.c new file mode 100644 index 0000000..614db37 --- /dev/null +++ b/src/init_history.c @@ -0,0 +1,46 @@ +/* +** 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/src/parse_history.c b/src/parse_history.c new file mode 100644 index 0000000..350d9c8 --- /dev/null +++ b/src/parse_history.c @@ -0,0 +1,131 @@ +/* +** EPITECH PROJECT, 2025 +** history_42sh +** File description: +** his for history +*/ +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "common.h" +#include "env.h" +#include "exec.h" +#include "u_mem.h" +#include "u_str.h" +#include "history.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; + } + 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); + 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/src/shell.c b/src/shell.c index 411b628..62751d3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -15,6 +15,7 @@ #include "common.h" #include "debug.h" #include "env.h" +#include "history.h" #include "shell.h" #include "u_str.h" @@ -32,6 +33,8 @@ void debug_env_entries(env_t *env) 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 == '<') @@ -46,40 +49,83 @@ void ignore_sigint(int sig __attribute__((unused))) } static -int shell_loop(env_t *env, int is_a_tty, history_t *history) +void write_prompt(int is_a_tty) +{ + if (is_a_tty) + WRITE_CONST(STDOUT_FILENO, SHELL_PROMPT); +} + +/* +** Noeud de fonction +** Pour changer la commande +** passer en parametre +** si besoin +*/ +static +int shell_loop(int is_a_tty, exec_ctx_t *exec_ctx) { char *buffer = NULL; - size_t buffer_sz; - size_t buffer_len; + size_t buffer_sz = 0; + size_t buffer_len = 0; while (true) { - if (is_a_tty) - WRITE_CONST(STDOUT_FILENO, SHELL_PROMPT); + write_prompt(is_a_tty); if (getline(&buffer, &buffer_sz, stdin) == -1) break; - buffer_len = u_strlen(buffer); - if (buffer_len < 2 || !u_str_is_alnum(buffer)) { + buffer_len = update_command(&buffer, &buffer_sz, exec_ctx); + if (buffer_len < 1 || !u_str_is_alnum(buffer)) { check_basic_error(buffer); continue; } - buffer[buffer_len - 1] = '\0'; U_DEBUG("Buffer [%lu] [%s]\n", buffer_len, buffer); - visitor(buffer, env, history); + visitor(buffer, exec_ctx); + free(buffer); } - return (free(buffer), history->last_exit_code); + free(exec_ctx->history_command); + return (free(buffer), exec_ctx->history->last_exit_code); +} + +his_command_t *init_cmd_history(void) +{ + his_command_t *cmd_history = malloc(sizeof(his_command_t) * 100); + + if (cmd_history == NULL) + return NULL; + for (int i = 0; i != 100; i++){ + cmd_history[i].arg = NULL; + cmd_history[i].command = NULL; + 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) { + free(exec_ctx->history_command); + free(exec_ctx->env->env); + return true; + } + return false; } int shell(char **env_ptr) { env_t env = parse_env(env_ptr); - history_t history = { .cmd_history = NULL, 0, .last_chdir = NULL }; + history_t history = { .cmd_history = NULL, 0, .last_chdir = NULL}; + his_command_t *cmd_history = init_cmd_history(); + exec_ctx_t exec_ctx = {.env = &env, + .history = &history, .history_command = cmd_history }; int shell_result; - if (!env.env) + if (error_in_init(&exec_ctx) == true){ return RETURN_FAILURE; + } U_DEBUG_CALL(debug_env_entries, &env); signal(SIGINT, ignore_sigint); - shell_result = shell_loop(&env, isatty(STDIN_FILENO), &history); - free_env(&env); + shell_result = shell_loop(isatty(STDIN_FILENO), &exec_ctx); + free_env(exec_ctx.env); return shell_result; } diff --git a/src/update_command.c b/src/update_command.c new file mode 100644 index 0000000..0f0ca4c --- /dev/null +++ b/src/update_command.c @@ -0,0 +1,48 @@ +/* +** EPITECH PROJECT, 2025 +** 42sh +** File description: +** update_command +*/ +#include "history.h" +#include "builtins_handler.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); + (*buffer)[buffer_len - 1] = '\0'; + if (parse_history(buffer, &buffer_len, + buffer_sz, &exec_ctx->history_command) == 84) + return -1; + exec_ctx->history_command = save_command(*buffer, + exec_ctx->history_command); + return buffer_len; +} diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..3431f06 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,18 @@ +/* +** EPITECH PROJECT, 2025 +** __ +** File description: +** _ +*/ + + +#ifndef UTILS_H + #define UTILS_H + #include "history.h" + #include "u_str.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); +#endif /* UTILS_H */ diff --git a/src/utils/cat_in_str.c b/src/utils/cat_in_str.c new file mode 100644 index 0000000..9fe5d0c --- /dev/null +++ b/src/utils/cat_in_str.c @@ -0,0 +1,43 @@ +/* +** 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/src/utils/is_a_token.c b/src/utils/is_a_token.c new file mode 100644 index 0000000..5ce25c3 --- /dev/null +++ b/src/utils/is_a_token.c @@ -0,0 +1,20 @@ +/* +** 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, 2) == 0){ + return true; + } + } + return false; +} diff --git a/src/utils/len_array.c b/src/utils/len_array.c new file mode 100644 index 0000000..7c9d807 --- /dev/null +++ b/src/utils/len_array.c @@ -0,0 +1,17 @@ +/* +** 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/src/utils/strn_to_ndup.c b/src/utils/strn_to_ndup.c new file mode 100644 index 0000000..29f2379 --- /dev/null +++ b/src/utils/strn_to_ndup.c @@ -0,0 +1,22 @@ +/* +** 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/src/visitor.c b/src/visitor.c index a3b40e1..8811a99 100644 --- a/src/visitor.c +++ b/src/visitor.c @@ -146,18 +146,19 @@ void remove_trailing_semi(char *str) } } -int visitor(char *buffer, env_t *env, history_t *history) +int visitor(char *buffer, exec_ctx_t *exec_ctx) { ast_ctx_t ctx = { 0, .str = buffer, .cap = u_strlen(buffer) + 10, .ast = malloc(sizeof *ctx.ast * (u_strlen(buffer) + 10)) }; - ef_t ef = { .buffer = buffer, .env = env, - .history = history, .ctx = &ctx, .pout_fd = STDOUT_FILENO, - .flags = 0, 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); - history->last_exit_code = 0; + exec_ctx->history->last_exit_code = 0; if (ctx.ast == NULL) return RETURN_FAILURE; result = visitor_launcher(&ef);