aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-06-14 16:07:19 +0200
committerCharles <sircharlesaze@gmail.com>2020-06-14 16:07:19 +0200
commit47fff4418d3a83ae214429f395232c3536ff03c4 (patch)
tree8dd1021d3ae899b80cf052ae42a40c4bc965c654
parent26ddbd7146f65a2cf100713f422a9ab5b1890620 (diff)
downloadminishell-47fff4418d3a83ae214429f395232c3536ff03c4.tar.gz
minishell-47fff4418d3a83ae214429f395232c3536ff03c4.tar.bz2
minishell-47fff4418d3a83ae214429f395232c3536ff03c4.zip
Added eval cmd and error handling draft, Updated preprocessing for list
-rw-r--r--include/eval.h27
-rw-r--r--include/minishell.h8
m---------libft0
-rw-r--r--src/builtin/builtin.c38
-rw-r--r--src/eval/cmd.c110
-rw-r--r--src/eval/error.c56
-rw-r--r--src/eval/eval.c93
-rw-r--r--src/main.c40
-rw-r--r--src/preprocess.c7
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, &param, &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, &param, &execve_wrapper)); */
-/* } */
-/* */
+
/* #<{(| */
/* ** \brief Evaluate a line */
/* ** \param state State of the evaluation */
diff --git a/src/main.c b/src/main.c
index 5d3e9d8..0f5b92c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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)
{