From a238d9aa50f88af04279d7e29b540bbad6d2f842 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Fri, 9 Oct 2020 14:55:28 +0200 Subject: Norming eval --- README.md | 2 ++ src/debug.c | 17 +---------- src/eval/cmd.c | 29 ++++++++---------- src/eval/eval.c | 11 +++---- src/eval/operation.c | 85 ++++++++++++++++++++++++---------------------------- src/eval/redir.c | 25 +++++++--------- src/parser/parsed.c | 4 +-- src/parser/parser.c | 74 +++++++++++++++++++++++---------------------- 8 files changed, 109 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index 9df33be..d8334cc 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,12 @@ Done with [minishell\_test](https://github.com/cacharle/minishell_test). ```sh $ git submodule update minishell_test $ cd minishell_test +$ ./run --help $ ./run ``` ## Documentation +Install [Doxygen](https://www.doxygen.nl/index.html) Generate with `make doc` (clean with `make doc_clean`). You can then read the man pages in `./doc/man` or open `./doc/html/index.html` in your browser. diff --git a/src/debug.c b/src/debug.c index 9743e5a..a0e6770 100644 --- a/src/debug.c +++ b/src/debug.c @@ -6,10 +6,9 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/09/16 15:58:35 by charles #+# #+# */ -/* Updated: 2020/10/08 11:37:57 by cacharle ### ########.fr */ +/* Updated: 2020/10/09 14:27:40 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ -#include #include "lexer.h" #include "parser.h" @@ -55,7 +54,6 @@ void print_level(int level) void ast_print(int level, t_ast *ast) { - /* printf("%p\n", ast); */ if (ast == NULL) return ; if (ast->tag == AST_PARENT) @@ -71,12 +69,6 @@ void ast_print(int level, t_ast *ast) print_level(level); printf("pipeline: {\n"); t_ftlst *curr = ast->pipeline; - /* printf("%p\n", curr); */ - /* printf("%p\n", curr->next); */ - /* printf("%p\n", curr->next->next); */ - - /* printf("%p\n", curr->data); */ - /* printf("%p\n", curr->next->); */ while (curr != NULL) { ast_print(level + 1, (t_ast*)curr->data); @@ -96,21 +88,14 @@ void ast_print(int level, t_ast *ast) printf(" ]"); } else if (ast->tag == AST_OP) { - /* printf("SEP: %d\n", ast->op.sep); */ - /* printf("redirs: ["); */ - /* ft_lstiter(ast->redirs, token_put); */ - /* printf(" ] "); */ printf("{\n"); - print_level(level); printf(" left:\n"); ast_print(level + 1, ast->op.left); - printf("\n"); print_level(level); printf(" right:\n"); ast_print(level + 1, ast->op.right); - printf("\n"); print_level(level); printf("}\n"); diff --git a/src/eval/cmd.c b/src/eval/cmd.c index c786a7b..a35a73d 100644 --- a/src/eval/cmd.c +++ b/src/eval/cmd.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/14 10:41:31 by charles #+# #+# */ -/* Updated: 2020/10/08 10:15:07 by cacharle ### ########.fr */ +/* Updated: 2020/10/09 14:31:45 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ pid_t g_child_pid = -1; -int wrapped_cmd(t_fork_param_cmd *param) +static int st_wrapped_cmd(t_fork_param_cmd *param) { int status; @@ -30,6 +30,12 @@ int wrapped_cmd(t_fork_param_cmd *param) return (status); } +static int st_split_destroy_ret(int ret, char **strs) +{ + ft_split_destroy(strs); + return (ret); +} + int eval_cmd(int fds[2], t_env env, t_ast *ast) { t_fork_param_cmd param; @@ -40,31 +46,20 @@ int eval_cmd(int fds[2], t_env env, t_ast *ast) return (status); if ((argv = preprocess(&ast->cmd_argv, env)) == NULL) return (EVAL_FATAL); - /* printf("%p\n", ast->cmd_argv); */ - /* ast->cmd_argv = NULL; */ if (argv[0] == NULL) - { - ft_split_destroy(argv); - return (0); - } + return (st_split_destroy_ret(0, argv)); param.builtin = builtin_search_func(argv[0]); if (param.builtin != NULL && !param.builtin->forked) { status = param.builtin->func(argv, env); - ft_split_destroy(argv); - return (status); + return (st_split_destroy_ret(status, argv)); } - if (param.builtin == NULL && (status = path_search(env, argv[0], param.exec_path, true)) != 0) - { - ft_split_destroy(argv); - return (status); - } - + return (st_split_destroy_ret(status, argv)); param.argv = argv; param.env = env; - status = fork_wrap(fds, ¶m, (t_wrapped_func)wrapped_cmd); + status = fork_wrap(fds, ¶m, (t_wrapped_func)st_wrapped_cmd); ft_split_destroy(argv); g_state.last_status = status; return (status); diff --git a/src/eval/eval.c b/src/eval/eval.c index 66a535b..0df8b85 100644 --- a/src/eval/eval.c +++ b/src/eval/eval.c @@ -6,20 +6,17 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/09/13 20:38:06 by charles #+# #+# */ -/* Updated: 2020/10/07 15:02:21 by cacharle ### ########.fr */ +/* Updated: 2020/10/09 14:03:31 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include "eval.h" -int st_replace(int oldfd, int newfd) +static int st_replace(int oldfd, int newfd) { if (oldfd != FD_NONE) - { dup2(oldfd, newfd); - /* close(oldfd); */ - } - return 0; + return (0); } /* @@ -41,7 +38,7 @@ int fork_wrap(int fds[2], void *passed, t_wrapped_func wrapped) return (EVAL_FATAL); if (pid == 0) { - g_state.is_child = true; + g_state.is_child = true; if (st_replace(fds[FD_READ], STDIN_FILENO) != 0) exit(EXIT_FAILURE); if (st_replace(fds[FD_WRITE], STDOUT_FILENO) != 0) diff --git a/src/eval/operation.c b/src/eval/operation.c index 6ec41f9..19ecec7 100644 --- a/src/eval/operation.c +++ b/src/eval/operation.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/17 15:27:22 by charles #+# #+# */ -/* Updated: 2020/10/09 14:00:04 by cacharle ### ########.fr */ +/* Updated: 2020/10/09 14:54:43 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,63 +33,56 @@ int eval_operation(int fds[2], t_env env, t_ast *ast) return (eval(right_fds, env, ast->op.right)); } -int eval_pipeline(int fds[2], t_env env, t_ast *ast) -{ - t_ftlst *curr; - /* t_ftvec *pids; */ - int p[2]; - int prev_output; - - /* pids = ft_vecnew(16); */ +#define PIPES_PREV_OUTPUT 2 - prev_output = STDIN_FILENO; - curr = ast->pipeline; - - while (curr->next != NULL) - { - pipe(p); - - int pid = fork(); - if (pid == 0) - { - g_state.is_child = true; - dup2(p[FD_WRITE], STDOUT_FILENO); - if (prev_output != STDIN_FILENO) - { - dup2(prev_output, STDIN_FILENO); - close(prev_output); - } - close(p[FD_READ]); - fds[0] = FD_NONE; - fds[1] = FD_NONE; - exit(eval(fds, env, curr->data)); - } - close(p[FD_WRITE]); - if (prev_output != STDIN_FILENO) - close(prev_output); - prev_output = p[FD_READ]; - curr = curr->next; - } +static int st_run_piped( + t_env env, t_ast *ast, int pipes[3], bool is_last) +{ + pid_t pid; + int fds[2]; - int pid = fork(); + if ((pid = fork()) == -1) + return (EVAL_FATAL); if (pid == 0) { g_state.is_child = true; - if (prev_output != STDIN_FILENO) + if (!is_last) + dup2(pipes[FD_WRITE], STDOUT_FILENO); + if (pipes[PIPES_PREV_OUTPUT] != STDIN_FILENO) { - dup2(prev_output, STDIN_FILENO); - close(prev_output); + dup2(pipes[PIPES_PREV_OUTPUT], STDIN_FILENO); + close(pipes[PIPES_PREV_OUTPUT]); } - /* close(p[FD_WRITE]); */ + if (!is_last) + close(pipes[FD_READ]); fds[0] = FD_NONE; fds[1] = FD_NONE; - exit(eval(fds, env, curr->data)); + exit(eval(fds, env, ast)); } - g_child_pid = pid; - close(p[FD_READ]); + return (pid); +} - /* int status = 0; */ +int eval_pipeline(int fds[2], t_env env, t_ast *ast) +{ + t_ftlst *curr; + int pipes[3]; + int pid; + pipes[PIPES_PREV_OUTPUT] = STDIN_FILENO; + curr = ast->pipeline; + while (curr->next != NULL) + { + pipe(pipes); + st_run_piped(env, curr->data, pipes, false); + close(pipes[FD_WRITE]); + if (pipes[PIPES_PREV_OUTPUT] != STDIN_FILENO) + close(pipes[PIPES_PREV_OUTPUT]); + pipes[PIPES_PREV_OUTPUT] = pipes[FD_READ]; + curr = curr->next; + } + pid = st_run_piped(env, curr->data, pipes, true); + g_child_pid = pid; + close(pipes[FD_READ]); waitpid(pid, &pid, 0); while (wait(NULL) != -1) ; diff --git a/src/eval/redir.c b/src/eval/redir.c index 0d830e2..9d88b29 100644 --- a/src/eval/redir.c +++ b/src/eval/redir.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/15 11:05:34 by charles #+# #+# */ -/* Updated: 2020/09/16 16:17:09 by charles ### ########.fr */ +/* Updated: 2020/10/09 14:38:16 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -56,6 +56,14 @@ static int st_open_replace_dispatch(char *filename, int fds[2], enum e_tok tag) return (st_open_replace(filename, fd, oflag)); } +static int st_tok_lsts_destroy_ret( + int ret, t_tok_lst **tokens1, t_tok_lst **tokens2) +{ + tok_lst_destroy(tokens1, free); + tok_lst_destroy(tokens2, free); + return (ret); +} + int redir_extract(t_tok_lst **redirs, t_env env, int fds[2]) { t_tok_lst *after; @@ -65,9 +73,6 @@ int redir_extract(t_tok_lst **redirs, t_env env, int fds[2]) if (*redirs == NULL) return (0); - if (!((*redirs)->tag & TAG_IS_REDIR) || (*redirs)->next == NULL - || !((*redirs)->next->tag & TAG_IS_STR)) - return (EVAL_FATAL); curr = (*redirs)->next; after = NULL; while (curr != NULL && curr->tag & TAG_IS_STR) @@ -80,17 +85,9 @@ int redir_extract(t_tok_lst **redirs, t_env env, int fds[2]) curr = curr->next; } if ((status = preprocess_filename(&(*redirs)->next, env, &filename))) - { - tok_lst_destroy(redirs, free); - tok_lst_destroy(&after, free); - return (status); - } + return (st_tok_lsts_destroy_ret(status, redirs, &after)); if ((status = st_open_replace_dispatch(filename, fds, (*redirs)->tag)) != 0) - { - tok_lst_destroy(redirs, free); - tok_lst_destroy(&after, free); - return (status); - } + return (st_tok_lsts_destroy_ret(status, redirs, &after)); tok_lst_destroy(redirs, free); free(filename); return (redir_extract(&after, env, fds)); diff --git a/src/parser/parsed.c b/src/parser/parsed.c index 71ff581..a2b569a 100644 --- a/src/parser/parsed.c +++ b/src/parser/parsed.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/08/27 20:27:42 by charles #+# #+# */ -/* Updated: 2020/10/08 17:07:35 by cacharle ### ########.fr */ +/* Updated: 2020/10/09 14:08:46 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,7 +21,7 @@ t_parsed *parsed_new(t_ast *ast, t_tok_lst *rest) ret->syntax_error = false; ret->rest = rest; ret->ast = ast; - return ret; + return (ret); } t_parsed *parsed_error(const char *format, ...) diff --git a/src/parser/parser.c b/src/parser/parser.c index cac820c..8d5a0aa 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -6,7 +6,7 @@ /* By: nahaddac +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/17 18:09:04 by nahaddac #+# #+# */ -/* Updated: 2020/10/09 13:58:05 by cacharle ### ########.fr */ +/* Updated: 2020/10/09 14:30:29 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,8 +15,8 @@ ** \brief Parser */ -#include "parser.h" #include "minishell.h" +#include "parser.h" static char *g_sep_str_lookup[] = { [TAG_END] = ";", @@ -24,10 +24,10 @@ static char *g_sep_str_lookup[] = { [TAG_OR] = "||", [TAG_PIPE] = "|", [TAG_REDIR_IN] = "<", - [TAG_REDIR_OUT] = ">", [TAG_REDIR_APPEND] = ">>", - [TAG_PARENT_OPEN] = "(", [TAG_PARENT_CLOSE] = ")", + [TAG_REDIR_OUT] = ">", + [TAG_PARENT_OPEN] = "(", }; /* @@ -38,18 +38,17 @@ static char *g_sep_str_lookup[] = { t_parsed *parse_redir(t_tok_lst *input, t_tok_lst **redirs) { + t_parsed *ret; + tok_lst_push_back(redirs, tok_lst_uncons(&input)); - // FIXME big condition could be avoided with lexer not putting STICK - // if the next tokens isn't a string - while (input != NULL - && input->tag & TAG_IS_STR && input->tag & TAG_STICK - && input->next != NULL && input->next->tag & TAG_IS_STR) + while (input != NULL && input->tag & TAG_IS_STR && input->tag & TAG_STICK && + input->next != NULL && input->next->tag & TAG_IS_STR) tok_lst_push_back(redirs, tok_lst_uncons(&input)); if (input == NULL) return (parsed_error("syntax error near unexpected token `newline'")); if (!(input->tag & TAG_IS_STR)) { - t_parsed *ret = parsed_error("syntax error near unexpected token `%s'", input->content); + ret = parsed_error("syntax error near unexpected token `%s'", input->content); tok_lst_destroy(&input, free); return (ret); } @@ -64,9 +63,9 @@ t_parsed *parse_cmd(t_tok_lst *input) if (input->tag & TAG_IS_SEP || input->tag == TAG_PIPE || input->tag == TAG_PARENT_CLOSE) { - t_parsed *ret = parsed_error("syntax error near unexpected token `%s'", input->content); + tmp = parsed_error("syntax error near unexpected token `%s'", input->content); tok_lst_destroy(&input, free); - return (ret); + return (tmp); } if ((ast = ast_new(AST_CMD)) == NULL) return (NULL); @@ -87,7 +86,7 @@ t_parsed *parse_cmd(t_tok_lst *input) free(tmp); } else - break; + break ; } return (parsed_new(ast, input)); } @@ -97,10 +96,10 @@ t_parsed *parse_pipeline(t_tok_lst *input) t_parsed *expr; t_parsed *tail; t_ast *expr_ast; + t_ast *pipeline_ast; expr = parse_expr(input); - if (expr == NULL || expr->syntax_error || - expr->rest == NULL || expr->rest->tag != TAG_PIPE) + if (expr == NULL || expr->syntax_error || expr->rest == NULL || expr->rest->tag != TAG_PIPE) return (expr); tok_lst_pop_front(&expr->rest, free); if (expr->rest == NULL) @@ -118,7 +117,6 @@ t_parsed *parse_pipeline(t_tok_lst *input) } expr_ast = expr->ast; free(expr); - t_ast *pipeline_ast; if (tail->ast->tag == AST_CMD || tail->ast->tag == AST_PARENT) { pipeline_ast = ast_new(AST_PIPELINE); @@ -156,8 +154,8 @@ t_parsed *parse_op(t_tok_lst *input) ast_destroy(left->ast); tok_lst_destroy(&left->rest, free); free(left); - return (parsed_error("syntax error near unexpected token `%s'", - g_sep_str_lookup[sep_tag])); + return (parsed_error( + "syntax error near unexpected token `%s'", g_sep_str_lookup[sep_tag])); } tok_lst_pop_front(&input, free); if (input == NULL && sep_tag == TAG_END) @@ -172,7 +170,7 @@ t_parsed *parse_op(t_tok_lst *input) return (parsed_error("syntax error expected token")); } right = parse_op(input); - if (right == NULL || right->syntax_error) + if (right == NULL || right->syntax_error) { ast_destroy(left->ast); free(left); @@ -196,19 +194,19 @@ t_parsed *parse_op(t_tok_lst *input) t_parsed *parse_expr(t_tok_lst *input) { - t_parsed *parsed; - t_parsed *tmp; + t_parsed *parsed; + t_parsed *tmp; t_ast *ast; - if (input->tag & TAG_PARENT_OPEN) - { + if (input->tag & TAG_PARENT_OPEN) + { tok_lst_pop_front(&input, free); if (input == NULL) return (parsed_error("syntax error expected token")); parsed = parse_op(input); - if (parsed == NULL || parsed->syntax_error) + if (parsed == NULL || parsed->syntax_error) return (parsed); - input = parsed->rest; + input = parsed->rest; if (input == NULL || !(input->tag & TAG_PARENT_CLOSE)) { ast_destroy(parsed->ast); @@ -216,10 +214,10 @@ t_parsed *parse_expr(t_tok_lst *input) return (parsed_error("syntax error expected token")); } tok_lst_pop_front(&input, free); - if ((ast = ast_new(AST_PARENT)) == NULL) + if ((ast = ast_new(AST_PARENT)) == NULL) return (NULL); - ast->parent_ast = parsed->ast; - parsed->ast = ast; + ast->parent_ast = parsed->ast; + parsed->ast = ast; while (input != NULL && input->tag & TAG_IS_REDIR) { tmp = parse_redir(input, &parsed->ast->redirs); @@ -228,26 +226,30 @@ t_parsed *parse_expr(t_tok_lst *input) input = tmp->rest; free(tmp); } - parsed->rest = input; - return (parsed); - } - return (parse_cmd(input)); + parsed->rest = input; + return (parsed); + } + return (parse_cmd(input)); } t_parsed *parse(t_tok_lst *input) { + t_parsed *parsed; + t_parsed *ret; + if (input == NULL) return (NULL); - t_parsed *parsed = parse_op(input); + parsed = parse_op(input); if (parsed == NULL || parsed->syntax_error) - return parsed; + return (parsed); if (parsed->rest != NULL) { - t_parsed *ret = parsed_error("syntax error near unexpected token `%s'", parsed->rest->content); + ret = parsed_error( + "syntax error near unexpected token `%s'", parsed->rest->content); tok_lst_destroy(&parsed->rest, free); ast_destroy(parsed->ast); free(parsed); - return ret; + return (ret); } return (parsed); } -- cgit