aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/debug.c17
-rw-r--r--src/eval/cmd.c29
-rw-r--r--src/eval/eval.c11
-rw-r--r--src/eval/operation.c85
-rw-r--r--src/eval/redir.c25
-rw-r--r--src/parser/parsed.c4
-rw-r--r--src/parser/parser.c74
7 files changed, 107 insertions, 138 deletions
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 <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stdio.h>
#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 <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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, &param, (t_wrapped_func)wrapped_cmd);
+ status = fork_wrap(fds, &param, (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 <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <nahaddac@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}