/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* parsing.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ /* Updated: 2021/11/11 13:11:55 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" size_t count_pipes(t_token *token); t_cmd **create_cmd(t_token *token_list, size_t cmd_nbr); void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr); void handle_path(t_cmd **cmd_arr, char **envp); void handle_fd(t_token *token, t_cmd **cmd_arr); void fd_heredoc(t_token *token, t_cmd *cmd); void fd_redirection(t_token *token, t_cmd *cmd); void find_path(char **argv, char **envp); int handle_builtin(t_cmd *cmd); int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)); int next_cmd(t_token *token); int is_redirection(enum e_token_id id); t_cmd **parsing(t_token *token_list, char **envp) { t_cmd **cmd_arr; size_t cmd_nbr; if (!valid_syntax(token_list)) return (NULL); cmd_nbr = count_pipes(token_list); cmd_arr = create_cmd(token_list, cmd_nbr); // cmd_expansion(cmd_arr, envp); handle_argv(token_list, cmd_arr, cmd_nbr); handle_path(cmd_arr, envp); handle_fd(token_list, cmd_arr); return (cmd_arr); } size_t count_pipes(t_token *token) { size_t nb; nb = 0; while (token) { if (token->id == T_PIPE) nb++; token = token->next; } return (nb + 1); } t_cmd **create_cmd(t_token *token_list, size_t cmd_nbr) { t_cmd **cmd_arr; size_t i; (void)token_list; cmd_arr = ft_calloc(cmd_nbr + 1, sizeof(t_cmd *)); cmd_arr[cmd_nbr] = NULL; i = 0; while (i < cmd_nbr) { cmd_arr[i] = ft_calloc(1, sizeof(t_cmd)); ft_bzero(cmd_arr[i], sizeof(t_cmd)); i++; } return (cmd_arr); } int is_redirection(enum e_token_id id) { if (id == T_LESS) // < return (1); else if (id == T_GREAT) // > return (1); else if (id == T_DLESS) // << return (1); else if (id == T_DGREAT) // >> return (1); else return (0); } // count nbr word in cmd, minus redirection and heredoc int next_cmd(t_token *token) { int i; i = 0; while (token && token->id != T_PIPE) { if (is_redirection(token->id)) i--; else i++; token = token->next; } if (token && token->id == T_PIPE) token = token->next; return (i); } void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr) { int argc; int j; int i; int redirection; i = 0; while (cmd_nbr) { argc = next_cmd(token); cmd[i]->argv = calloc(argc + 1, sizeof(char *)); cmd[i]->argv[argc] = NULL; j = 0; redirection = is_redirection(token->id); while (token && token->id != T_PIPE) { if (!redirection && token->id == T_WORD) { cmd[i]->argv[j] = ft_strdup(token->content); j++; } redirection = is_redirection(token->id); token = token->next; } if (token && token->id == T_PIPE) token = token->next; cmd_nbr--; i++; } } int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)) { cmd->builtin_command = builtin; return (1); } int handle_builtin(t_cmd *cmd) { if (!ft_strncmp(cmd->argv[0], "echo", 4)) return (fill_builtin(cmd, builtin_echo)); else if (!ft_strncmp(cmd->argv[0], "cd", 2)) return (fill_builtin(cmd, &builtin_cd)); else if (!ft_strncmp(cmd->argv[0], "pwd", 3)) return (fill_builtin(cmd, builtin_pwd)); else if (!ft_strncmp(cmd->argv[0], "export", 6)) return (fill_builtin(cmd, &builtin_export)); else if (!ft_strncmp(cmd->argv[0], "unset", 5)) return (fill_builtin(cmd, &builtin_unset)); else if (!ft_strncmp(cmd->argv[0], "env", 3)) return (fill_builtin(cmd, builtin_env)); else if (!ft_strncmp(cmd->argv[0], "exit", 4)) return (fill_builtin(cmd, builtin_exit)); return (0); } void find_path(char **argv, char **envp) { int i; char **path; char *cmd; i = 0; while (envp[i] && ft_strncmp(envp[i], "PATH=", 5)) i++; path = ft_split(envp[i] + 5, ':'); // 5 = lentgh of "PATH=" i = -1; while (*path && i != 0) { cmd = ft_strjoin(path[0], "/"); cmd = ft_strjoin(cmd, argv[0]); i = access(cmd, X_OK); path++; } if (!(*path)) exit(0); // gerer erreur argv[0] = cmd; } void handle_path(t_cmd **cmd_arr, char **envp) { int i; i = 0; while (cmd_arr[i]) { if (!handle_builtin(cmd_arr[i])) find_path(cmd_arr[i]->argv, envp); i++; } } void fd_redirection(t_token *token, t_cmd *cmd) { int flag; if (token->id == T_LESS) // '<' { flag = O_RDONLY | O_CREAT; if (cmd->fd_in != 0) close(cmd->fd_in); cmd->fd_in = open(token->next->content, flag); } else if (token->id == T_GREAT) // '>' { flag = O_WRONLY | O_CREAT | O_TRUNC; cmd->fd_out = open(token->next->content, flag, S_IRWXU); } else if (token->id == T_DGREAT) // '>>' { flag = O_WRONLY | O_CREAT | O_APPEND; cmd->fd_out = open(token->next->content, flag, S_IRWXU); } } void fd_heredoc(t_token *token, t_cmd *cmd) { (void)token; (void)cmd; } void handle_fd(t_token *token, t_cmd **cmd_arr) { int *pipes_fd; int i; i = 0; while (cmd_arr[i]) { cmd_arr[i]->fd_out = 1; while (token && token->id != T_PIPE) { if (token->id == T_DGREAT) // '<<' fd_heredoc(token, cmd_arr[i]); else fd_redirection(token, cmd_arr[i]); token = token->next; } if (token && token->id == T_PIPE) { token = token->next; pipes_fd = calloc(2, sizeof(int)); pipe(pipes_fd); if (cmd_arr[i]->fd_out == 1) cmd_arr[i]->fd_out = pipes_fd[1]; else close(pipes_fd[1]); cmd_arr[i + 1]->fd_in = pipes_fd[0]; } i++; } } /* ------------------------------------------------------- The grammar symbols ------------------------------------------------------- */ /* %token WORD %token LESS // '<' %token GREAT // '>' %token DLESS // '<<' %token DGREAT // '>>' %token PIPE // '|' */ /* ------------------------------------------------------- The Simplified Grammar ------------------------------------------------------- */ /* %start program %% pipeline : command | pipeline '|' command ; command : cmd_prefix cmd_name cmd_suffix | cmd_prefix cmd_name | cmd_name cmd_suffix | cmd_name ; cmd_name : WORD // Apply rule 7a ; cmd_prefix : io_redirect | cmd_prefix io_redirect ; cmd_suffix : io_redirect | cmd_suffix io_redirect | WORD | cmd_suffix WORD ; io_redirect : io_file | io_here ; io_file : '<' filename | '>' filename | DGREAT filename ; filename : WORD // Apply rule 2 ; io_here : DLESS here_end ; here_end : WORD // Apply rule 3 ; */