/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* minishell.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: anarama +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/05 12:16:38 by victor #+# #+# */ /* Updated: 2024/08/27 17:28:49 by vvobis ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef MINISHELL_H # define MINISHELL_H # include # include "libft/libft.h" # include # include # include # include # include # include # include # include # include # include # include # include # include # include # define PWD 0 # define CUSTOM 1 # define PROMPT_COMMAND_STACK_SIZE 16 # define PROMPT_INPUT_BUFFER_SIZE 4096 # define CURSOR_MOVE_HOME "\033[H" # define GREEN "\033[0;32m" # define RESET "\033[0m" # define RED "\033[0;31m" # define CURSOR_MOVE_UP "\033[A" # define CURSOR_MOVE_DOWN "\033[B" # define CURSOR_MOVE_RIGHT "\033[C" # define CURSOR_MOVE_LEFT "\033[D" # define CURSOR_POSITION_GET "\033[6n" # define CURSOR_POSITION_SET "\033[%d;%dH" # define CURSOR_POSITION_SAVE "\033[s" # define CURSOR_POSITION_RESTORE "\033[u" # define MAXIMUM_COLUMN 9999 # define MAXIMUM_ROW 9999 # define SCREEN_MAX "\033[9999;9999H" # define DEL 127 # define EOT 4 # define ESC 27 # define VARIABLE_TOKEN_SIZE 1024 # define SCREEN_DISBLE_WRAPPING "\033[?7l" # define SCREEN_ENABLE_WRAPPING "\033[?7h" # define SCREEN_CLEAR_TO_EOL "\033[K" # define SCREEN_CLEAR "\033[2J" # define SCREEN_CLEAR_TO_EOF "\033[J" # define ENVIRONMENT_SIZE 512 # define INITIAL_TOKEN_CAPACITY 16 # define BUFFER_CAPACITY 64 typedef struct s_history_buffer { uint write; uint read; uint buffer_capacity; char *buffer[BUFFER_CAPACITY]; } t_history_buffer; typedef struct s_prompt { bool exists; char *prompt; t_history_buffer history; uint32_t cursor_position[2]; void (*prompt_display_func)(char *); uint32_t prompt_length; char *command; } t_prompt; typedef enum e_token_type { TOKEN_WORD = 1, TOKEN_REDIRECT_OUT, TOKEN_REDIRECT_IN, TOKEN_REDIRECT_APPEND, TOKEN_HEREDOC, TOKEN_PIPE, TOKEN_AND, TOKEN_OR, TOKEN_NEWLINE, TOKEN_SEMICOLON, TOKEN_EOL, TOKEN_DONE, } t_token_type; typedef struct s_token { t_token_type token_type; char *token_value; } t_token; typedef struct s_ring_buffer { uint write; uint read; uint buffer_capacity; t_token *buffer[BUFFER_CAPACITY]; } t_ring_buffer; typedef enum t_node_type { NODE_NONE, NODE_END = TOKEN_EOL, NODE_PIPE = 6, NODE_LOGICAL_AND, NODE_LOGICAL_OR, NODE_NEWLINE, NODE_INVALID, } t_node_type; typedef struct s_ast { t_node_type type; t_token_type token_type; char **args; bool is_heredoc; char *path_file_in; char *path_file_out; bool has_redir_in; bool has_redir_out; bool was_pipe; int32_t pipefd[2]; int fd_in; int fd_out; pid_t cpid; } t_ast; enum e_alloc { ADD, CLEAN, END, FREE, }; typedef struct s_clean { void *content; void (*clean)(void *del); struct s_clean *next; } t_clean; extern int32_t volatile g_signal_flag; /* Builtins */ int32_t ft_echo(char **args, int32_t *exit_status); void ft_cd( const char **environment, \ const char **args, \ int32_t *exit_status); void ft_pwd(const char **env, int32_t *exit_status); void ft_env(const char **env, int32_t *exit_status); void ft_unset( char **environment, \ const char **args, \ int32_t *exit_status); void ft_export(const char **args, int32_t *exit_status); void ft_exit(t_ast *tree, int *exit_status); void *ft_realloc(void *ptr, int old_size, int new_size); /* Commands */ bool is_buildin( t_ast *node); bool buildin_execute( t_ast *node, \ const char **environment, \ int *exit_status); void command_execute( char const *command_path, \ char const *argv[], \ char const **env); void m_tokenizer( const char *input, \ char **env, \ int *exit_status, \ int32_t std[2]); /* non_interactive */ int32_t minishell_single_command( char *command, \ char **environment, \ int32_t std[2]); void *ft_realloc_string( char **string, uint32_t *new_size); char *check_redir_input(void); void setup_environment( const char **environment); int setup( uint32_t argc, \ const char **argv, \ char **environment, \ int32_t std[2]); /* Handle signal */ void handle_sigint(int sig); void setup_signal_handlers(void); /* Input */ void free_split(void *back); uint32_t get_split_size(const char **split); uint32_t get_split_length(char **split); int get_amount_tokens(t_token *tokens); /* List Memory */ void lst_memory(void *mem, void (*del)(void *c), int mode); int p_stderr(int stderr_fd, const char *error, const char *specifier); /* List */ t_clean *lst_node_new(void *content, void (*del)(void *)); void lst_node_del(t_clean **lst); void lst_node_del_clean(t_clean **lst, void *mem); void lst_list_clean(t_clean **head); int lst_add_back(t_clean **node, t_clean *node_new); /* Path Utils */ char *find_absolute_path( const char *path_variable, \ char *input, \ int *exit_status); /* Prompt */ void prompt_destroy(void *prompt); t_prompt prompt_create(uint8_t mode); char *prompt_get(const char *prompt); uint32_t prompt_display_string_set( t_prompt *prompt, \ const char **environment, \ const char *prompt_string); void handle_arrow_key_up( t_history_buffer *history, \ char **input, \ uint32_t cursor_position_current[2]); /* Prompt_print.c */ void prompt_print_custom_string(char *string); void prompt_print_pwd(char *prompt); /* Lexer */ void evaluate_input( char **input[], \ int32_t *exit_status, \ bool *error_caught); uint32_t get_spaces(char *input); uint32_t determine_variables(char **input); void split_string_by_space(char *to_split, char **input_new); void adjust_input(char **input, char *new_string); uint32_t determine_full_length(char *string, char **environment); uint32_t evaluate_variable( char ***input, \ int32_t *exit_status); /* input skip pattern */ bool is_delimiter_variable(char c); char skip_to_delimiter(char *input_new); bool skip_single_quotes( char *input, \ uint32_t *i, \ bool *in_double_quotes); bool evaluate_double_quotes(char *input, uint32_t *i); bool evaluate_single_quotes(char *input, uint32_t *i); /* Cursor Manipulation */ void cursor_position_get(uint32_t cursor_position[2]); void cursor_position_save(void); void cursor_position_restore(void); bool handle_escape_sequence( t_prompt *prompt, \ char buffer[], \ char **input, \ uint32_t cursor_position[2]); char *prompt_get_input( t_prompt *prompt, \ uint32_t prompt_initial_size, \ const char *delimiter); bool handle_multiple_character( char **input, \ char buffer[], \ uint32_t cursor_position[2], \ uint32_t prompt_length); /* Prompt Buffer Management */ void prompt_refresh_line( char *input, \ uint32_t cursor_position_base, \ uint32_t cursor_position[2]); char *prompt_buffer_size_manage( char **input, \ uint32_t old_size, \ uint32_t size_to_add, \ uint32_t scalar); void prompt_string_insert( char *string_to_insert, \ char **current_input, \ char *position_to_insert, \ uint32_t current_word_length); bool handle_new_character_to_input( char **input, \ char character, \ uint32_t *cursor_position, \ uint32_t prompt_length); uint8_t handle_single_char_input( char **input, char buffer[], \ uint32_t cursor_position[2], \ bool *do_refresh); uint8_t handle_single_char_input( char **input, char buffer[], \ uint32_t cursor_position[2], \ bool *do_refresh); bool handle_new_character_to_input( char **input, \ char character, \ uint32_t *cursor_position, \ uint32_t prompt_length); /* Non Blocking mode */ void blocking_mode_toggle(int flag); /* Tab Completion */ void handle_tab( char **input, t_prompt *prompt); void handle_tab_no_match( const char *input_path, \ char **env, \ uint32_t cursor_position_current[2], \ t_prompt *prompt); void handle_tab_yes_match( t_prompt *prompt, \ const char *next_word_match, \ char **input, \ uint32_t current_word_length); char *determine_word( char *input, \ char **input_path, \ uint32_t cursor_position_current); void get_next_word_match( char **input, \ t_prompt *prompt, \ char *input_path, \ bool *is_directory); void handle_rapid_input( char buffer[], \ uint32_t cursor_position[2], \ char **input, \ uint32_t cursor_position_base); void handle_backspace( char *input, \ uint32_t *cursor_position_current, \ uint32_t input_length_current); /* Termios */ void terminal_raw_mode_enable(int flag); void terminal_raw_mode_disable(int flag); /* Utils */ int ft_close(int fd, const char *specifier); void ft_pipe(int pipefd[2], const char *specifier); void ft_dup2(int fd_old, int fd_new, const char *specifier); void ft_fork(pid_t *pid, const char *specifier); void ft_open(int *fd, const char *path, int flag, int mode); int64_t ft_read(int fd, char *character, uint32_t size_read); void ft_opendir(DIR **directory, const char *directory_path); void close_fds(void *std_ptr); /* Wildcards */ void check_and_expand_wildcards(char ***input); int check_wildcard(char *str); int get_tokens_count(char **tokens); /* Wildcards Helper */ int compare_suffix( const char *current_position_in_str, \ const char *current_position_in_pattern); int handle_prefix( const char *pattern, \ const char *str, \ char *adr_next_wild); int handle_middle( const char *pattern, const char *str); char **expand_wildcard( const char *pattern); /* Environment_variable */ void environment_variable_print( const char *variable, \ const char **environment); void environment_print( const char **environment); char **environment_create( const char **env); void environment_variable_remove( char **environment, \ const char *variable); void environment_variable_add( char ***environment, \ const char *variable_name, \ const char *variable_value); char **environment_variable_get( const char *variable, \ const char **environment); char *environment_variable_value_get( const char *variable, \ const char **environment); void environment_variable_value_change( const char **environment, \ const char *variable_name, \ const char *variable_value); char **env_static(char **environment); /*check_special_symbol.c*/ int is_special_char(char c); int ft_isspace(char c); bool is_in_alphabet(char c); bool unrecognized_input(char c); /*create_token_double_special_symbol.c*/ int is_double_special(const char *input); t_token create_token_double_special_symbol(char **input); bool is_mutliple_lines(char *c); void remove_qoutes_delimiter(char *delimiter, uint32_t *length); void token_heredoc_get( t_token *token, const char *delimiter); /* token_heredoc.c */ char *heredoc_while_tokenizing(char *input); char *handle_delimiter(char *input, char **temp_move); char *heredoc_loop( char *input, \ char *temp_move, \ const char *delimiter, \ uint32_t delimiter_length); /* handle_heredoc.c */ void handle_heredoc(t_token tokens, int32_t fd); bool heredoc_has_been_done(t_token *token, char *value, int fd); void print_value(char *value, int fd); void remove_quotes(char *s); /*create_token_single_special_symbol.c*/ int is_single_special(const char input); t_token create_token_single_special_symbol(const char **input); /*create_token_word.c*/ t_token create_token_word(const char **input); /*create_token.c*/ t_token create_token(t_token_type token_type, const char *value); /*env_utils.c*/ void print_tokens(t_token *tokens); /* subshell.c */ char *execute_subshell(char *input, const char **environement); /*tokenizer.c*/ t_token *lexical_analysis(char *input); /* tokenizer_heredoc_helper.c */ void ring_buffer_put( t_ring_buffer *buffer, t_token *entry); t_token *ring_buffer_get( t_ring_buffer *buffer); t_token mark_tokens_till_heredoc( char *value, char **input); void tokenizing_loop( char **input, \ t_token *tokens, \ uint32_t *i, \ t_ring_buffer *heredoc_buffer); /*ats_print.c*/ void print_ast(t_ast *head); /*handle_command.c*/ void handle_command( t_ast *current, \ const char **env, \ int *exit_status, \ int std[2]); void execute_commands( t_ast *tree, \ const char **env, \ int *exit_status, \ int32_t std[2]); void wait_pids( t_ast *tree, \ uint pid_count, \ pid_t pid_final, \ int32_t *exit_status); /*handle_fds.c*/ bool handle_fds_child_proccess(t_ast *command, int32_t *exit_status); void handle_fds_parent_proccess(t_ast *command, int32_t *exit_status); void handle_pipe_in_child(t_ast *command); void handle_pipe_in_parent(t_ast *command); bool buildin_apply_pipe(t_ast *node, int32_t *exit_status); /*handle_logical_operator.c*/ void handle_logical_operator(t_ast **logical_node, int exit_status); /* handle_pipes.c */ void handle_pipe(t_ast *pipe_node, int *error_catched); /*handle_redirs.c*/ void handle_redir_in( t_ast *branch, \ t_token *token, \ t_token *token_next); void handle_redir_out( t_ast *branch, \ t_token *token, \ t_token *token_next); void handle_redir_append( t_ast *branch, \ t_token *token, \ t_token *token_next); void handle_redir_heredoc( t_ast *branch, \ t_token *token, \ uint8_t token_id); /*parse_tokens.c*/ t_ast *parse_tokens( t_token *tokens, \ int32_t *exit_status); uint32_t determine_trees(t_token *tokens); void tree_destroy(void *tree_ptr); /* Syntac_check.c */ void check_valid_logical_operator( t_token *token, \ int index, \ int *error_catched); void check_valid_pipe( t_token *token, \ int index, \ int *error_catched); void check_valid_redir( t_token *token, \ int index, \ int *error_catched); void print_error_redir( t_token_type token_type); void print_error_logical_operator( t_token_type token_type); void restore_fd(int std[2]); /*parser.c*/ void fill_args( char ***args, \ int count, \ char *token_value, \ int *capacity); bool is_delimiter_token(t_token *token); /*syntax_check.c*/ void check_valid_redir( t_token *token, \ int index, \ int *error_catched); void check_valid_pipe( t_token *token, \ int index, \ int *error_catched); void check_valid_logical_operator( t_token *token, \ int index, \ int *error_catched); void check_valid_heredoc(t_token *token, int index, int *error_catched); /* syntax_check_helper.c */ void print_error_logical_operator(t_token_type token_type); void print_error_pipe(void); void print_error_redir(t_token_type token_type); void free_tokens(void *token_ptr); #endif