aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ast.h8
-rw-r--r--include/eval.h1
-rw-r--r--src/ast.c42
-rw-r--r--src/eval/eval.c32
-rw-r--r--src/main.c48
-rw-r--r--src/path.c2
6 files changed, 117 insertions, 16 deletions
diff --git a/include/ast.h b/include/ast.h
index 4ee3396..63dc12c 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -6,6 +6,11 @@
** \brief AST structs
*/
+# include <stdlib.h>
+# include <stdbool.h>
+# include "libft_mem.h"
+# include "libft_util.h"
+
/**
** \brief Separator type
** \param SEP_END Regular command end `;`
@@ -77,4 +82,7 @@ struct s_ast
} data;
};
+t_ast *ast_new(t_ast_tag tag, void *data);
+void ast_destroy(t_ast *ast);
+
#endif
diff --git a/include/eval.h b/include/eval.h
index ec04ff5..0c3240a 100644
--- a/include/eval.h
+++ b/include/eval.h
@@ -15,7 +15,6 @@
typedef struct
{
- int status;
int in_pipe[2]; // need stack pipe
int out_pipe[2];
t_path path;
diff --git a/src/ast.c b/src/ast.c
new file mode 100644
index 0000000..7c3fb8f
--- /dev/null
+++ b/src/ast.c
@@ -0,0 +1,42 @@
+#include "ast.h"
+
+t_ast *ast_new(t_ast_tag tag, void *data)
+{
+ t_ast *ast;
+
+ if (data == NULL)
+ return (NULL);
+ if ((ast = (t_ast*)malloc(sizeof(t_ast))) == NULL)
+ return (NULL);
+ ft_bzero(ast, sizeof(t_ast));
+ ast->tag = tag;
+ if (tag == TAG_CMD)
+ ft_memcpy(&ast->data.cmd, (t_cmd*)data, sizeof(t_cmd));
+ else if (tag == TAG_LINE)
+ ft_memcpy(&ast->data.line, (t_line*)data, sizeof(t_line));
+ return (ast);
+}
+
+static void cmd_destroy(t_cmd *cmd)
+{
+ ft_split_destroy(cmd->argv);
+ free(cmd->in);
+ free(cmd->out);
+}
+
+static void line_destroy(t_line *line)
+{
+ ast_destroy(line->left);
+ ast_destroy(line->right);
+}
+
+void ast_destroy(t_ast *ast)
+{
+ if (ast == NULL)
+ return ;
+ if (ast->tag == TAG_CMD)
+ cmd_destroy(&ast->data.cmd);
+ else if (ast->tag == TAG_LINE)
+ line_destroy(&ast->data.line);
+ free(ast);
+}
diff --git a/src/eval/eval.c b/src/eval/eval.c
index d40c7f3..28cb386 100644
--- a/src/eval/eval.c
+++ b/src/eval/eval.c
@@ -18,19 +18,40 @@ static int eval_line(t_eval_state *state, t_line *line)
return (eval(state, line->right));
}
+static bool is_exec_path(char *path_str)
+{
+ return (ft_strncmp(path_str, "../", 3) == 0
+ || ft_strncmp(path_str, "./", 2) == 0
+ || ft_strncmp(path_str, "/", 1) == 0);
+}
+
+static bool is_valid_exec(char *exec_path)
+{
+ struct stat statbuf;
+
+ if (stat(exec_path, &statbuf) != 0)
+ return (false);
+ if (!S_ISREG(statbuf.st_mode)) // also need to manage link
+ return (false);
+ // could test permission but probably handled by execve
+ return (true);
+}
+
static char *search_exec_path(t_path path, char *path_var, char *exec_name)
{
- char *exec_path;
+ char *exec_path;
+ if (is_exec_path(exec_name))
+ return (exec_name);
// try current first
if ((exec_path = ft_htget(path, exec_name)) == NULL)
{
- if (path_update(path, path_var) == NULL)
+ if (path_update(path, path_var) == NULL) // optimise by not updating not changed path in ht
return (NULL);
if ((exec_path = ft_htget(path, exec_name)) == NULL)
return (NULL);
}
- return exec_path;
+ return (exec_path);
}
static int eval_cmd(t_eval_state *state, t_cmd *cmd)
@@ -38,7 +59,8 @@ static int eval_cmd(t_eval_state *state, t_cmd *cmd)
int child_pid;
char *exec_path;
- if ((exec_path = search_exec_path(state->path, ft_htget(state->env, "PATH"), cmd->argv[0])) == NULL)
+ if ((exec_path = search_exec_path(state->path,
+ ft_htget(state->env, "PATH"), cmd->argv[0])) == NULL)
return (-1);
if (cmd->in != NULL)
{
@@ -51,7 +73,6 @@ static int eval_cmd(t_eval_state *state, t_cmd *cmd)
(cmd->is_append ? O_WRONLY : O_APPEND) | O_CREAT)) < 0)
return (-1);
}
-
if ((child_pid = fork()) == -1)
return (-1);
if (child_pid == 0)
@@ -69,6 +90,7 @@ static int eval_cmd(t_eval_state *state, t_cmd *cmd)
int eval(t_eval_state *state, t_ast *ast)
{
+ errno = 0;
if (ast->tag == TAG_LINE)
return eval_line(state, &ast->data.line);
if (ast->tag == TAG_CMD)
diff --git a/src/main.c b/src/main.c
index e1005d8..4005bf2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -16,6 +16,8 @@
*/
#include "minishell.h"
+#include "ast.h"
+#include "eval.h"
/**
** \brief Program entrypoint
@@ -25,24 +27,52 @@
** \return 0 if ok, 1 otherwise
*/
-int main(int argc, char **argv, const char **envp)
+int main(int argc, char **argv, char **envp)
{
+ (void)argc;
+ (void)argv;
+ /* (void)envp; */
t_path path;
t_env env;
/* char *line; */
/* int ret; */
- (void)argc;
- (void)argv;
- env = env_from_array((char**)envp);
+ env = env_from_array(envp);
path = path_update(NULL, ft_htget(env, "PATH"));
- printf("%s\n", (char*)ft_htget(path, "nmap"));
- /* env(env); */
- /* pwd(&state); */
- /* cd(&state, NULL); */
- /* pwd(&state); */
+ 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.in_pipe[0] = -1;
+ state.in_pipe[1] = -1;
+ state.out_pipe[0] = -1;
+ state.out_pipe[1] = -1;
+ state.path = path;
+ state.env = env;
+ eval(&state, ast);
+
+ ast_destroy(ast);
/* while ((ret = ft_next_line(STDIN_FILENO, &line)) == 1) */
/* { */
/* if (eval(parse(line)) == -1) */
diff --git a/src/path.c b/src/path.c
index db9d8bd..1136a7c 100644
--- a/src/path.c
+++ b/src/path.c
@@ -21,7 +21,7 @@
** \brief Number of buckets of a path hash table
*/
-#define MS_PATH_HT_SIZE 4096
+#define MS_PATH_HT_SIZE 8192
/**
** \brief Update `path` with all files in the directory named `dirname`.