From 0461bae82be1f9755d4204b1744c2da36e84401b Mon Sep 17 00:00:00 2001 From: LARGEOT MAXENCE Date: Tue, 9 May 2023 15:37:02 +0200 Subject: [PATCH] feat(history): Add function that will be use to get history --- mars_lib/my_stdlib/src/array/my_str_tok.c | 63 +++++++++++++++ src/history/execution/display_history.c | 35 +++++++++ src/history/execution/exec_history_command.c | 76 +++++++++++++++++++ src/history/execution/exec_history_display.c | 53 +++++++++++++ src/history/execution/my_history.c | 27 +++++++ .../lst_management/create_history_node.c | 56 ++++++++++++++ src/history/lst_management/destroy_history.c | 39 ++++++++++ src/history/lst_management/init_history.c | 45 +++++++++++ 8 files changed, 394 insertions(+) create mode 100755 mars_lib/my_stdlib/src/array/my_str_tok.c create mode 100644 src/history/execution/display_history.c create mode 100644 src/history/execution/exec_history_command.c create mode 100644 src/history/execution/exec_history_display.c create mode 100644 src/history/execution/my_history.c create mode 100644 src/history/lst_management/create_history_node.c create mode 100644 src/history/lst_management/destroy_history.c create mode 100644 src/history/lst_management/init_history.c diff --git a/mars_lib/my_stdlib/src/array/my_str_tok.c b/mars_lib/my_stdlib/src/array/my_str_tok.c new file mode 100755 index 0000000..4310dd8 --- /dev/null +++ b/mars_lib/my_stdlib/src/array/my_str_tok.c @@ -0,0 +1,63 @@ +/* +** EPITECH PROJECT, 2023 +** my_str_to_word_array +** File description: +** my_str_to_word_array +*/ + +#include "my_stdlib.h" +#include +#include + +static bool my_char_is_in_lst(const char c, const char *lst) +{ + for (size_t i = 0; lst[i] != '\0'; i++) + if (lst[i] == c) + return (true); + return (false); +} + +static size_t count_words(char const *str, char const *token) +{ + size_t nb_words = 0; + + if (!str) + return (0); + for (size_t i = 0; str[i] != '\0'; i++) + if (!my_char_is_in_lst(str[i], token) && + (str[i + 1] == '\0' || my_char_is_in_lst(str[i + 1], token))) + nb_words++; + return (nb_words); +} + +static size_t get_size_word(char const *str, char const *token) +{ + size_t count = 0; + + while (!my_char_is_in_lst(str[count], token) && + str[count] != '\0') + count++; + return (count); +} + +char **my_str_tok(char const *str, char const *token) +{ + size_t nb_word = count_words(str, token); + char **word_arr = malloc(sizeof(char *) * (nb_word + 1)); + size_t size_str = my_strlen(str); + size_t size_w = 0; + size_t pos_arr = 0; + + if (!word_arr) + return (NULL); + for (size_t i = 0; i < size_str; i++){ + if (my_char_is_in_lst(str[i], token)) + continue; + size_w = get_size_word(&str[i], token); + word_arr[pos_arr] = my_strndup(&str[i], size_w); + i += size_w; + pos_arr++; + } + word_arr[pos_arr] = NULL; + return (word_arr); +} diff --git a/src/history/execution/display_history.c b/src/history/execution/display_history.c new file mode 100644 index 0000000..a64b9a2 --- /dev/null +++ b/src/history/execution/display_history.c @@ -0,0 +1,35 @@ +/* +** EPITECH PROJECT, 2023 +** display_history +** File description: +** display_history +*/ + +#include +#include "my.h" + +void display_command_array(char **command) +{ + size_t parser = 0; + + if (!command) { + printf("\n"); + return; + } + for (; command[parser + 1]; parser++) + printf("%s ", command[parser]); + printf("%s\n", command[parser]); +} + +void display_history(history_list_t *list) +{ + history_t *node = NULL; + + if (!list) + return; + node = list->head; + for (; node; node = node->next) { + printf("\t%i\t%s\t", node->pos, node->time); + display_command_array(node->command); + } +} diff --git a/src/history/execution/exec_history_command.c b/src/history/execution/exec_history_command.c new file mode 100644 index 0000000..159949d --- /dev/null +++ b/src/history/execution/exec_history_command.c @@ -0,0 +1,76 @@ +/* +** EPITECH PROJECT, 2023 +** exec_history_command +** File description: +** exec_history_command +*/ + +#include +#include "my.h" +int execute_commands(char **args, term_t *term); + +bool is_existant_event(char *str, history_list_t *list) +{ + history_t *node = list->tail; + bool check_nb = my_str_isnum(str); + + for (; node; node = node->prev){ + if (check_nb && atoi(str) == node->pos) + return (true); + if (!check_nb && node->command && strncmp (node->command[0], str, + strlen(str)) == 0) + return (true); + } + return (false); +} + +static bool handle_error(char **args, history_list_t *list) +{ + if (!args || !list) + return (true); + if (strcmp(args[0], "!") == 0){ + printf("!: Command not found.\n"); + return (true); + } + if (!is_existant_event(&args[0][1], list)) { + printf("%s: Event not found.\n", &args[0][1]); + return (true); + } + return (false); +} + +char **convert_args(char **args, history_list_t *list, bool is_num) +{ + char **new_cmd = NULL; + history_t *node = list->tail; + + for (; node; node = node->prev){ + if ((is_num && node->pos == atoi(&args[0][1])) || (!is_num && + strncmp(&args[0][1], node->command[0], strlen(&args[0][1])) == 0)) { + new_cmd = my_dup_array((const char **)node->command); + break; + } + } + if (my_count_array_size((const char **)args) != 1) + for (size_t i = 1; args[i]; i++) + new_cmd = my_add_str_to_array(new_cmd, args[i]); + return (new_cmd); +} + +int exec_history_command(char **args, history_list_t *list, term_t *term) +{ + bool is_num = false; + char **new_cmd = NULL; + int exit_status = 0; + + if (handle_error(args, list)) + return (1); + is_num = my_str_isnum(&args[0][1]); + new_cmd = convert_args(args, list, is_num); + my_destroy_str_array(args); + command_is_in_history(list->tail->command, list); + if (list->size > 100) + rm_history_node(list->head, list); + exit_status = execute_commands(new_cmd, term); + return (exit_status); +} diff --git a/src/history/execution/exec_history_display.c b/src/history/execution/exec_history_display.c new file mode 100644 index 0000000..4ebca5b --- /dev/null +++ b/src/history/execution/exec_history_display.c @@ -0,0 +1,53 @@ +/* +** EPITECH PROJECT, 2023 +** exec_history_display +** File description: +** exec_history_display +*/ + +#include "my.h" + +static bool handle_error_args(char **args) +{ + size_t nb_args = my_count_array_size((const char **)args); + + if (!args) + return (true); + if (nb_args > 3) { + printf("history: Too many arguments.\n"); + return (true); + } + for (size_t i = 1; args[i]; i++) { + if (!my_str_isnum(args[i])){ + printf("Usage: history [number of events].\n"); + return (true); + } + } + return (false); +} + +static void display_history_part(char *nb_str, history_list_t *list) +{ + history_t *node = list->head; + int nb = atoi(nb_str); + + for (size_t i = 0; node; node = node->next, i++){ + if (i >= list->size - nb) { + printf("\t%i\t%s\t", node->pos, node->time); + display_command_array(node->command); + } + } +} + +int exec_history_display(char **args, history_list_t *list) +{ + if (handle_error_args(args) || !list) + return (1); + if (my_count_array_size((const char**)args) == 1 || + atoi(args[1]) >= (int)list->size) { + display_history(list); + return (0); + } + display_history_part(args[1], list); + return (0); +} diff --git a/src/history/execution/my_history.c b/src/history/execution/my_history.c new file mode 100644 index 0000000..6309a76 --- /dev/null +++ b/src/history/execution/my_history.c @@ -0,0 +1,27 @@ +/* +** EPITECH PROJECT, 2023 +** my_history +** File description: +** my_history +*/ + +#include +#include "my.h" + +int my_history(char **args, UNUSED char **env, int *exit_status, void *data) +{ + term_t *term = data; + + if (!args || !term->history) + return (1); + if (strcmp(args[0], "history") == 0) { + (*exit_status) = exec_history_display(args, term->history); + return ((*exit_status)); + } else { + (*exit_status) = exec_history_command(args, term->history, term); + return ((*exit_status)); + } + printf("History error\n"); + *exit_status = 84; + return (84); +} diff --git a/src/history/lst_management/create_history_node.c b/src/history/lst_management/create_history_node.c new file mode 100644 index 0000000..7574885 --- /dev/null +++ b/src/history/lst_management/create_history_node.c @@ -0,0 +1,56 @@ +/* +** EPITECH PROJECT, 2023 +** create_history_node +** File description: +** create_history_node +*/ + +#include +#include "my.h" + +static char *get_time(void) +{ + time_t mytime = time(NULL); + char *complete_time = ctime(&mytime); + char *time = NULL; + + complete_time[my_strlen(complete_time)-1] = '\0'; + time = my_strndup(&complete_time[11], 5); + return (time); +} + +static history_t *init_node(const char **command, history_list_t *list) +{ + history_t *node = NULL; + + if (!list || !command) + return (NULL); + node = malloc(sizeof(history_t)); + if (!node) + return (NULL); + node->command = my_dup_array(command); + node->time = get_time(); + if (list->tail) + node->pos = list->tail->pos + 1; + else + node->pos = 1; + node->next = NULL; + node->prev = list->tail; + return (node); +} + +void create_history_node(history_list_t *list, char **command) +{ + history_t *node = init_node((const char **)command, list); + + if (!node || !list) + return; + if (list->size == 0){ + list->head = node; + list->tail = node; + } else { + list->tail->next = node; + list->tail = node; + } + list->size++; +} diff --git a/src/history/lst_management/destroy_history.c b/src/history/lst_management/destroy_history.c new file mode 100644 index 0000000..d5030a7 --- /dev/null +++ b/src/history/lst_management/destroy_history.c @@ -0,0 +1,39 @@ +/* +** EPITECH PROJECT, 2023 +** destroy_history +** File description: +** destroy_history +*/ + +#include "my.h" + +void rm_history_node(history_t *node, history_list_t *list) +{ + if (!node || !list) + return; + if (node->prev) + node->prev->next = node->next; + if (node->next) + node->next->prev = node->prev; + if (node == list->head) + list->head = node->next; + if (node == list->tail) + list->tail = node->prev; + free(node->time); + my_destroy_str_array(node->command); + free(node); + list->size--; +} + +void destroy_history(history_list_t *list) +{ + history_t *node = NULL; + + if (!list) + return; + node = list->tail; + for (; node->prev; node = node->prev) + rm_history_node(node, list); + rm_history_node(node, list); + free(list); +} diff --git a/src/history/lst_management/init_history.c b/src/history/lst_management/init_history.c new file mode 100644 index 0000000..567e112 --- /dev/null +++ b/src/history/lst_management/init_history.c @@ -0,0 +1,45 @@ +/* +** EPITECH PROJECT, 2023 +** init_destroy_history +** File description: +** init__destroy_history +*/ + +#include +#include +#include +#include "my.h" + +static void get_old_history(UNUSED history_list_t *history) +{ + int fd = open("save_file/history.txt", O_RDONLY); + struct stat stats; + char *buffer = NULL; + char **commands = NULL; + + if (fd == -1 || stat("save_file/history.txt", &stats) == -1) + return; + buffer = malloc(sizeof(char) * (stats.st_size + 1)); + if (!buffer) + return; + read(fd, buffer, stats.st_size); + buffer[stats.st_size] = '\0'; + if (buffer[0] == '\0') { + free(buffer); + return; + } + commands = my_str_tok(buffer, "\n"); +} + +history_list_t *init_history_list(void) +{ + history_list_t *history = malloc(sizeof(history_list_t)); + + if (!history) + return (NULL); + history->head = NULL; + history->tail = NULL; + history->size = 0; + get_old_history(history); + return (history); +}