From e5393671a265e1c301c6c303f21f938c4cf9ca75 Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 2 Apr 2020 15:50:13 +0200 Subject: Evaluation pipe frame (not tested) --- src/builtin/cd.c | 10 +--- src/builtin/echo.c | 6 +- src/builtin/export.c | 4 +- src/builtin/unset.c | 5 +- src/env.c | 7 ++- src/eval/eval.c | 160 +++++++++++++++++++++++++++++++++++++++------------ src/main.c | 13 +++-- src/path.c | 13 +++-- 8 files changed, 155 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/builtin/cd.c b/src/builtin/cd.c index 66f1f81..1a7c70e 100644 --- a/src/builtin/cd.c +++ b/src/builtin/cd.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:10:20 by charles #+# #+# */ -/* Updated: 2020/04/01 22:15:49 by charles ### ########.fr */ +/* Updated: 2020/04/02 11:33:15 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,14 +19,10 @@ int builtin_cd(char **argv, t_env env) { - char *path; - - path = argv[1]; + (void)env; if (argv[1] == NULL) - path = env_search(env, "HOME"); - if (path == NULL) return (1); - if (chdir(path) == -1) + if (chdir(argv[1]) == -1) return (1); return (0); } diff --git a/src/builtin/echo.c b/src/builtin/echo.c index 9b7a8f6..886c2ca 100644 --- a/src/builtin/echo.c +++ b/src/builtin/echo.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:10:47 by charles #+# #+# */ -/* Updated: 2020/04/01 17:10:48 by charles ### ########.fr */ +/* Updated: 2020/04/02 11:18:16 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,8 +22,8 @@ int builtin_echo(char **argv, t_env env) bool newline; (void)env; - newline = ft_strcmp(argv[1], "-n") == 0; - if (newline) + newline = !ft_strcmp(argv[1], "-n") == 0; + if (!newline) argv++; while (*++argv != NULL) { diff --git a/src/builtin/export.c b/src/builtin/export.c index 650a421..3636407 100644 --- a/src/builtin/export.c +++ b/src/builtin/export.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:11:34 by charles #+# #+# */ -/* Updated: 2020/04/01 22:37:47 by charles ### ########.fr */ +/* Updated: 2020/04/02 10:46:27 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,7 +25,7 @@ int builtin_export(char **argv, t_env env) return (1); if ((tmp = ft_strdup(argv[1])) == NULL) return (2); - if (ft_vecpush(env, tmp) == NULL) + if (ft_vecinsert(env, env->size - 1, tmp) == NULL) return (2); // internal error code return (0); } diff --git a/src/builtin/unset.c b/src/builtin/unset.c index ffcf60f..146b755 100644 --- a/src/builtin/unset.c +++ b/src/builtin/unset.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:10:51 by charles #+# #+# */ -/* Updated: 2020/04/01 23:05:33 by charles ### ########.fr */ +/* Updated: 2020/04/02 11:17:03 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,10 +25,13 @@ int builtin_unset(char **argv, t_env env) return (1); i = 0; while (i < env->size) + { if (ft_strncmp(env->data[i], argv[1], ft_strlen(argv[1])) == 0) { ft_vecremove(env, i, free); return (0); } + i++; + } return (1); } diff --git a/src/env.c b/src/env.c index 66b4994..631c2b4 100644 --- a/src/env.c +++ b/src/env.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 09:21:24 by cacharle #+# #+# */ -/* Updated: 2020/04/01 23:09:33 by charles ### ########.fr */ +/* Updated: 2020/04/02 10:33:12 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,9 +32,9 @@ t_env env_from_array(char **envp) while (envp[i] != NULL) if (ft_strchr(envp[i++], '=') == NULL) return (NULL); - if ((env = ft_vecnew(i)) == NULL) + if ((env = ft_vecnew(i + 1)) == NULL) return (NULL); - env->size = i; + env->size = i + 1; i = 0; while (envp[i] != NULL) { @@ -45,6 +45,7 @@ t_env env_from_array(char **envp) } i++; } + env->data[i] = NULL; return (env); } diff --git a/src/eval/eval.c b/src/eval/eval.c index 8c1e509..0e57f15 100644 --- a/src/eval/eval.c +++ b/src/eval/eval.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:21 by charles #+# #+# */ -/* Updated: 2020/04/01 23:15:16 by charles ### ########.fr */ +/* Updated: 2020/04/02 17:08:18 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,63 +17,139 @@ #include "eval.h" -/* -** \brief Evaluate a line -** \param state State of the evaluation -** \param line Line to evaluate -** \return Last Executed command status or -1 on error -*/ +#define PARAM_SIZE 3 + +#define PARAM_STATE 0 +#define PARAM_LINE 1 + +#define PARAM_EXEC_PATH 0 +#define PARAM_ARGV 1 +#define PARAM_ENVP 2 -static int eval_line(t_eval_state *state, t_line *line) +int io_frame_init(t_io_frame *frame) { - int status; + if (pipe(frame->pipe_in) == -1 + || pipe(frame->pipe_out) == -1) + return (-1); + /* frame->pipe_in[PIPE_READ] = STDIN_FILENO; */ + /* frame->pipe_in[PIPE_WRITE] = PIPE_CLOSED; */ + /* frame->pipe_out[PIPE_READ] = PIPE_CLOSED; */ + /* frame->pipe_out[PIPE_WRITE] = STDOUT_FILENO; */ + return (0); +} + +static int eval_root(void *params[PARAM_SIZE]) +{ + int status; + t_eval_state *state; + t_line *line; + t_io_frame frame_left; + t_io_frame frame_right; + state = params[PARAM_STATE]; + line = params[PARAM_LINE]; + io_frame_init(&frame_left); if (line->right == NULL) - return (eval(state, line->left)); - if ((status = eval(state, line->left)) == -1) + return (eval(&frame_left, state, line->left)); + + if (line->sep == SEP_PIPE) + dup2(STDOUT_FILENO, frame_left.pipe_out[PIPE_WRITE]); + + if ((status = eval(&frame_left, state, line->left)) == -1) return (-1); if ((line->sep == SEP_AND && status != 0) || (line->sep == SEP_OR && status == 0)) return (status); - return (eval(state, line->right)); + + if (line->sep == SEP_PIPE) + dup2(frame_right.pipe_in[PIPE_WRITE], frame_left.pipe_out[PIPE_READ]); + + return (eval(&frame_right, state, line->right)); } -/* -** \brief Evaluate a command -** \param state Evaluation state -** \param cmd Command to evaluate -** \return Executable status or -1 on error -*/ +int execve_wrapper(void *params[PARAM_SIZE]) +{ + return (execve( + params[PARAM_EXEC_PATH], + params[PARAM_ARGV], + params[PARAM_ENVP] + )); +} -static int eval_cmd(t_eval_state *state, t_cmd *cmd) +int exec_wrap( + t_io_frame *frame, + void *passed[PARAM_SIZE], + int (*wrapped)(void *params[PARAM_SIZE]) +) { - int child_pid; - char *exec_path; - bool is_builtin; + int status; + pid_t child_pid; - is_builtin = builtin_check_exec_name(cmd->argv[0]); // no fork if builtin - if (!is_builtin) - { - if ((exec_path = exec_search_path(state->path, - env_search(state->env, "PATH"), cmd->argv[0])) == NULL) - return (-1); - } - pipe_setup_parent(cmd, state->pipe_in, state->pipe_out); if ((child_pid = fork()) == -1) return (-1); if (child_pid == 0) { - pipe_setup_child(state->pipe_in, state->pipe_out); - if (is_builtin) - exit(builtin_dispatch_run(cmd->argv, state->env)); - else if (execve(exec_path, cmd->argv, NULL) == -1) + if (dup2(STDIN_FILENO, frame->pipe_in[PIPE_READ]) == -1 || + dup2(STDOUT_FILENO, frame->pipe_out[PIPE_WRITE]) == -1) exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); + if ((status = wrapped(passed)) == -1) + exit(EXIT_FAILURE); + exit(status); } wait(&child_pid); return (WEXITSTATUS(child_pid)); } +/* +** \brief Evaluate a line +** \param state State of the evaluation +** \param line Line to evaluate +** \return Last Executed command status or -1 on error +*/ + +static int eval_line(t_io_frame *frame, t_eval_state *state, t_line *line) +{ + void *params[PARAM_SIZE]; + + params[PARAM_STATE] = state; + params[PARAM_LINE] = line; + return (exec_wrap(frame, params, &eval_root)); +} + +int run_builtin(t_eval_state *state, char **argv) +{ + return (builtin_dispatch_run(argv, state->env)); +} + +/* +** \brief Evaluate a command +** \param state Evaluation state +** \param cmd Command to evaluate +** \return Executable status or -1 on error +*/ + +static int eval_cmd(t_io_frame *frame, t_eval_state *state, t_cmd *cmd) +{ + void *params[PARAM_SIZE]; + + if (builtin_check_exec_name(cmd->argv[0])) + return (run_builtin(state, cmd->argv)); + params[PARAM_EXEC_PATH] = exec_search_path( + state->path, env_search(state->env, "PATH"), cmd->argv[0]); + if (params[PARAM_EXEC_PATH] == NULL) + return (-1); + if (cmd->in != NULL) + if ((frame->pipe_in[PIPE_WRITE] = open(cmd->in, O_RDONLY)) == -1) + return (-1); + if (cmd->out != NULL) + if ((frame->pipe_out[PIPE_READ] = open(cmd->out, + (cmd->is_append ? O_APPEND : O_RDONLY) | O_CREAT)) == -1) + return (-1); + params[PARAM_ARGV] = cmd->argv; + params[PARAM_ENVP] = state->env->data; + return (exec_wrap(frame, params, &execve_wrapper)); +} + /* ** \brief Evaluate an AST ** \param state State of the evaluation @@ -81,12 +157,20 @@ static int eval_cmd(t_eval_state *state, t_cmd *cmd) ** \return Executable status or -1 on error */ -int eval(t_eval_state *state, t_ast *ast) +int eval(t_io_frame *frame, t_eval_state *state, t_ast *ast) { + void *params[PARAM_SIZE]; + errno = 0; + if (ast->tag == TAG_ROOT) + { + params[PARAM_STATE] = state; + params[PARAM_LINE] = &ast->data.line; + return (eval_root(params)); + } if (ast->tag == TAG_LINE) - return (eval_line(state, &ast->data.line)); + return (eval_line(frame, state, &ast->data.line)); if (ast->tag == TAG_CMD) - return (eval_cmd(state, &ast->data.cmd)); + return (eval_cmd(frame, state, &ast->data.cmd)); return (-1); } diff --git a/src/main.c b/src/main.c index c46324f..f898bf8 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/04/01 23:12:51 by charles ### ########.fr */ +/* Updated: 2020/04/03 08:56:46 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -70,9 +70,14 @@ int main(int argc, char **argv, char **envp) state.pipe_out[1] = -1; state.path = path; state.env = env; - printf("ret: %d %s\n", eval(&state, ast), strerror(errno)); + t_io_frame frame; + io_frame_init(&frame); + printf("ret: %d %s\n", eval(&frame,&state, ast), strerror(errno)); - ast_destroy(ast); + /* 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) */ @@ -80,7 +85,7 @@ int main(int argc, char **argv, char **envp) /* free(line); */ /* } */ /* free(line); */ - ft_htdestroy(path, ht_del_str_entry); + ft_htdestroy(path, free); ft_vecdestroy(env, free); return (0); } diff --git a/src/path.c b/src/path.c index f1424cc..1576a66 100644 --- a/src/path.c +++ b/src/path.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/27 15:51:01 by cacharle #+# #+# */ -/* Updated: 2020/04/01 17:55:28 by charles ### ########.fr */ +/* Updated: 2020/04/03 07:17:04 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,16 +35,19 @@ static t_path st_path_dir_update(t_path path, char *dirname) { DIR *dir; struct dirent *entry; - char *tmp; + char *filepath; if ((dir = opendir(dirname)) == NULL) return (NULL); while ((entry = readdir(dir)) != NULL) { - if ((tmp = ft_strjoin3(dirname, "/", entry->d_name)) == NULL) - return (NULL); - if (ft_htset(path, entry->d_name, tmp, ht_del_str_entry) == NULL) + if ((filepath = ft_strjoin3(dirname, "/", entry->d_name)) == NULL || + ft_htset(path, entry->d_name, filepath, free) == NULL) + { + free(filepath); + closedir(dir); return (NULL); + } } if (closedir(dir) == -1) return (NULL); -- cgit From c0e2ee28eedc1a9a886f9729a994d77738e2eb58 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 3 Apr 2020 15:13:08 +0200 Subject: Refactoring env, connecting pipes, preprocess draft --- src/builtin/cd.c | 3 ++- src/builtin/export.c | 4 ++- src/env.c | 41 +++++++++++++++++++---------- src/main.c | 55 +++++++++++++++++++------------------- src/path.c | 30 +++++++-------------- src/preprocess.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils.c | 36 ++++++++++++++++--------- 7 files changed, 167 insertions(+), 76 deletions(-) create mode 100644 src/preprocess.c (limited to 'src') diff --git a/src/builtin/cd.c b/src/builtin/cd.c index 1a7c70e..ed0b3cc 100644 --- a/src/builtin/cd.c +++ b/src/builtin/cd.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:10:20 by charles #+# #+# */ -/* Updated: 2020/04/02 11:33:15 by charles ### ########.fr */ +/* Updated: 2020/04/03 12:11:52 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,7 @@ int builtin_cd(char **argv, t_env env) { + //change $PWD (void)env; if (argv[1] == NULL) return (1); diff --git a/src/builtin/export.c b/src/builtin/export.c index 3636407..1d362b3 100644 --- a/src/builtin/export.c +++ b/src/builtin/export.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:11:34 by charles #+# #+# */ -/* Updated: 2020/04/02 10:46:27 by charles ### ########.fr */ +/* Updated: 2020/04/03 12:11:38 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,8 @@ int builtin_export(char **argv, t_env env) { char *tmp; + // modify existing + // set with no string without '=' if (ft_strchr(argv[1], '=') == NULL) return (1); if ((tmp = ft_strdup(argv[1])) == NULL) diff --git a/src/env.c b/src/env.c index 631c2b4..d402a1b 100644 --- a/src/env.c +++ b/src/env.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 09:21:24 by cacharle #+# #+# */ -/* Updated: 2020/04/02 10:33:12 by charles ### ########.fr */ +/* Updated: 2020/04/03 14:25:31 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,8 @@ #include "minishell.h" +#define ENV_VEC_DEFAULT_SIZE 64 + /* ** \brief Convert array of string to environment hash table ** \param envp array of string (each in the format `name=value`) @@ -25,28 +27,22 @@ t_env env_from_array(char **envp) { + char *tmp; t_env env; - size_t i; - i = 0; - while (envp[i] != NULL) - if (ft_strchr(envp[i++], '=') == NULL) - return (NULL); - if ((env = ft_vecnew(i + 1)) == NULL) + if ((env = ft_vecnew(ENV_VEC_DEFAULT_SIZE)) == NULL) return (NULL); - env->size = i + 1; - i = 0; - while (envp[i] != NULL) + while (*envp != NULL) { - if ((env->data[i] = ft_strdup(envp[i])) == NULL) + if ((tmp = ft_strdup(*envp)) == NULL || + ft_vecpush(env, tmp) == NULL) { ft_vecdestroy(env, free); return (NULL); } - i++; + envp++; } - env->data[i] = NULL; - return (env); + return (ft_vecpush(env, NULL)); } /** @@ -69,3 +65,20 @@ char *env_search(t_env env, char *key) } return (NULL); } + +char *env_match_first(t_env env, const char *haystack) +{ + int len; + size_t i; + + len = -1; + while (ft_isalnum(haystack[len]) || haystack[len] == '_') + len++; + while (i < env->size) + { + if (ft_strncmp((char*)env->data[i], haystack, len) == 0) + return (ft_strchr((char*)env->data[i], '=') + 1); + i++; + } + return (NULL); +} diff --git a/src/main.c b/src/main.c index f898bf8..2e42601 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/04/03 08:56:46 by charles ### ########.fr */ +/* Updated: 2020/04/03 14:25:48 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,22 +38,22 @@ int main(int argc, char **argv, char **envp) /* 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); + /* 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); */ @@ -64,15 +64,15 @@ int main(int argc, char **argv, char **envp) /* 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)); + /* 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)); */ @@ -85,7 +85,8 @@ int main(int argc, char **argv, char **envp) /* free(line); */ /* } */ /* free(line); */ - ft_htdestroy(path, free); + /* ft_htdestroy(path, free); */ + printf("%s\n", preprocess("*.c", env)); ft_vecdestroy(env, free); return (0); } diff --git a/src/path.c b/src/path.c index 1576a66..c9f184c 100644 --- a/src/path.c +++ b/src/path.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/27 15:51:01 by cacharle #+# #+# */ -/* Updated: 2020/04/03 07:17:04 by charles ### ########.fr */ +/* Updated: 2020/04/03 13:53:01 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,27 +31,17 @@ ** \return Same path or NULL on error */ -static t_path st_path_dir_update(t_path path, char *dirname) +static int st_add_file(char *dirname, struct dirent *entry, void *path) { - DIR *dir; - struct dirent *entry; - char *filepath; + char *filepath; - if ((dir = opendir(dirname)) == NULL) - return (NULL); - while ((entry = readdir(dir)) != NULL) + if ((filepath = ft_strjoin3(dirname, "/", entry->d_name)) == NULL || + ft_htset((t_path)path, entry->d_name, filepath, free) == NULL) { - if ((filepath = ft_strjoin3(dirname, "/", entry->d_name)) == NULL || - ft_htset(path, entry->d_name, filepath, free) == NULL) - { - free(filepath); - closedir(dir); - return (NULL); - } + free(filepath); + return (-1); } - if (closedir(dir) == -1) - return (NULL); - return (path); + return (0); } /* @@ -74,8 +64,8 @@ t_path path_update(t_path path, char *path_var) if ((dirs = ft_split(path_var, ':')) == NULL) return (NULL); i = -1; - while (dirs[++i] != NULL) - if (st_path_dir_update(path, dirs[i]) == NULL) + while (dirs[++i] != NULL) // carefull with non existant dir error + if (utils_directory_iter(dirs[i], path, st_add_file) == -1) return (ft_split_destroy(dirs)); ft_split_destroy(dirs); return (path); diff --git a/src/preprocess.c b/src/preprocess.c new file mode 100644 index 0000000..30d2aa3 --- /dev/null +++ b/src/preprocess.c @@ -0,0 +1,74 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* preprocess.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/04/03 08:58:49 by charles #+# #+# */ +/* Updated: 2020/04/03 14:48:57 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ms_glob(char *pattern) +{ + (void)pattern; + return (NULL); +} + +/* void iterpolate_iter_f(char **curr) */ +/* { */ +/* if (*curr != '$') */ +/* return (i + 1); */ +/* } */ + + +char *preprocess(char *input, t_env env) +{ + int i; + t_ftdstr *input_dstr; + char *glob_str; + /* char *tmp; */ + + glob_str = NULL; + if ((input_dstr = ft_dstrnew(input)) == NULL) + return (NULL); + i = 0; + while (input_dstr->str[i] != '\0') + { + if (input_dstr->str[i] == '*') + { + free(glob_str); + /* if ((glob_str = ms_glob()) = NULL) */ + /* { */ + /* ft_dstrdestroy(input_str); */ + /* return (NULL); */ + /* } */ + if (ft_dstrinsert(input_dstr, glob_str, 0) == NULL) + { + free(glob_str); + ft_dstrdestroy(input_dstr); + return (NULL); + } + i += strlen(glob_str); + } + /* else if (input_dstr->str[i] == '$') */ + /* { */ + /* if ((tmp = env_match_first(env, input_dstr->str + i + 1)) == NULL) */ + /* tmp = ""; */ + /* if (ft_dstrreplace(input_dstr, tmp, i, i + ft_strlen(tmp)) == NULL) */ + /* { */ + /* free(glob_str); */ + /* ft_dstrdestroy(input_dstr); */ + /* return (NULL); */ + /* } */ + /* i += ft_strlen(tmp); */ + /* } */ + /* else */ + i++; + } + printf("%d %d %s\n", input_dstr->length, input_dstr->capacity, input_dstr->str); + return (ft_dstrunwrap(input_dstr)); +} diff --git a/src/utils.c b/src/utils.c index 1649199..9ef99a6 100644 --- a/src/utils.c +++ b/src/utils.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:56:31 by cacharle #+# #+# */ -/* Updated: 2020/04/01 17:55:34 by charles ### ########.fr */ +/* Updated: 2020/04/03 14:58:17 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,17 +17,27 @@ #include "minishell.h" -/* -** \brief Delete function for a entry containing -** an allocated key and value -** \param entry Hash table entry -*/ - -void ht_del_str_entry(t_ftht_entry *entry) +int utils_directory_iter( + char *dirname, + void *param, + int (*f)(char*, struct dirent*, void*) +) { - if (entry == NULL) - return ; - free(entry->key); - free(entry->value); - free(entry); + DIR *dir; + struct dirent *entry; + + if ((dir = opendir(dirname)) == NULL) + return (-1); + while ((entry = readdir(dir)) != NULL) + if (f(dirname, entry, param) == -1) + { + closedir(dir); + return (-1); + } + if (closedir(dir) == -1) + return (-1); + return (0); + } + +/* int utils_not_alnum */ -- cgit From db122618b7dd0e1c2b9432e3f470c880e0d4422e Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 4 Apr 2020 19:11:05 +0200 Subject: Glob logic mainly done --- src/env.c | 6 +- src/main.c | 9 ++- src/preprocess.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 145 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/env.c b/src/env.c index d402a1b..f00d046 100644 --- a/src/env.c +++ b/src/env.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 09:21:24 by cacharle #+# #+# */ -/* Updated: 2020/04/03 14:25:31 by charles ### ########.fr */ +/* Updated: 2020/04/04 13:33:42 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,15 +27,13 @@ t_env env_from_array(char **envp) { - char *tmp; t_env env; if ((env = ft_vecnew(ENV_VEC_DEFAULT_SIZE)) == NULL) return (NULL); while (*envp != NULL) { - if ((tmp = ft_strdup(*envp)) == NULL || - ft_vecpush(env, tmp) == NULL) + if (ft_vecpush_safe(env, ft_strdup(*envp)) == NULL) { ft_vecdestroy(env, free); return (NULL); diff --git a/src/main.c b/src/main.c index 2e42601..f897faa 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/04/03 14:25:48 by charles ### ########.fr */ +/* Updated: 2020/04/04 18:37:03 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,7 +32,7 @@ int main(int argc, char **argv, char **envp) (void)argc; (void)argv; /* (void)envp; */ - t_path path; + /* t_path path; */ t_env env; /* char *line; */ /* int ret; */ @@ -86,7 +86,10 @@ int main(int argc, char **argv, char **envp) /* } */ /* free(line); */ /* ft_htdestroy(path, free); */ - printf("%s\n", preprocess("*.c", env)); + /* ms_glob("src#<{(|"); */ + char *j = ms_glob("*/"); + printf("%s\n", j); + free(j); ft_vecdestroy(env, free); return (0); } diff --git a/src/preprocess.c b/src/preprocess.c index 30d2aa3..6dbc386 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,16 +6,123 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/04/03 14:48:57 by charles ### ########.fr */ +/* Updated: 2020/04/04 18:30:10 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +// 8 en moyenne +#define MATCHES_VEC_DEFAULT_SIZE 32 + +struct s_glob_param +{ + char *pattern; + t_ftvec *matches; +}; + +t_ftvec *glob_matches(char *pattern); + + +int glob_iter(char *dirname, struct dirent *entry, void *void_param) +{ + struct s_glob_param *param; + char *subdir_pattern; + char *subdir_name; + t_ftvec *subdir_matches; + + param = void_param; + /* printf("DIR: %15s %d\n", entry->d_name, entry->d_type == DT_DIR); */ + if (param->pattern[0] != '.' && entry->d_name[0] == '.') + return (0); + if ((subdir_pattern = ft_strchr(param->pattern, '/')) != NULL) + { + *subdir_pattern = '\0'; + subdir_pattern++; + } + if (!ft_fnmatch(param->pattern, entry->d_name)) + { + if (subdir_pattern != NULL) + subdir_pattern[-1] = '/'; + return (0); + } + if (subdir_pattern != NULL) + { + if (entry->d_type != DT_DIR) + { + if (ft_vecpush_safe(param->matches, ft_strdup(entry->d_name)) == NULL) + return (-1); + subdir_pattern[-1] = '/'; + return (0); + } + + if ((subdir_name = ft_strjoin3(dirname, "/", entry->d_name)) == NULL) + return (-1); + chdir(subdir_name); + free(subdir_name); + subdir_matches = glob_matches(subdir_pattern); + chdir(dirname); + if (subdir_matches == NULL) + return (-1); + for (size_t i = 0; i < subdir_matches->size; i++) + { + if (ft_vecpush_safe(param->matches, + ft_strjoin3(entry->d_name, "/", subdir_matches->data[i])) == NULL) + { + ft_vecdestroy(subdir_matches, free); + return (-1); + } + } + ft_vecdestroy(subdir_matches, free); + subdir_pattern[-1] = '/'; + } + else + { + if (ft_vecpush_safe(param->matches, ft_strdup(entry->d_name)) == NULL) + return (-1); + } + return (0); +} + +t_ftvec *glob_matches(char *pattern) +{ + char dirname[PATH_MAX]; + struct s_glob_param param; + + if (getcwd(dirname, PATH_MAX) == NULL) + return (NULL); + if ((param.pattern = ft_strdup(pattern)) == NULL || + (param.matches = ft_vecnew(MATCHES_VEC_DEFAULT_SIZE)) == NULL) + { + free(param.pattern); + return (NULL); + } + if (utils_directory_iter(dirname, ¶m, glob_iter) == -1) + { + free(param.pattern); + ft_vecdestroy(param.matches, free); + return (NULL); + } + free(param.pattern); + return (param.matches); +} + char *ms_glob(char *pattern) { - (void)pattern; - return (NULL); + char *join; + t_ftvec *matches; + + if ((matches = glob_matches(pattern)) == NULL) + return (NULL); + ft_vecsort(matches, ft_compar_str); + if (ft_vecpush(matches, NULL) == NULL || + (join = ft_strsjoin((char**)matches->data, "\n")) == NULL) + { + ft_vecdestroy(matches, free); + return (NULL); + } + ft_vecdestroy(matches, free); + return (join); } /* void iterpolate_iter_f(char **curr) */ @@ -27,33 +134,35 @@ char *ms_glob(char *pattern) char *preprocess(char *input, t_env env) { - int i; - t_ftdstr *input_dstr; - char *glob_str; + /* int i; */ + /* t_ftdstr *input_dstr; */ + /* char *glob_str; */ /* char *tmp; */ - glob_str = NULL; - if ((input_dstr = ft_dstrnew(input)) == NULL) - return (NULL); - i = 0; - while (input_dstr->str[i] != '\0') - { - if (input_dstr->str[i] == '*') - { - free(glob_str); + (void)input; + (void)env; + /* glob_str = NULL; */ + /* if ((input_dstr = ft_dstrnew(input)) == NULL) */ + /* return (NULL); */ + /* i = 0; */ + /* while (input_dstr->str[i] != '\0') */ + /* { */ + /* if (input_dstr->str[i] == '*') */ + /* { */ + /* free(glob_str); */ /* if ((glob_str = ms_glob()) = NULL) */ /* { */ /* ft_dstrdestroy(input_str); */ /* return (NULL); */ /* } */ - if (ft_dstrinsert(input_dstr, glob_str, 0) == NULL) - { - free(glob_str); - ft_dstrdestroy(input_dstr); - return (NULL); - } - i += strlen(glob_str); - } + /* if (ft_dstrinsert(input_dstr, glob_str, 0) == NULL) */ + /* { */ + /* free(glob_str); */ + /* ft_dstrdestroy(input_dstr); */ + /* return (NULL); */ + /* } */ + /* i += strlen(glob_str); */ + /* } */ /* else if (input_dstr->str[i] == '$') */ /* { */ /* if ((tmp = env_match_first(env, input_dstr->str + i + 1)) == NULL) */ @@ -67,8 +176,9 @@ char *preprocess(char *input, t_env env) /* i += ft_strlen(tmp); */ /* } */ /* else */ - i++; - } - printf("%d %d %s\n", input_dstr->length, input_dstr->capacity, input_dstr->str); - return (ft_dstrunwrap(input_dstr)); + /* i++; */ + /* } */ + /* printf("%d %d %s\n", input_dstr->length, input_dstr->capacity, input_dstr->str); */ + /* return (ft_dstrunwrap(input_dstr)); */ + return NULL; } -- cgit From 4aeba6d2f03706fa21281709a138a7d3ea9797dc Mon Sep 17 00:00:00 2001 From: Charles Date: Sun, 5 Apr 2020 15:04:23 +0200 Subject: Preprocessing (glob and iterpolation) draft (not tested) --- src/env.c | 9 ++- src/glob.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 5 +- src/path.c | 3 +- src/preprocess.c | 191 +++++++++++-------------------------------------------- src/utils.c | 26 +++++++- 6 files changed, 234 insertions(+), 162 deletions(-) create mode 100644 src/glob.c (limited to 'src') diff --git a/src/env.c b/src/env.c index f00d046..41aca6d 100644 --- a/src/env.c +++ b/src/env.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 09:21:24 by cacharle #+# #+# */ -/* Updated: 2020/04/04 13:33:42 by charles ### ########.fr */ +/* Updated: 2020/04/05 14:42:38 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,6 +50,7 @@ t_env env_from_array(char **envp) ** \return Value after '=' in environment variable array or NULL if not found */ +// could be a wrapper around ft_lfind char *env_search(t_env env, char *key) { size_t i; @@ -64,12 +65,14 @@ char *env_search(t_env env, char *key) return (NULL); } -char *env_match_first(t_env env, const char *haystack) +char *env_search_first_match(t_env env, const char *haystack) { int len; size_t i; - len = -1; + if (ft_isdigit(*haystack)) + return (NULL); + len = 0; while (ft_isalnum(haystack[len]) || haystack[len] == '_') len++; while (i < env->size) diff --git a/src/glob.c b/src/glob.c new file mode 100644 index 0000000..2d544da --- /dev/null +++ b/src/glob.c @@ -0,0 +1,162 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* glob.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/04/05 11:44:07 by charles #+# #+# */ +/* Updated: 2020/04/05 13:21:25 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ms_glob.h" + +/* +** \brief Match vector start size +** \note From ~: average file in directory is 8 +** From /: average file in directory is 15 +*/ + +#define MATCHES_VEC_START_SIZE 16 + +/* +** \brief Glob directory iteration function +** for subdirectory matches +** \param dirname Current directory name +** \param entry Current directory entry +** \param param Contain matches vector and pattern to match +** \param subdir_pattern Pattern left after '/' in parrent pattern +** \return 0 on success, -1 on error +*/ + +static int glob_iter_subdir( + char *dirname, + struct dirent *entry, + struct s_glob_param *param, + char *subdir_pattern +) +{ + char subdir_name[PATH_MAX]; + t_ftvec *subdir_matches; + size_t i; + + ft_strcat3(ft_strcpy(subdir_name, dirname), "/", entry->d_name); + chdir(subdir_name); + subdir_matches = glob_matches(subdir_pattern); + chdir(dirname); + if (subdir_matches == NULL) + return (-1); + i = 0; + while (i < subdir_matches->size) + if (ft_vecpush_safe(param->matches, ft_strjoin3(entry->d_name, + "/", subdir_matches->data[i++])) == NULL) + { + ft_vecdestroy(subdir_matches, free); + return (-1); + } + ft_vecdestroy(subdir_matches, free); + subdir_pattern[-1] = '/'; + return (0); +} + +/* +** \brief Glob directory iteration function +** \param dirname Current directory name +** \param entry Current directory entry +** \param param Contain matches vector and pattern to match +** \return 0 on success or -1 on error +*/ + +static int glob_iter( + char *dirname, + struct dirent *entry, + struct s_glob_param *param +) +{ + char *subdir_pattern; + + if (param->pattern[0] != '.' && entry->d_name[0] == '.') + return (0); + if ((subdir_pattern = ft_strchr(param->pattern, '/')) != NULL) + *subdir_pattern++ = '\0'; + if (!ft_fnmatch(param->pattern, entry->d_name)) + { + if (subdir_pattern != NULL) + subdir_pattern[-1] = '/'; + return (0); + } + if (subdir_pattern != NULL) + { + if (entry->d_type != DT_DIR) + { + subdir_pattern[-1] = '/'; + return (0); + } + return (glob_iter_subdir(dirname, entry, param, subdir_pattern)); + } + if (ft_vecpush_safe(param->matches, ft_strdup(entry->d_name)) == NULL) + return (-1); + return (0); +} + +/* +** \brief Fill a vector with all match +** \param pattern Pattern to match +** \return Matches vector or NULL on error +*/ + +t_ftvec *glob_matches(char *pattern) +{ + char dirname[PATH_MAX]; + struct s_glob_param param; + + if (getcwd(dirname, PATH_MAX) == NULL) + return (NULL); + if ((param.pattern = ft_strdup(pattern)) == NULL || + (param.matches = ft_vecnew(MATCHES_VEC_START_SIZE)) == NULL) + { + free(param.pattern); + return (NULL); + } + if (utils_directory_iter(dirname, ¶m, + (t_directory_iter_func)glob_iter) == -1) + { + free(param.pattern); + ft_vecdestroy(param.matches, free); + return (NULL); + } + free(param.pattern); + return (param.matches); +} + +/* +** \brief Search files which match a pattern in the current directory +** \param pattern Pattern to match +** \return Space separated list of match, +** pattern if no match found, +** NULL on error +*/ + +char *ms_glob(char *pattern) +{ + char *join; + t_ftvec *matches; + + if ((matches = glob_matches(pattern)) == NULL) + return (NULL); + ft_vecsort(matches, ft_compar_str); + if (ft_vecpush(matches, NULL) == NULL || + (join = ft_strsjoin((char**)matches->data, "\n")) == NULL) + { + ft_vecdestroy(matches, free); + return (NULL); + } + ft_vecdestroy(matches, free); + if (*join == '\0') + { + free(join); + return (ft_strdup(pattern)); + } + return (join); +} diff --git a/src/main.c b/src/main.c index f897faa..d9302ad 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/04/04 18:37:03 by charles ### ########.fr */ +/* Updated: 2020/04/05 12:15:57 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,6 +18,7 @@ #include "minishell.h" #include "ast.h" #include "eval.h" +#include "ms_glob.h" /* ** \brief Program entrypoint @@ -87,7 +88,7 @@ int main(int argc, char **argv, char **envp) /* free(line); */ /* ft_htdestroy(path, free); */ /* ms_glob("src#<{(|"); */ - char *j = ms_glob("*/"); + char *j = ms_glob("*/*.c"); printf("%s\n", j); free(j); ft_vecdestroy(env, free); diff --git a/src/path.c b/src/path.c index c9f184c..d768d07 100644 --- a/src/path.c +++ b/src/path.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/27 15:51:01 by cacharle #+# #+# */ -/* Updated: 2020/04/03 13:53:01 by charles ### ########.fr */ +/* Updated: 2020/04/05 12:09:05 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ */ #include "minishell.h" +#include "utils.h" /* ** \brief Number of buckets of a path hash table diff --git a/src/preprocess.c b/src/preprocess.c index 6dbc386..1151bca 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,179 +6,64 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/04/04 18:30:10 by charles ### ########.fr */ +/* Updated: 2020/04/05 14:58:00 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +#include "ms_glob.h" -// 8 en moyenne -#define MATCHES_VEC_DEFAULT_SIZE 32 - -struct s_glob_param -{ - char *pattern; - t_ftvec *matches; -}; - -t_ftvec *glob_matches(char *pattern); - - -int glob_iter(char *dirname, struct dirent *entry, void *void_param) +static char *iterpolate(char *str, t_env env) { - struct s_glob_param *param; - char *subdir_pattern; - char *subdir_name; - t_ftvec *subdir_matches; + size_t i; + t_ftdstr *dstr; + char *match; - param = void_param; - /* printf("DIR: %15s %d\n", entry->d_name, entry->d_type == DT_DIR); */ - if (param->pattern[0] != '.' && entry->d_name[0] == '.') - return (0); - if ((subdir_pattern = ft_strchr(param->pattern, '/')) != NULL) - { - *subdir_pattern = '\0'; - subdir_pattern++; - } - if (!ft_fnmatch(param->pattern, entry->d_name)) - { - if (subdir_pattern != NULL) - subdir_pattern[-1] = '/'; - return (0); - } - if (subdir_pattern != NULL) + if ((dstr = ft_dstrnew(str)) == NULL) + return (NULL); + free(str); + i = 0; + while (i < dstr->length) { - if (entry->d_type != DT_DIR) - { - if (ft_vecpush_safe(param->matches, ft_strdup(entry->d_name)) == NULL) - return (-1); - subdir_pattern[-1] = '/'; - return (0); - } - - if ((subdir_name = ft_strjoin3(dirname, "/", entry->d_name)) == NULL) - return (-1); - chdir(subdir_name); - free(subdir_name); - subdir_matches = glob_matches(subdir_pattern); - chdir(dirname); - if (subdir_matches == NULL) - return (-1); - for (size_t i = 0; i < subdir_matches->size; i++) + if (dstr->str[i] == '$') { - if (ft_vecpush_safe(param->matches, - ft_strjoin3(entry->d_name, "/", subdir_matches->data[i])) == NULL) + if ((match = env_search_first_match(env, dstr->str + i + 1)) == NULL) + ft_dstrerase(dstr, i, utils_var_end(dstr->str + i + 1)); + else { - ft_vecdestroy(subdir_matches, free); - return (-1); + if (ft_dstrsubstitute(dstr, match, i, utils_var_end(dstr->str + i + 1)) == NULL) + return (NULL); } } - ft_vecdestroy(subdir_matches, free); - subdir_pattern[-1] = '/'; - } - else - { - if (ft_vecpush_safe(param->matches, ft_strdup(entry->d_name)) == NULL) - return (-1); + i++; } - return (0); + return (ft_dstrunwrap(dstr)); } -t_ftvec *glob_matches(char *pattern) +static char *preprocess_arg(char *arg, t_env env) { - char dirname[PATH_MAX]; - struct s_glob_param param; - - if (getcwd(dirname, PATH_MAX) == NULL) - return (NULL); - if ((param.pattern = ft_strdup(pattern)) == NULL || - (param.matches = ft_vecnew(MATCHES_VEC_DEFAULT_SIZE)) == NULL) - { - free(param.pattern); - return (NULL); - } - if (utils_directory_iter(dirname, ¶m, glob_iter) == -1) + if (*arg == '\'') + return (ft_strsubf(arg, 1, ft_strlen(arg) - 1)); + if (*arg == '"') { - free(param.pattern); - ft_vecdestroy(param.matches, free); - return (NULL); + if (ft_strchr(arg, '$') != NULL) + arg = iterpolate(arg, env); + return (ft_strsubf(arg, 1, ft_strlen(arg) - 1)); } - free(param.pattern); - return (param.matches); + if (ft_strchr(arg, '$') != NULL) + return (iterpolate(arg, env)); + if (ft_strchr(arg, '*') != NULL) + return (ms_glob(arg)); + return (arg); } -char *ms_glob(char *pattern) -{ - char *join; - t_ftvec *matches; - - if ((matches = glob_matches(pattern)) == NULL) - return (NULL); - ft_vecsort(matches, ft_compar_str); - if (ft_vecpush(matches, NULL) == NULL || - (join = ft_strsjoin((char**)matches->data, "\n")) == NULL) - { - ft_vecdestroy(matches, free); - return (NULL); - } - ft_vecdestroy(matches, free); - return (join); -} - -/* void iterpolate_iter_f(char **curr) */ -/* { */ -/* if (*curr != '$') */ -/* return (i + 1); */ -/* } */ - - -char *preprocess(char *input, t_env env) +char **preprocess_argv(char **argv, t_env env) { - /* int i; */ - /* t_ftdstr *input_dstr; */ - /* char *glob_str; */ - /* char *tmp; */ + int i; - (void)input; - (void)env; - /* glob_str = NULL; */ - /* if ((input_dstr = ft_dstrnew(input)) == NULL) */ - /* return (NULL); */ - /* i = 0; */ - /* while (input_dstr->str[i] != '\0') */ - /* { */ - /* if (input_dstr->str[i] == '*') */ - /* { */ - /* free(glob_str); */ - /* if ((glob_str = ms_glob()) = NULL) */ - /* { */ - /* ft_dstrdestroy(input_str); */ - /* return (NULL); */ - /* } */ - /* if (ft_dstrinsert(input_dstr, glob_str, 0) == NULL) */ - /* { */ - /* free(glob_str); */ - /* ft_dstrdestroy(input_dstr); */ - /* return (NULL); */ - /* } */ - /* i += strlen(glob_str); */ - /* } */ - /* else if (input_dstr->str[i] == '$') */ - /* { */ - /* if ((tmp = env_match_first(env, input_dstr->str + i + 1)) == NULL) */ - /* tmp = ""; */ - /* if (ft_dstrreplace(input_dstr, tmp, i, i + ft_strlen(tmp)) == NULL) */ - /* { */ - /* free(glob_str); */ - /* ft_dstrdestroy(input_dstr); */ - /* return (NULL); */ - /* } */ - /* i += ft_strlen(tmp); */ - /* } */ - /* else */ - /* i++; */ - /* } */ - /* printf("%d %d %s\n", input_dstr->length, input_dstr->capacity, input_dstr->str); */ - /* return (ft_dstrunwrap(input_dstr)); */ - return NULL; + i = -1; + while (argv[++i] != NULL) + if ((argv[i] = preprocess_arg(argv[i], env)) == NULL) + return (NULL); + return (argv); } diff --git a/src/utils.c b/src/utils.c index 9ef99a6..dd89457 100644 --- a/src/utils.c +++ b/src/utils.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:56:31 by cacharle #+# #+# */ -/* Updated: 2020/04/03 14:58:17 by charles ### ########.fr */ +/* Updated: 2020/04/05 14:51:52 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,7 +37,27 @@ int utils_directory_iter( if (closedir(dir) == -1) return (-1); return (0); - } -/* int utils_not_alnum */ +/* bool utils_is_var_name(char *name) */ +/* { */ +/* if (!(ft_isalpha(*name) || *name == '_')) */ +/* return (false); */ +/* name++; */ +/* while (*name != '\0) */ +/* if (!(ft_isalnum(*name) || *name == '_')) */ +/* return (false); */ +/* return (true); */ +/* } */ + +size_t utils_var_end(char *name) +{ + size_t i; + + if (ft_isdigit(*name)) + return (0); + i = 0; + while (ft_isalnum(name[i]) || name[i] == '_') + i++; + return (i); +} -- cgit From 9fabc25a980550afc6337fd729632462f2680daa Mon Sep 17 00:00:00 2001 From: Charles Date: Sun, 12 Apr 2020 18:36:17 +0200 Subject: Removing data name in ast union, io_frame, root line ast tag --- src/ast.c | 16 ++--- src/eval/eval.c | 194 +++++++++++++++++++++++++------------------------------ src/preprocess.c | 2 +- 3 files changed, 98 insertions(+), 114 deletions(-) (limited to 'src') diff --git a/src/ast.c b/src/ast.c index 2393a95..4c66fa7 100644 --- a/src/ast.c +++ b/src/ast.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:42 by charles #+# #+# */ -/* Updated: 2020/04/01 17:05:44 by charles ### ########.fr */ +/* Updated: 2020/05/04 12:00:20 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,9 +36,9 @@ t_ast *ast_new(t_ast_tag tag, void *data) ft_bzero(ast, sizeof(t_ast)); ast->tag = tag; if (tag == TAG_CMD) - ft_memcpy(&ast->data.cmd, (t_cmd*)data, sizeof(t_cmd)); + ft_memcpy(&ast->cmd, (t_cmd*)data, sizeof(t_cmd)); else if (tag == TAG_LINE) - ft_memcpy(&ast->data.line, (t_line*)data, sizeof(t_line)); + ft_memcpy(&ast->line, (t_line*)data, sizeof(t_line)); return (ast); } @@ -53,14 +53,14 @@ void ast_destroy(t_ast *ast) return ; if (ast->tag == TAG_CMD) { - ft_split_destroy(ast->data.cmd.argv); - free(ast->data.cmd.in); - free(ast->data.cmd.out); + ft_split_destroy(ast->cmd.argv); + free(ast->cmd.in); + free(ast->cmd.out); } else if (ast->tag == TAG_LINE) { - ast_destroy(ast->data.line.left); - ast_destroy(ast->data.line.right); + ast_destroy(ast->line.left); + ast_destroy(ast->line.right); } free(ast); } diff --git a/src/eval/eval.c b/src/eval/eval.c index 0e57f15..0270024 100644 --- a/src/eval/eval.c +++ b/src/eval/eval.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:21 by charles #+# #+# */ -/* Updated: 2020/04/02 17:08:18 by charles ### ########.fr */ +/* Updated: 2020/05/04 12:00:38 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,70 +17,19 @@ #include "eval.h" -#define PARAM_SIZE 3 - -#define PARAM_STATE 0 -#define PARAM_LINE 1 - -#define PARAM_EXEC_PATH 0 -#define PARAM_ARGV 1 -#define PARAM_ENVP 2 - -int io_frame_init(t_io_frame *frame) -{ - if (pipe(frame->pipe_in) == -1 - || pipe(frame->pipe_out) == -1) - return (-1); - /* frame->pipe_in[PIPE_READ] = STDIN_FILENO; */ - /* frame->pipe_in[PIPE_WRITE] = PIPE_CLOSED; */ - /* frame->pipe_out[PIPE_READ] = PIPE_CLOSED; */ - /* frame->pipe_out[PIPE_WRITE] = STDOUT_FILENO; */ - return (0); -} - -static int eval_root(void *params[PARAM_SIZE]) -{ - int status; - t_eval_state *state; - t_line *line; - t_io_frame frame_left; - t_io_frame frame_right; - - state = params[PARAM_STATE]; - line = params[PARAM_LINE]; - io_frame_init(&frame_left); - if (line->right == NULL) - return (eval(&frame_left, state, line->left)); - - if (line->sep == SEP_PIPE) - dup2(STDOUT_FILENO, frame_left.pipe_out[PIPE_WRITE]); - - if ((status = eval(&frame_left, state, line->left)) == -1) - return (-1); - if ((line->sep == SEP_AND && status != 0) || - (line->sep == SEP_OR && status == 0)) - return (status); - - if (line->sep == SEP_PIPE) - dup2(frame_right.pipe_in[PIPE_WRITE], frame_left.pipe_out[PIPE_READ]); - - return (eval(&frame_right, state, line->right)); -} - -int execve_wrapper(void *params[PARAM_SIZE]) -{ - return (execve( - params[PARAM_EXEC_PATH], - params[PARAM_ARGV], - params[PARAM_ENVP] - )); -} +/* +** \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 exec_wrap( - t_io_frame *frame, - void *passed[PARAM_SIZE], - int (*wrapped)(void *params[PARAM_SIZE]) -) +int fork_wrap( + int fd_in, + int fd_out, + void *passed, + int (*wrapped)(void *param)) { int status; pid_t child_pid; @@ -89,8 +38,8 @@ int exec_wrap( return (-1); if (child_pid == 0) { - if (dup2(STDIN_FILENO, frame->pipe_in[PIPE_READ]) == -1 || - dup2(STDOUT_FILENO, frame->pipe_out[PIPE_WRITE]) == -1) + if (dup2(STDIN_FILENO, fd_in) == -1 || + dup2(STDOUT_FILENO, fd_out) == -1) exit(EXIT_FAILURE); if ((status = wrapped(passed)) == -1) exit(EXIT_FAILURE); @@ -100,25 +49,24 @@ int exec_wrap( return (WEXITSTATUS(child_pid)); } -/* -** \brief Evaluate a line -** \param state State of the evaluation -** \param line Line to evaluate -** \return Last Executed command status or -1 on error -*/ - -static int eval_line(t_io_frame *frame, t_eval_state *state, t_line *line) +int run_builtin(t_eval_state *state, char **argv) { - void *params[PARAM_SIZE]; - - params[PARAM_STATE] = state; - params[PARAM_LINE] = line; - return (exec_wrap(frame, params, &eval_root)); + return (builtin_dispatch_run(argv, state->env)); } -int run_builtin(t_eval_state *state, char **argv) +/* +** \brief execve syscall wrapper passed it to fork_wrap +** \param param function params +** \return execve return value +*/ + +int execve_wrapper(void *param) { - return (builtin_dispatch_run(argv, state->env)); + return (execve( + ((t_fork_param_execve*)param)->exec_path, + ((t_fork_param_execve*)param)->argv, + ((t_fork_param_execve*)param)->envp + )); } /* @@ -128,49 +76,85 @@ int run_builtin(t_eval_state *state, char **argv) ** \return Executable status or -1 on error */ -static int eval_cmd(t_io_frame *frame, t_eval_state *state, t_cmd *cmd) +static int eval_cmd(int fd_in, int fd_out, t_eval_state *state, t_cmd *cmd) { - void *params[PARAM_SIZE]; + t_fork_param_execve param; if (builtin_check_exec_name(cmd->argv[0])) return (run_builtin(state, cmd->argv)); - params[PARAM_EXEC_PATH] = exec_search_path( + param.exec_path = exec_search_path( state->path, env_search(state->env, "PATH"), cmd->argv[0]); - if (params[PARAM_EXEC_PATH] == NULL) + 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_RDONLY) | O_CREAT)) == -1) return (-1); - if (cmd->in != NULL) - if ((frame->pipe_in[PIPE_WRITE] = open(cmd->in, O_RDONLY)) == -1) - return (-1); - if (cmd->out != NULL) - if ((frame->pipe_out[PIPE_READ] = open(cmd->out, - (cmd->is_append ? O_APPEND : O_RDONLY) | O_CREAT)) == -1) - return (-1); - params[PARAM_ARGV] = cmd->argv; - params[PARAM_ENVP] = state->env->data; - return (exec_wrap(frame, params, &execve_wrapper)); + 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 +** \param line Line to evaluate +** \return Last Executed command status or -1 on error +*/ +static int eval_line(void *param) +{ + int status; + t_eval_state *state; + t_line *line; + int fd_in; + int fd_out; + + state = ((t_fork_param_line*)param)->state; + line = ((t_fork_param_line*)param)->line; + fd_in = ((t_fork_param_line*)param)->fd_in; + fd_out = ((t_fork_param_line*)param)->fd_out; + + /* if (line->right == NULL) */ + /* return (eval(state, line->left)); */ + + /* if (line->sep == SEP_PIPE) */ + /* pipe(state->p); */ + + if (line->left->tag == TAG_LINE) + { + return (fork_wrap(fd_in, fd_out, param, &eval_line)); + } + if ((status = eval(fd_in, fd_out, state, line->left)) == -1) + return (-1); + if ((line->sep == SEP_AND && status != 0) || + (line->sep == SEP_OR && status == 0)) + return (status); + + return (eval(fd_in, fd_out, state, line->right)); } /* ** \brief Evaluate an AST ** \param state State of the evaluation ** \param ast Abstract syntax tree to evaluate -** \return Executable status or -1 on error +** \return Last command status or -1 on error */ -int eval(t_io_frame *frame, t_eval_state *state, t_ast *ast) +int eval(int fd_in, int fd_out, t_eval_state *state, t_ast *ast) { - void *params[PARAM_SIZE]; + t_fork_param_line param; errno = 0; - if (ast->tag == TAG_ROOT) + if (ast->tag == TAG_LINE) { - params[PARAM_STATE] = state; - params[PARAM_LINE] = &ast->data.line; - return (eval_root(params)); + param.state = state; + param.line = &ast->line; + param.fd_in = fd_in; + param.fd_out = fd_out; + return (eval_line(¶m)); } - if (ast->tag == TAG_LINE) - return (eval_line(frame, state, &ast->data.line)); if (ast->tag == TAG_CMD) - return (eval_cmd(frame, state, &ast->data.cmd)); + return (eval_cmd(fd_in, fd_out, state, &ast->cmd)); return (-1); } diff --git a/src/preprocess.c b/src/preprocess.c index 1151bca..c30bb70 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/04/05 14:58:00 by charles ### ########.fr */ +/* Updated: 2020/04/05 15:04:06 by charles ### ########.fr */ /* */ /* ************************************************************************** */ -- cgit