aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile5
-rw-r--r--include/parser.h23
-rw-r--r--src/ast.c7
-rw-r--r--src/debug.c167
-rw-r--r--src/eval/eval.c8
-rw-r--r--src/eval/operation.c105
-rw-r--r--src/main.c4
-rw-r--r--src/parser/parser.c44
9 files changed, 241 insertions, 123 deletions
diff --git a/.gitignore b/.gitignore
index afd864a..f70fd1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@ tmp/*
a.out
vgcore.*
*.orig
+*.dSYM
diff --git a/Makefile b/Makefile
index 1ea268f..0aabc5a 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@
# By: cacharle <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/02/03 04:14:24 by cacharle #+# #+# #
-# Updated: 2020/09/14 19:10:10 by charles ### ########.fr #
+# Updated: 2020/10/02 12:52:19 by cacharle ### ########.fr #
# #
# **************************************************************************** #
@@ -25,7 +25,8 @@ OBJDIRS = $(shell find $(SRCDIR) -type d | sed 's/src/$(OBJDIR)/')
INCLUDE = $(shell find $(INCLUDEDIR) -name "*.h")
-SRC = $(shell find $(SRCDIR) -name "*.c")
+SRC = $(shell find $(SRCDIR) -type f -name "*.c")
+
OBJ = $(SRC:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
diff --git a/include/parser.h b/include/parser.h
index ff644ed..d2d3351 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -6,7 +6,7 @@
/* By: cacharle <cacharle@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/28 09:00:00 by cacharle #+# #+# */
-/* Updated: 2020/08/28 10:06:44 by charles ### ########.fr */
+/* Updated: 2020/10/06 08:35:42 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -54,17 +54,19 @@ typedef struct s_op
} t_op;
/*
-** \brief AST node tag (type)
-** \param TAG_CMD Command AST node
-** \param TAG_OP Operation AST node
-** \param TAG_PARENT Parenthesis AST node
+** \brief AST node tag (type)
+** \param TAG_CMD Command AST node
+** \param TAG_OP Operation AST node
+** \param TAG_PARENT Parenthesis AST node
+** \param TAG_PIPELINE Pipeline AST node
*/
-enum e_ast
+enum e_ast
{
AST_CMD,
AST_OP,
AST_PARENT,
+ AST_PIPELINE,
};
/*
@@ -72,6 +74,7 @@ enum e_ast
** \param tag Node tag
** \param op Operation struct
** \param cmd_argv Command argv tokens
+** \param pipline List of commands in a pipeline
** \param parend_ast AST inside parenthesis
** \param redirs Redirections tokens
*/
@@ -83,6 +86,7 @@ typedef struct s_ast
{
t_op op;
t_tok_lst *cmd_argv;
+ t_ftlst *pipeline;
struct s_ast *parent_ast;
};
t_tok_lst *redirs;
@@ -102,18 +106,13 @@ void ast_destroy(t_ast *ast);
typedef struct s_parsed
{
bool syntax_error;
- union
- {
- t_ast *ast;
- t_tok_lst *redir; // more general
- };
+ t_ast *ast;
t_tok_lst *rest;
} t_parsed;
t_parsed *parsed_new(t_ast *ast, t_tok_lst *rest);
t_parsed *parsed_error(const char *format, ...);
-
/*
** parse.c
*/
diff --git a/src/ast.c b/src/ast.c
index 2bb90d9..6c1e51b 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -6,7 +6,7 @@
/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:05:42 by charles #+# #+# */
-/* Updated: 2020/08/27 20:31:48 by charles ### ########.fr */
+/* Updated: 2020/10/06 09:58:35 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -57,6 +57,11 @@ void ast_destroy(t_ast *ast)
ast_destroy(ast->op.right);
}
else if (ast->tag == AST_PARENT)
+ {
ast_destroy(ast->parent_ast);
+ tok_lst_destroy(&ast->redirs, free);
+ }
+ else if (ast->tag == AST_PIPELINE)
+ ft_lstdestroy(&ast->pipeline, (void (*)(void*))ast_destroy);
free(ast);
}
diff --git a/src/debug.c b/src/debug.c
index 3fe7784..42c34eb 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -6,19 +6,31 @@
/* By: charles <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/09/16 15:58:35 by charles #+# #+# */
-/* Updated: 2020/09/16 16:18:11 by charles ### ########.fr */
+/* Updated: 2020/10/06 13:14:44 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdio.h>
#include "lexer.h"
+#include "parser.h"
void debug_tok_lst(t_tok_lst *tokens)
{
while (tokens != NULL)
{
// FIXME libft for safer correction
- printf("[%#06x] |%s|%s\n", tokens->tag, tokens->content, tokens->tag & TAG_STICK ? " STICK" : "");
+ printf("[%#06x] |%s|%s\n", tokens->tag, tokens->content,
+ tokens->tag & TAG_STICK ? " STICK" : "");
+ tokens = tokens->next;
+ }
+}
+
+void debug_tok_lst_line(t_tok_lst *tokens)
+{
+ while (tokens != NULL)
+ {
+ // FIXME libft for safer correction
+ printf("|%s| ", tokens->content);
tokens = tokens->next;
}
}
@@ -35,66 +47,91 @@ int debug_lexer(char *input)
return (status);
}
-/* void token_debug(void *v) */
-/* { */
-/* t_token *t; */
-/* */
-/* t= v; */
-/* printf("[%4d %d] (%s)\n", t->tag, !!(t->tag & TAG_STICK), t->content); */
-/* } */
-/* */
-/* void token_put(void *v) */
-/* { */
-/* t_token *t; */
-/* */
-/* t= v; */
-/* printf("%s ", t->content); */
-/* } */
-/* */
-/* void print_level(int level) */
-/* { */
-/* while (level-- > 0) */
-/* printf(" "); */
-/* } */
-/* */
-/* void ast_print(int level, t_ast *ast) */
-/* { */
-/* if (ast->tag == AST_PARENT) */
-/* { */
-/* print_level(level); */
-/* printf("parent: redir [ "); */
-/* ft_lstiter(ast->redirs, token_put); */
-/* printf(" ]\n"); */
-/* ast_print(level + 1, ast->parent_ast); */
-/* } */
-/* else if (ast->tag == AST_CMD) */
-/* { */
-/* print_level(level); */
-/* printf("cmd: [ "); */
-/* ft_lstiter(ast->cmd_argv, token_put); */
-/* printf(" ] redirs: ["); */
-/* ft_lstiter(ast->redirs, token_put); */
-/* printf(" ]"); */
-/* } */
-/* else if (ast->tag == AST_OP) { */
-/* #<{(| printf("SEP: %d\n", ast->op.sep); |)}># */
-/* print_level(level); */
-/* #<{(| 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"); */
-/* } */
-/* } */
+void print_level(int level)
+{
+ while (level-- > 0)
+ printf(" ");
+}
+
+void ast_print(int level, t_ast *ast)
+{
+ /* printf("%p\n", ast); */
+ if (ast == NULL)
+ return ;
+ if (ast->tag == AST_PARENT)
+ {
+ print_level(level);
+ printf("parent: redir [ ");
+ debug_tok_lst_line(ast->redirs);
+ printf(" ]\n");
+ ast_print(level + 1, ast->parent_ast);
+ }
+ else if (ast->tag == AST_PIPELINE)
+ {
+ 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);
+ printf("\n");
+ curr = curr->next;
+ }
+ print_level(level);
+ printf(" }\n");
+ }
+ else if (ast->tag == AST_CMD)
+ {
+ print_level(level);
+ printf("cmd: [ ");
+ debug_tok_lst_line(ast->cmd_argv);
+ printf(" ] redirs: [");
+ debug_tok_lst_line(ast->redirs);
+ 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");
+ }
+}
+
+int debug_parser(char *input)
+{
+ int status;
+ t_tok_lst *out;
+
+ status = lexer(input, &out);
+ if (status != 0)
+ {
+ printf("Lexer error\n");
+ debug_tok_lst(out);
+ return (status);
+ }
+ t_parsed *ret = parse(out);
+ if (ret == NULL || ret->syntax_error)
+ return (1);
+ ast_print(0, ret->ast);
+ return (status);
+}
diff --git a/src/eval/eval.c b/src/eval/eval.c
index 2775f9e..d2eb822 100644
--- a/src/eval/eval.c
+++ b/src/eval/eval.c
@@ -6,7 +6,7 @@
/* By: charles <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/09/13 20:38:06 by charles #+# #+# */
-/* Updated: 2020/09/16 16:29:20 by charles ### ########.fr */
+/* Updated: 2020/10/06 12:57:33 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -74,11 +74,13 @@ int fork_wrap(
int eval(int fds[2], t_env env, t_ast *ast, pid_t *child_pid, int fd_to_close)
{
- if (ast->tag == AST_PARENT)
- return (eval_parenthesis(fds, env, ast, child_pid, fd_to_close));
if (ast->tag == AST_OP)
return (eval_operation(fds, env, ast));
if (ast->tag == AST_CMD)
return (eval_cmd(fds, env, ast, child_pid, fd_to_close));
+ if (ast->tag == AST_PIPELINE)
+ return (eval_pipeline(fds, env, ast));
+ if (ast->tag == AST_PARENT)
+ return (eval_parenthesis(fds, env, ast, child_pid, fd_to_close));
return (EVAL_FATAL);
}
diff --git a/src/eval/operation.c b/src/eval/operation.c
index fbdf5bb..a54b657 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/09/15 20:30:27 by charles ### ########.fr */
+/* Updated: 2020/10/06 15:53:12 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -17,51 +17,84 @@ int eval_operation(int fds[2], t_env env, t_ast *ast)
int status;
int left_fds[2];
int right_fds[2];
- int p[2];
left_fds[FD_READ] = fds[FD_READ];
left_fds[FD_WRITE] = FD_NONE;
right_fds[FD_READ] = FD_NONE;
right_fds[FD_WRITE] = fds[FD_WRITE];
- if (ast->op.sep == TAG_PIPE)
- {
- pipe(p);
- left_fds[FD_WRITE] = p[FD_WRITE];
- right_fds[FD_READ] = p[FD_READ];
-
- pid_t left_pid;
- pid_t right_pid;
-
- /* left_pid = fork(); */
- /* if (left_pid != 0) */
- /* { */
- /* dup2(p[FD_WRITE], STDOUT_FILENO); */
- /* close(p[FD_READ]); */
- /* exit(eval(left_fds, env, ast->op.left, NULL)); */
- /* } */
- /* */
- /* right_pid = fork(); */
- /* if (right_pid != 0) */
- /* { */
- /* dup2(p[FD_READ], STDIN_FILENO); */
- /* close(p[FD_WRITE]); */
- /* exit(eval(right_fds, env, ast->op.right, NULL)); */
- /* } */
- eval(left_fds, env, ast->op.left, &left_pid, p[FD_READ]);
- close(p[FD_WRITE]);
- status = eval(right_fds, env, ast->op.right, &right_pid, p[FD_WRITE]);
- close(p[FD_READ]);
-
- wait(&left_pid);
- wait(&left_pid);
- return (status);
- }
if ((status = eval(left_fds, env, ast->op.left, NULL, FD_NONE)) == EVAL_FATAL)
return (EVAL_FATAL);
g_state.last_status = status;
if ((ast->op.sep == TAG_AND && status != 0) ||
- (ast->op.sep == TAG_PIPE && status != 0) ||
(ast->op.sep == TAG_OR && status == 0))
return (status);
return (eval(right_fds, env, ast->op.right, NULL, FD_NONE));
}
+
+/* pid_t run_piped_child(t_env env, t_ast *ast, int copied, int closed) */
+/* { */
+/* pid_t pid; */
+/* int fds[2]; */
+/* */
+/* pid = fork(); */
+/* if (pid == 0) */
+/* { */
+/* dup2(copied, STDOUT_FILENO); */
+/* close(closed); */
+/* fds[0] = FD_NONE; */
+/* fds[1] = FD_NONE; */
+/* exit(eval(fds, env, ast, NULL, FD_NONE)); */
+/* } */
+/* return (pid); */
+/* } */
+
+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); */
+
+ prev_output = STDIN_FILENO;
+ curr = ast->pipeline;
+
+
+ // create pipe
+ // fork
+ // dup2 pipe write -> stdout
+ // dup2 prev_output -> stdin
+
+ while (curr->next != NULL)
+ {
+ pipe(p);
+
+ int pid = fork();
+ if (pid == 0)
+ {
+ dup2(p[FD_WRITE], STDOUT_FILENO);
+ if (prev_output != STDIN_FILENO)
+ dup2(prev_output, STDIN_FILENO);
+ close(p[FD_READ]);
+ exit(eval(fds, env, curr->data, NULL, FD_NONE));
+ }
+ close(p[FD_WRITE]);
+ prev_output = p[FD_READ];
+ curr = curr->next;
+ }
+
+ int pid = fork();
+ if (pid == 0)
+ {
+ /* dup2(p[FD_WRITE], STDOUT_FILENO); */
+ if (prev_output != STDIN_FILENO)
+ dup2(prev_output, STDIN_FILENO);
+ close(p[FD_WRITE]);
+ exit(eval(fds, env, curr->data, NULL, FD_NONE));
+ }
+
+ while (wait(NULL) != -1)
+ ;
+ return (0);
+}
diff --git a/src/main.c b/src/main.c
index 411bd43..3398814 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,7 +6,7 @@
/* By: cacharle <cacharle@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */
-/* Updated: 2020/09/16 19:51:55 by charles ### ########.fr */
+/* Updated: 2020/10/06 10:36:28 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -110,6 +110,8 @@ int main(int argc, char **argv, char **envp)
g_state.last_status = 0;
if (argc == 3 && ft_strcmp(argv[1], "-l") == 0)
return (debug_lexer(argv[2]));
+ if (argc == 3 && ft_strcmp(argv[1], "-p") == 0)
+ return (debug_parser(argv[2]));
if (argc == 3 && ft_strcmp(argv[1], "-c") == 0)
{
status = execute(env, argv[2]);
diff --git a/src/parser/parser.c b/src/parser/parser.c
index 3a61a2c..0e3fbaf 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/09/17 11:20:53 by charles ### ########.fr */
+/* Updated: 2020/10/06 11:22:14 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -80,6 +80,43 @@ t_parsed *parse_cmd(t_tok_lst *input)
return (parsed_new(ast, input));
}
+t_parsed *parse_pipeline(t_tok_lst *input)
+{
+ t_parsed *expr;
+ t_parsed *tail;
+ t_ast *expr_ast;
+
+ expr = parse_expr(input);
+ if (expr == NULL || expr->syntax_error ||
+ expr->rest == NULL || expr->rest->tag != TAG_PIPE)
+ return (expr);
+ tail = parse_pipeline(expr->rest->next);
+ if (tail == NULL || tail->syntax_error)
+ return (tail);
+ expr_ast = expr->ast;
+ free(expr);
+ t_ast *pipeline_ast;
+ if (tail->ast->tag == AST_CMD)
+ {
+ pipeline_ast = ast_new(AST_PIPELINE);
+ if ((pipeline_ast->pipeline = ft_lstnew(tail->ast)) == NULL)
+ {
+ /* ast_destroy(expr_ast); */
+ /* ft_lstdestroy(&tail, NULL); */
+ return (NULL);
+ }
+ }
+ else
+ pipeline_ast = tail->ast;
+ if (ft_lstpush_front_node(&pipeline_ast->pipeline, expr_ast) == NULL)
+ {
+ /* ast_destroy(expr_ast); */
+ /* ft_lstdestroy(&tail, NULL); */
+ return (NULL);
+ }
+ return (parsed_new(pipeline_ast, tail->rest));
+}
+
/*
** parse and operation (| ; && ||)
*/
@@ -91,7 +128,7 @@ t_parsed *parse_op(t_tok_lst *input)
t_parsed *right;
enum e_tok sep_tag;
- left = parse_expr(input);
+ left = parse_pipeline(input);
if (left == NULL || left->syntax_error)
return (left);
input = left->rest;
@@ -99,7 +136,8 @@ t_parsed *parse_op(t_tok_lst *input)
return (left);
sep_tag = input->tag;
if (!(sep_tag & TAG_IS_SEP))
- return (parsed_error("syntax error near unexpected token `%s'\n", g_sep_str_lookup[sep_tag]));
+ return (parsed_error("syntax error near unexpected token `%s'\n",
+ g_sep_str_lookup[sep_tag]));
ft_lstpop_front((t_ftlst**)&input, free);
if (input == NULL && sep_tag == TAG_END)
return (left);