582 lines
16 KiB
C
582 lines
16 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* minishell.h :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* 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 <stdbool.h>
|
|
# include "libft/libft.h"
|
|
# include <unistd.h>
|
|
# include <fcntl.h>
|
|
# include <sys/types.h>
|
|
# include <stdio.h>
|
|
# include <dirent.h>
|
|
# include <string.h>
|
|
# include <stdlib.h>
|
|
# include <sys/wait.h>
|
|
# include <termios.h>
|
|
# include <errno.h>
|
|
# include <signal.h>
|
|
# include <sys/ioctl.h>
|
|
# include <stddef.h>
|
|
# include <sys/stat.h>
|
|
|
|
# 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
|