aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.c3
-rw-r--r--src/builtin/builtin.c38
-rw-r--r--src/builtin/echo.c7
-rw-r--r--src/eval/cmd.c98
-rw-r--r--src/eval/error.c56
-rw-r--r--src/eval/eval.c93
-rw-r--r--src/eval/redir.c80
-rw-r--r--src/lexer/token.c20
-rw-r--r--src/main.c255
-rwxr-xr-xsrc/parse/parse.c16
-rw-r--r--src/preprocess.c34
11 files changed, 464 insertions, 236 deletions
diff --git a/src/ast.c b/src/ast.c
index 99d1db3..1a5f7eb 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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, &param, &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, &param, &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);
+}
diff --git a/src/main.c b/src/main.c
index 14da075..8fa91b3 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/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);
+}