diff options
| -rw-r--r-- | include/eval.h | 27 | ||||
| -rw-r--r-- | include/minishell.h | 8 | ||||
| m--------- | libft | 0 | ||||
| -rw-r--r-- | src/builtin/builtin.c | 38 | ||||
| -rw-r--r-- | src/eval/cmd.c | 110 | ||||
| -rw-r--r-- | src/eval/error.c | 56 | ||||
| -rw-r--r-- | src/eval/eval.c | 93 | ||||
| -rw-r--r-- | src/main.c | 40 | ||||
| -rw-r--r-- | src/preprocess.c | 7 |
9 files changed, 226 insertions, 153 deletions
diff --git a/include/eval.h b/include/eval.h index 8fbbb1c..b90e8b6 100644 --- a/include/eval.h +++ b/include/eval.h @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:30 by charles #+# #+# */ -/* Updated: 2020/06/14 10:33:54 by charles ### ########.fr */ +/* Updated: 2020/06/14 12:52:45 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,7 +27,6 @@ typedef struct { - int p[2]; t_path path; t_env env; } t_eval_state; @@ -54,8 +53,9 @@ typedef struct { char *exec_path; char **argv; - char **envp; -} t_fork_param_execve; + t_env env; + t_builtin_func builtin; +} t_fork_param_cmd; /* ** eval.c @@ -71,11 +71,20 @@ bool exec_is_path(char *path_str); bool exec_is_valid(char *exec_path); char *exec_search_path(t_path path, char *path_var, char *exec_name); -/* -** pipe.c -*/ +enum e_error +{ + ERROR_AMBIGUOUS_REDIR, + ERROR_OPEN, + ERROR_CMD_NOT_FOUND, + ERROR_SYNTAX, +}; -// int pipe_setup_parent(t_cmd *cmd, int pipe_in[2], int pipe_out[2]); -// int pipe_setup_child(int pipe_in[2], int pipe_out[2]); +typedef struct +{ + enum e_error id; + int status; + char *msg; // if NULL call strerror + // char *basename; +} t_error; #endif diff --git a/include/minishell.h b/include/minishell.h index 2afbed9..07c2fa1 100644 --- a/include/minishell.h +++ b/include/minishell.h @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/26 15:33:51 by cacharle #+# #+# */ -/* Updated: 2020/06/12 11:57:36 by charles ### ########.fr */ +/* Updated: 2020/06/14 16:03:25 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -95,8 +95,8 @@ struct s_builtin_entry t_builtin_func func; }; -int builtin_dispatch_run(char **argv, t_env env); -bool builtin_check_exec_name(char *exec_name); +t_builtin_func builtin_search_func(char *name); + int builtin_echo(char **argv, t_env env); int builtin_cd(char **argv, t_env env); int builtin_pwd(char **argv, t_env env); @@ -109,6 +109,6 @@ int builtin_exit(char **argv, t_env env); ** preprocess.c */ -char **preprocess(t_ftvec *argv, t_env env); +char **preprocess(t_ftlst *tokens, t_env env); #endif diff --git a/libft b/libft -Subproject 4f4fa0d6ba8f42da8d72257b50517c222c06249 +Subproject 984a683f93a1a061714544532192b88b355ca5d 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/eval/cmd.c b/src/eval/cmd.c new file mode 100644 index 0000000..2896ab6 --- /dev/null +++ b/src/eval/cmd.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/06/14 10:41:31 by charles #+# #+# */ +/* Updated: 2020/06/14 12:52:59 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 (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)); +} + +/* +** \brief execve syscall wrapper passed it to fork_wrap +** \param param function params +** \return execve return value +*/ + +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; + + // check in and out (single string) + // argv[0]: [string]: ambiguous redirect code 1 + + // check in and out (exist) + // argv[0]: [string]: No such file or directory (probably from errno) + + return (0); + /* if (in != NULL) */ + /* { */ + /* char **redir_in = preprocess(in); */ + /* if (redir_in[1] != NULL) */ + /* ambiguous; */ + /* if ((fd_in = open(cmd->in, O_RDONLY)) == -1) */ + /* file error; */ + /* } */ + /* */ + /* if (out != NULL) */ + /* { */ + /* char **redir_out = preprocess(out); */ + /* if (redir_out[1] != NULL) */ + /* ambiguous; */ + /* if ((fd_out = open(cmd->out, (is_append ? O_APPEND : O_WRONLY) | O_CREAT)) == -1) */ + /* file error; */ + /* } */ + /* */ + /* char **argv = preprocess(cmd_argv); */ + /* */ + /* param.builtin = builtin_search_func(argv[0]); */ + /* if (param.builtin) */ + /* param.exec_path = exec_search_path(path, env_search(env, "PATH"), argv[0]); */ + /* */ + /* // get cmd path */ + /* // argv[0]: [string]: command not found code 127 */ + /* if (param.exec_path == NULL) */ + /* not_found; */ + /* */ + /* param.argv = argv; */ + /* param.env = env; */ + /* return (fork_wrap(fd_in, fd_out, ¶m, &execve_wrapper)); */ +} 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 */ @@ -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/14 16:04:41 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -79,27 +79,29 @@ int main(int argc, char **argv, char **envp) /* 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); + t_ftlst *l = NULL; + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$TERM$LFS$TERM$TERM."))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$$LFS$TERM$TERM."))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "*/*.c"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "src/*.c include/*.h"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$A$B"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "\\$TERM"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "$TER\\M"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR, "\\\\"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_SINGLE, "''''$TEST\\TEST"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE, ",$TEST,$B,"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE , "$TEST"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_DOUBLE | TAG_STICK, "$TEST"))); + ft_lstpush_back(&l, ft_lstnew(token_new(TAG_STR_SINGLE, "$TEST"))); + 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_split_destroy(tmp); */ ft_vecdestroy(env, free); return (0); } diff --git a/src/preprocess.c b/src/preprocess.c index badf3cf..22f42ab 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,7 +6,7 @@ /* 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/14 16:02:46 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -113,11 +113,14 @@ static void st_iter_func_unwrap_token(void **addr) *(char**)addr = content; } -char **preprocess(t_ftvec *argv, t_env env) +char **preprocess(t_ftlst *tokens, t_env env) { size_t i; t_token *token; + t_ftvec *argv; + if ((argv = ft_vecfrom_lst(tokens)) == NULL) + return (NULL); i = -1; while (++i < argv->size) { |
