diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast.c | 3 | ||||
| -rw-r--r-- | src/builtin/builtin.c | 38 | ||||
| -rw-r--r-- | src/builtin/echo.c | 7 | ||||
| -rw-r--r-- | src/eval/cmd.c | 98 | ||||
| -rw-r--r-- | src/eval/error.c | 56 | ||||
| -rw-r--r-- | src/eval/eval.c | 93 | ||||
| -rw-r--r-- | src/eval/redir.c | 80 | ||||
| -rw-r--r-- | src/lexer/token.c | 20 | ||||
| -rw-r--r-- | src/main.c | 255 | ||||
| -rwxr-xr-x | src/parse/parse.c | 16 | ||||
| -rw-r--r-- | src/preprocess.c | 34 |
11 files changed, 464 insertions, 236 deletions
@@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:42 by charles #+# #+# */ -/* Updated: 2020/06/14 10:29:21 by charles ### ########.fr */ +/* Updated: 2020/06/15 13:01:20 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -46,6 +46,7 @@ void ast_destroy(t_ast *ast) { if (ast == NULL) return ; + ft_lstdestroy(&ast->cmd_argv, (void (*)(void*))token_destroy); if (ast->tag == AST_CMD) { ft_lstdestroy(&ast->cmd_argv, (void (*)(void*))token_destroy); diff --git a/src/builtin/builtin.c b/src/builtin/builtin.c index 65e8cf4..ae47a60 100644 --- a/src/builtin/builtin.c +++ b/src/builtin/builtin.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:11:01 by charles #+# #+# */ -/* Updated: 2020/04/01 17:46:48 by charles ### ########.fr */ +/* Updated: 2020/06/14 12:52:12 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,44 +31,16 @@ static struct s_builtin_entry g_builtin_lookup[] = { {"exit", builtin_exit}, }; -/* -** \brief Call builtin function associated with command name -** \param argv Arguments to the builtin 'main', -** with argv[0] being the executable name -** \param env Environment Vector -** \return Builtin main return status -*/ - -int builtin_dispatch_run(char **argv, t_env env) -{ - size_t i; - - i = 0; - while (i < sizeof(g_builtin_lookup) / sizeof(struct s_builtin_entry)) - { - if (ft_strcmp(g_builtin_lookup[i].name, argv[0]) == 0) - return (g_builtin_lookup[i].func(argv, env)); - i++; - } - return (BUILTIN_NOT_FOUND); -} - -/* -** \brief Check if executable name is a builtin -** \param exec_name Executable name -** \return True if executable name is a builtin -*/ - -bool builtin_check_exec_name(char *exec_name) +t_builtin_func builtin_search_func(char *name) { size_t i; i = 0; while (i < sizeof(g_builtin_lookup) / sizeof(struct s_builtin_entry)) { - if (ft_strcmp(g_builtin_lookup[i].name, exec_name) == 0) - return (true); + if (ft_strcmp(g_builtin_lookup[i].name, name) == 0) + return (g_builtin_lookup[i].func); i++; } - return (false); + return (NULL); } diff --git a/src/builtin/echo.c b/src/builtin/echo.c index 886c2ca..0c4ff8b 100644 --- a/src/builtin/echo.c +++ b/src/builtin/echo.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:10:47 by charles #+# #+# */ -/* Updated: 2020/04/02 11:18:16 by charles ### ########.fr */ +/* Updated: 2020/06/15 10:12:53 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,11 @@ int builtin_echo(char **argv, t_env env) bool newline; (void)env; + if (argv[1] == NULL) + { + ft_putchar('\n'); + return (0); + } newline = !ft_strcmp(argv[1], "-n") == 0; if (!newline) argv++; diff --git a/src/eval/cmd.c b/src/eval/cmd.c new file mode 100644 index 0000000..9468cb2 --- /dev/null +++ b/src/eval/cmd.c @@ -0,0 +1,98 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/06/14 10:41:31 by charles #+# #+# */ +/* Updated: 2020/06/15 11:09:38 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "eval.h" + +/* +** \brief Wrap a function in a fork +** \param fd_in fork input file descriptor +** \param fd_out fork output file descriptor +** \param passed param of the wrapped function +** \param wrapped function to wrap +*/ + +int fork_wrap( + int fd_in, + int fd_out, + void *passed, + int (*wrapped)(void *param)) +{ + int status; + pid_t child_pid; + + if ((child_pid = fork()) == -1) + return (-1); + if (child_pid == 0) + { + if ((fd_in != MS_NO_FD && dup2(fd_in, STDIN_FILENO) == -1) || + (fd_out != MS_NO_FD && dup2(fd_out, STDOUT_FILENO) == -1)) + exit(EXIT_FAILURE); + if ((status = wrapped(passed)) == -1) + exit(EXIT_FAILURE); + exit(status); + } + wait(&child_pid); + return (WEXITSTATUS(child_pid)); +} + +int forked_cmd(void *void_param) +{ + t_fork_param_cmd *param; + + param = void_param; + + if (param->builtin != NULL) + return (param->builtin(param->argv, param->env)); + else + return (execve(param->exec_path, param->argv, (char**)param->env->data)); +} + +int eval_cmd(t_env env, t_path path, t_ast *ast) +{ + t_fork_param_cmd param; + int fd_in; + int fd_out; + char **argv; + + fd_in = MS_NO_FD; + fd_out = MS_NO_FD; + if (!redir_extract(ast->redirs, env, &fd_in, &fd_out)) + { + ast->redirs = NULL; + return (-1); + } + ast->redirs = NULL; + + if ((argv = preprocess(&ast->cmd_argv, env)) == NULL) + { + ast->cmd_argv = NULL; + return (-1); + } + + param.builtin = builtin_search_func(argv[0]); + if (param.builtin == NULL) + { + param.exec_path = exec_search_path(path, env_search(env, "PATH"), argv[0]); + if (param.exec_path == NULL) + { + error_eval_put(ERROR_CMD_NOT_FOUND, argv[0]); + ft_split_destroy(argv); + return (-1); // return error status + } + } + + param.argv = argv; + param.env = env; + int ret = fork_wrap(fd_in, fd_out, ¶m, &forked_cmd); + ft_split_destroy(argv); + return (ret); +} diff --git a/src/eval/error.c b/src/eval/error.c new file mode 100644 index 0000000..016a751 --- /dev/null +++ b/src/eval/error.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/06/14 11:02:52 by charles #+# #+# */ +/* Updated: 2020/06/14 12:19:14 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "eval.h" + +static t_error g_errors[] = +{ + {ERROR_AMBIGUOUS_REDIR, 1, "ambiguous redirect"}, + {ERROR_OPEN, 1, NULL}, + {ERROR_CMD_NOT_FOUND, 127, "command not found"}, + {ERROR_SYNTAX, 2, "syntax error near unexpected token "}, +}; + +t_error *st_error_get(enum e_error id) +{ + size_t i; + t_error *match; + + match = NULL; + i = 0; + while (i < sizeof(g_errors) / sizeof(t_error)) + { + if (g_errors[i].id == id) + match = &g_errors[i]; + i++; + } + return (match); +} + +void error_eval_put(enum e_error id, char *unexpected) +{ + t_error *err; + + err = st_error_get(id); + ft_putstr_fd("minishell: ", STDERR_FILENO); + ft_putstr_fd(unexpected, STDERR_FILENO); + ft_putstr_fd(": ", STDERR_FILENO); + if (err->msg == NULL) + ft_putendl_fd(strerror(errno), STDERR_FILENO); + else + ft_putendl_fd(err->msg, STDERR_FILENO); +} + +int error_status(enum e_error id) +{ + return (st_error_get(id)->status); +} diff --git a/src/eval/eval.c b/src/eval/eval.c index 1e0a8d7..c1b580f 100644 --- a/src/eval/eval.c +++ b/src/eval/eval.c @@ -6,96 +6,17 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:21 by charles #+# #+# */ -/* Updated: 2020/06/14 10:34:11 by charles ### ########.fr */ +/* Updated: 2020/06/14 10:42:37 by charles ### ########.fr */ /* */ /* ************************************************************************** */ -/* #<{(| */ -/* ** \file eval.c */ -/* ** \brief Evaluation of an AST */ -/* |)}># */ -/* */ +/* +** \file eval.c +** \brief Evaluation of an AST +*/ + /* #include "eval.h" */ -/* */ -/* #<{(| */ -/* ** \brief Wrap a function in a fork */ -/* ** \param fd_in fork input file descriptor */ -/* ** \param fd_out fork output file descriptor */ -/* ** \param passed param of the wrapped function */ -/* ** \param wrapped function to wrap */ -/* |)}># */ -/* */ -/* int fork_wrap( */ -/* int fd_in, */ -/* int fd_out, */ -/* void *passed, */ -/* int (*wrapped)(void *param)) */ -/* { */ -/* int status; */ -/* pid_t child_pid; */ -/* */ -/* if ((child_pid = fork()) == -1) */ -/* return (-1); */ -/* if (child_pid == 0) */ -/* { */ -/* if (dup2(STDIN_FILENO, fd_in) == -1 || */ -/* dup2(STDOUT_FILENO, fd_out) == -1) */ -/* exit(EXIT_FAILURE); */ -/* if ((status = wrapped(passed)) == -1) */ -/* exit(EXIT_FAILURE); */ -/* exit(status); */ -/* } */ -/* wait(&child_pid); */ -/* return (WEXITSTATUS(child_pid)); */ -/* } */ -/* */ -/* int run_builtin(t_eval_state *state, char **argv) */ -/* { */ -/* return (builtin_dispatch_run(argv, state->env)); */ -/* } */ -/* */ -/* #<{(| */ -/* ** \brief execve syscall wrapper passed it to fork_wrap */ -/* ** \param param function params */ -/* ** \return execve return value */ -/* |)}># */ -/* */ -/* int execve_wrapper(void *param) */ -/* { */ -/* return (execve( */ -/* ((t_fork_param_execve*)param)->exec_path, */ -/* ((t_fork_param_execve*)param)->argv, */ -/* ((t_fork_param_execve*)param)->envp */ -/* )); */ -/* } */ -/* */ -/* #<{(| */ -/* ** \brief Evaluate a command */ -/* ** \param state Evaluation state */ -/* ** \param cmd Command to evaluate */ -/* ** \return Executable status or -1 on error */ -/* |)}># */ -/* */ -/* static int eval_cmd(int fd_in, int fd_out, t_eval_state *state, t_cmd *cmd) */ -/* { */ -/* t_fork_param_execve param; */ -/* */ -/* if (builtin_check_exec_name(cmd->argv[0])) */ -/* return (run_builtin(state, cmd->argv)); */ -/* param.exec_path = exec_search_path( */ -/* state->path, env_search(state->env, "PATH"), cmd->argv[0]); */ -/* if (param.exec_path == NULL) */ -/* return (-1); */ -/* if (cmd->in != NULL && (fd_in = open(cmd->in, O_RDONLY)) == -1) */ -/* return (-1); */ -/* if (cmd->out != NULL && (fd_out = open(cmd->out, */ -/* (cmd->is_append ? O_APPEND : O_WRONLY) | O_CREAT)) == -1) */ -/* return (-1); */ -/* param.argv = cmd->argv; */ -/* param.envp = (char**)state->env->data; */ -/* return (fork_wrap(fd_in, fd_out, ¶m, &execve_wrapper)); */ -/* } */ -/* */ + /* #<{(| */ /* ** \brief Evaluate a line */ /* ** \param state State of the evaluation */ diff --git a/src/eval/redir.c b/src/eval/redir.c new file mode 100644 index 0000000..c6f98d4 --- /dev/null +++ b/src/eval/redir.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redir.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/06/15 11:05:34 by charles #+# #+# */ +/* Updated: 2020/06/15 11:44:38 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "eval.h" + +static enum e_token_tag st_lst_tag(t_ftlst *lst) +{ + return (((t_token*)lst->data)->tag); +} + +static bool st_open_replace(int *fd, char *filename, int oflag) +{ + if (*fd != MS_NO_FD) + close(*fd); + if (oflag & O_CREAT) + *fd = open(filename, oflag, 0644); + else + *fd = open(filename, oflag); + if (*fd == -1) + { + error_eval_put(ERROR_OPEN, filename); + free(filename); + return (false); + } + return (true); +} + +bool redir_extract( + t_ftlst *redirs, + t_env env, + int *fd_in, + int *fd_out) +{ + t_ftlst *after; + t_ftlst *curr; + char *filename; + + if (redirs == NULL) + return (true); + if (!(st_lst_tag(redirs) & TAG_IS_REDIR) || redirs->next == NULL + || !(st_lst_tag(redirs->next) & TAG_IS_STR)) + return (false); + curr = redirs->next; + while (curr != NULL && st_lst_tag(curr) & TAG_IS_STR) + { + if (curr->next == NULL || st_lst_tag(curr->next) & TAG_IS_REDIR) + { + after = curr->next; + curr->next = NULL; + } + curr = curr->next; + } + if ((filename = preprocess_filename(&redirs->next, env)) == NULL) + { + token_destroy_lst2(redirs, after); + return (false); + } + if ((st_lst_tag(redirs) == TAG_REDIR_IN + && !st_open_replace(fd_in, filename, O_RDONLY)) + || (st_lst_tag(redirs) == TAG_REDIR_OUT + && !st_open_replace(fd_out, filename, O_WRONLY | O_CREAT | O_TRUNC)) + || (st_lst_tag(redirs) == TAG_REDIR_APPEND + && !st_open_replace(fd_out, filename, O_WRONLY | O_CREAT | O_APPEND))) + { + token_destroy_lst2(redirs, after); + return (false); + } + token_destroy_lst(redirs); + free(filename); + return (redir_extract(after, env, fd_in, fd_out)); +} diff --git a/src/lexer/token.c b/src/lexer/token.c index 490c7b1..966a443 100644 --- a/src/lexer/token.c +++ b/src/lexer/token.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/09 13:38:08 by charles #+# #+# */ -/* Updated: 2020/06/09 17:55:23 by charles ### ########.fr */ +/* Updated: 2020/06/15 11:38:24 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,10 +16,11 @@ t_token *token_new(enum e_token_tag tag, char *content) { t_token *token; - if (content == NULL - || (token = (t_token*)malloc(sizeof(t_token))) == NULL) + if ((token = (t_token*)malloc(sizeof(t_token))) == NULL) return (NULL); - if ((token->content = ft_strdup(content)) == NULL) + if (content == NULL) + token->content = NULL; + else if ((token->content = ft_strdup(content)) == NULL) { free(token); return (NULL); @@ -33,3 +34,14 @@ void token_destroy(t_token *token) free(token->content); free(token); } + +void token_destroy_lst(t_ftlst *tokens) +{ + ft_lstdestroy(&tokens, (void (*)(void*))token_destroy); +} + +void token_destroy_lst2(t_ftlst *tokens1, t_ftlst *tokens2) +{ + ft_lstdestroy(&tokens1, (void (*)(void*))token_destroy); + ft_lstdestroy(&tokens2, (void (*)(void*))token_destroy); +} @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/06/14 10:36:06 by charles ### ########.fr */ +/* Updated: 2020/06/15 13:12:21 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,109 +19,162 @@ #include "ast.h" #include "lexer.h" #include "parser.h" +#include "eval.h" -// int main(int argc, char **argv, char **envp) -// { -// (void)argc; -// (void)argv; -// /* (void)envp; */ -// /* t_path path; */ -// t_env env; -// /* char *line; */ -// /* int ret; */ -// env = env_from_array(envp); -// /* path = path_update(NULL, env_search(env, "PATH")); */ -// /* */ -// /* t_ast *ast; */ -// /* t_line line; */ -// /* t_cmd cmd; */ -// /* t_eval_state state; */ -// /* */ -// /* cmd.argv = ft_split("ls -l", ' '); */ -// /* cmd.in = NULL; */ -// /* cmd.out = NULL; */ -// /* cmd.is_append = false; */ -// /* */ -// /* line.left = ast_new(TAG_CMD, &cmd); */ -// /* line.right = NULL; */ -// /* line.sep = SEP_END; */ -// /* ast = ast_new(TAG_LINE, &line); */ -// /* printf("%p\n", ast); */ -// /* printf("%d\n", ast->tag); */ -// /* printf("%p\n", ast->data.line.left); */ -// /* printf("%p\n", ast->data.line.right); */ -// /* printf("%d\n", ast->data.line.left->tag); */ -// /* printf("%p\n", ast->data.line.left->data.cmd.argv); */ -// /* printf("%s\n", ast->data.line.left->data.cmd.argv[0]); */ -// /* printf("%s\n", ast->data.line.left->data.cmd.argv[1]); */ -// /* state.pipe_in[0] = -1; */ -// /* state.pipe_in[1] = -1; */ -// /* state.pipe_out[0] = -1; */ -// /* state.pipe_out[1] = -1; */ -// /* state.path = path; */ -// /* state.env = env; */ -// /* t_io_frame frame; */ -// /* io_frame_init(&frame); */ -// /* printf("ret: %d %s\n", eval(&frame,&state, ast), strerror(errno)); */ -// /* char buf[2048]; */ -// /* printf("%s\n", getcwd(buf, 2048)); */ -// /* builtin_env(NULL, state.env); */ -// /* ast_destroy(ast); */ -// /* while ((ret = ft_next_line(STDIN_FILENO, &line)) == 1) */ -// /* { */ -// /* if (eval(parse(line)) == -1) */ -// /* continue ; // and display error */ -// /* free(line); */ -// /* } */ -// /* free(line); */ -// /* ft_htdestroy(path, free); */ -// /* ms_glob("src#<{(|"); */ -// /* char *j = ms_glob("|)}>#*.c"); */ -// /* printf("%s\n", j); */ -// /* free(j); */ -// t_ftvec *v = ft_vecnew(32); -// ft_vecpush(v, token_new(TAG_STR, "$TERM$LFS$TERM$TERM.")); -// ft_vecpush(v, token_new(TAG_STR, "$$LFS$TERM$TERM.")); -// ft_vecpush(v, token_new(TAG_STR, "*/*.c$TERM")); -// ft_vecpush(v, token_new(TAG_STR, "src/*.c include/*.h")); -// ft_vecpush(v, token_new(TAG_STR, "$A$B")); -// ft_vecpush(v, token_new(TAG_STR, "\\$TERM")); -// ft_vecpush(v, token_new(TAG_STR, "$TER\\M")); -// ft_vecpush(v, token_new(TAG_STR, "\\\\")); -// ft_vecpush(v, token_new(TAG_STR_SINGLE, "''''$TEST\\TEST")); -// ft_vecpush(v, token_new(TAG_STR_DOUBLE, ",$TEST,$B,")); -// ft_vecpush(v, token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST")); -// ft_vecpush(v, token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST")); -// ft_vecpush(v, token_new(TAG_STR_DOUBLE , "$TEST")); -// ft_vecpush(v, token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST")); -// ft_vecpush(v, token_new(TAG_STR_SINGLE, "$TEST")); -// char **as = preprocess(v, env); -// char **tmp = as; -// while (*as != NULL) -// puts(*as++); -// ft_split_destroy(tmp); -// ft_vecdestroy(env, free); -// return (0); -// } +int main(int argc, char **argv, char **envp) +{ + t_path path; + t_env env; -///////////////////////////////////////////////////////////////////////////////////////// -// lexer main -///////////////////////////////////////////////////////////////////////////////////////// + env = env_from_array(envp); + path = path_update(NULL, env_search(env, "PATH")); -int main(int argc, char **argv) -{ - char *input; - t_ftlst *lst; + if (argc == 3 && ft_strcmp(argv[1], "-c") == 0) + { + t_ftlst *lex_out = lexer(argv[2]); + + t_ret *parser_out = parse(lex_out); - if (argv[1] == NULL) - return (0); - if (!(input = malloc(sizeof(char) * ft_strlen(argv[1]) + 1))) - return(0); - ft_strlcpy(input, argv[1], ft_strlen(argv[1]) + 1); + int eval_out = eval_cmd(env, path, parser_out->ast); + (void)eval_out; + } - lst = lexer(input); - parse(lst); - free(input); - exit(0); - return (0); + ft_htdestroy(path, free); + ft_vecdestroy(env, free); + return (0); } + +/* int main(int argc, char **argv, char **envp) */ +/* { */ +/* (void)argc; */ +/* (void)argv; */ +/* #<{(| (void)envp; |)}># */ +/* t_path path; */ +/* t_env env; */ +/* #<{(| char *line; |)}># */ +/* #<{(| int ret; |)}># */ +/* env = env_from_array(envp); */ +/* path = path_update(NULL, env_search(env, "PATH")); */ +/* #<{(| |)}># */ +/* #<{(| t_ast *ast; |)}># */ +/* #<{(| t_line line; |)}># */ +/* #<{(| t_cmd cmd; |)}># */ +/* #<{(| t_eval_state state; |)}># */ +/* #<{(| |)}># */ +/* #<{(| cmd.argv = ft_split("ls -l", ' '); |)}># */ +/* #<{(| cmd.in = NULL; |)}># */ +/* #<{(| cmd.out = NULL; |)}># */ +/* #<{(| cmd.is_append = false; |)}># */ +/* #<{(| |)}># */ +/* #<{(| line.left = ast_new(TAG_CMD, &cmd); |)}># */ +/* #<{(| line.right = NULL; |)}># */ +/* #<{(| line.sep = SEP_END; |)}># */ +/* #<{(| ast = ast_new(TAG_LINE, &line); |)}># */ +/* #<{(| printf("%p\n", ast); |)}># */ +/* #<{(| printf("%d\n", ast->tag); |)}># */ +/* #<{(| printf("%p\n", ast->data.line.left); |)}># */ +/* #<{(| printf("%p\n", ast->data.line.right); |)}># */ +/* #<{(| printf("%d\n", ast->data.line.left->tag); |)}># */ +/* #<{(| printf("%p\n", ast->data.line.left->data.cmd.argv); |)}># */ +/* #<{(| printf("%s\n", ast->data.line.left->data.cmd.argv[0]); |)}># */ +/* #<{(| printf("%s\n", ast->data.line.left->data.cmd.argv[1]); |)}># */ +/* #<{(| state.pipe_in[0] = -1; |)}># */ +/* #<{(| state.pipe_in[1] = -1; |)}># */ +/* #<{(| state.pipe_out[0] = -1; |)}># */ +/* #<{(| state.pipe_out[1] = -1; |)}># */ +/* #<{(| state.path = path; |)}># */ +/* #<{(| state.env = env; |)}># */ +/* #<{(| t_io_frame frame; |)}># */ +/* #<{(| io_frame_init(&frame); |)}># */ +/* #<{(| printf("ret: %d %s\n", eval(&frame,&state, ast), strerror(errno)); |)}># */ +/* #<{(| char buf[2048]; |)}># */ +/* #<{(| printf("%s\n", getcwd(buf, 2048)); |)}># */ +/* #<{(| builtin_env(NULL, state.env); |)}># */ +/* #<{(| ast_destroy(ast); |)}># */ +/* #<{(| while ((ret = ft_next_line(STDIN_FILENO, &line)) == 1) |)}># */ +/* #<{(| { |)}># */ +/* #<{(| if (eval(parse(line)) == -1) |)}># */ +/* #<{(| continue ; // and display error |)}># */ +/* #<{(| free(line); |)}># */ +/* #<{(| } |)}># */ +/* #<{(| free(line); |)}># */ +/* #<{(| ms_glob("src#<{(|"); |)}># */ +/* #<{(| char *j = ms_glob("|)}>#*.c"); |)}># */ +/* #<{(| printf("%s\n", j); |)}># */ +/* #<{(| free(j); |)}># */ +/* */ +/* t_ftlst *args = NULL; */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "echo"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "bonjour"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "je"))); |)}># */ +/* */ +/* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "cat"))); */ +/* ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "-e"))); */ +/* */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "ls"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "-a"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "-l"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "$$LFS$TERM$TERM."))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "|)}>#*.c"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "src#<{(|.c include#<{(|.h"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "$A$B"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "\\$TERM"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "$TER\\M"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR, "\\\\"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR_SINGLE, "''''$TEST\\TEST"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR_DOUBLE, ",$TEST,$B,"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR_DOUBLE , "$TEST"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); |)}># */ +/* #<{(| ft_lstpush_back(&args, ft_lstnew(token_new(TAG_STR_SINGLE, "$TEST"))); |)}># */ +/* */ +/* t_ftlst *redirs = NULL; */ +/* ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_REDIR_IN, NULL))); */ +/* ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_STR, "bonjour"))); */ +/* ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_REDIR_APPEND, NULL))); */ +/* ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_STR, "yo"))); */ +/* ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_REDIR_OUT, NULL))); */ +/* ft_lstpush_back(&redirs, ft_lstnew(token_new(TAG_STR, "yo1"))); */ +/* */ +/* t_ast *ast = ast_new(AST_CMD); */ +/* ast->cmd_argv = args; */ +/* ast->redirs = redirs; */ +/* */ +/* printf("eval %d\n", eval_cmd(env, path, ast)); */ +/* ast_destroy(ast); */ +/* */ +/* */ +/* #<{(| char **as = preprocess(l, env); |)}># */ +/* #<{(| printf("%p\n", as); |)}># */ +/* #<{(| printf("%p\n", *as); |)}># */ +/* #<{(| char **tmp = as; |)}># */ +/* #<{(| while (*as != NULL) |)}># */ +/* #<{(| puts(*as++); |)}># */ +/* #<{(| ft_split_destroy(tmp); |)}># */ +/* ft_htdestroy(path, free); */ +/* ft_vecdestroy(env, free); */ +/* return (0); */ +/* } */ + +///////////////////////////////////////////////////////////////////////////////////////// +// lexer main +///////////////////////////////////////////////////////////////////////////////////////// + +/* int main(int argc, char **argv) */ +/* { */ +/* char *input; */ +/* t_ftlst *lst; */ +/* */ +/* if (argv[1] == NULL) */ +/* return (0); */ +/* if (!(input = malloc(sizeof(char) * ft_strlen(argv[1]) + 1))) */ +/* return(0); */ +/* ft_strlcpy(input, argv[1], ft_strlen(argv[1]) + 1); */ +/* */ +/* lst = lexer(input); */ +/* parse(lst); */ +/* free(input); */ +/* exit(0); */ +/* return (0); */ +/* } */ diff --git a/src/parse/parse.c b/src/parse/parse.c index bb19bea..a0d981f 100755 --- a/src/parse/parse.c +++ b/src/parse/parse.c @@ -13,7 +13,7 @@ t_ret *parse(t_ftlst *input) { t_ret *ret; - t_ret *first; + /* t_ret *first; */ enum e_token_tag tag; int i = 0; @@ -22,7 +22,7 @@ t_ret *parse(t_ftlst *input) ret->rest = input; ret->ast = NULL; ret->unexpected = NULL; - first = ret; + /* first = ret; */ while (ret->rest != NULL) { @@ -37,7 +37,7 @@ t_ret *parse(t_ftlst *input) ret->rest = ret->rest->next; if (ret->rest != NULL) ret->ast = parse_redir(ret->ast, ret->rest); - printf("%s\n","ici" ); + /* printf("%s\n","ici" ); */ ret->rest = ret->rest->next; if (ret->rest != NULL) { @@ -51,20 +51,20 @@ t_ret *parse(t_ftlst *input) } while(ret->ast->cmd_argv != NULL) { - printf("%s\n", ((t_token *)ret->ast->cmd_argv->data)->content); + /* printf("%s\n", ((t_token *)ret->ast->cmd_argv->data)->content); */ ret->ast->cmd_argv = ret->ast->cmd_argv->next; } while(ret->ast->redirs != NULL) { if (i == 0) { - printf("redir"); + /* printf("redir"); */ i++; } - printf("%s\n", ((t_token *)ret->ast->redirs->data)->content); + /* printf("%s\n", ((t_token *)ret->ast->redirs->data)->content); */ ret->ast->redirs = ret->ast->redirs->next; } - ast_destroy(ret->ast); - ft_lstdestroy(&ret->rest, (void (*)(void*))token_destroy); + /* ast_destroy(ret->ast); */ + /* ft_lstdestroy(&ret->rest, (void (*)(void*))token_destroy); */ return NULL; } diff --git a/src/preprocess.c b/src/preprocess.c index badf3cf..1c59e28 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,13 +6,14 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/06/14 10:33:17 by charles ### ########.fr */ +/* Updated: 2020/06/15 10:47:24 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" #include "ms_glob.h" #include "lexer.h" +#include "eval.h" static bool st_escapable(char c, enum e_token_tag tag) { @@ -113,11 +114,19 @@ static void st_iter_func_unwrap_token(void **addr) *(char**)addr = content; } -char **preprocess(t_ftvec *argv, t_env env) +// need to free argv on error +char **preprocess(t_ftlst **tokens, t_env env) { size_t i; t_token *token; + t_ftvec *argv; + if ((argv = ft_vecfrom_lst(*tokens)) == NULL) + { + ft_lstdestroy(tokens, NULL); + return (NULL); + } + ft_lstdestroy(tokens, NULL); i = -1; while (++i < argv->size) { @@ -154,3 +163,24 @@ char **preprocess(t_ftvec *argv, t_env env) ft_vecpush(argv, NULL); return ((char**)ft_vecunwrap(argv)); } + +// need to free tokens +char *preprocess_filename(t_ftlst **tokens, t_env env) +{ + char **strs; + char *ret; + + if ((strs = preprocess(tokens, env)) == NULL + || strs[0] == NULL) + return (NULL); + if (strs[1] != NULL) + { + // save tokens + error_eval_put(ERROR_AMBIGUOUS_REDIR, strs[1]); + ft_split_destroy(strs); + return (NULL); + } + ret = strs[0]; + free(strs); + return (ret); +} |
