diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-06-09 10:53:57 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-06-09 10:53:57 +0200 |
| commit | c16cf5fcc4a421608bf3c291ef84a79b7dbe7591 (patch) | |
| tree | 2c7b814f7e9eee40d34a6cf26b4948c39fecfc4c /src | |
| parent | 9dca7dc98e46d5b29e236f2970072ffaf582e13e (diff) | |
| parent | 9fabc25a980550afc6337fd729632462f2680daa (diff) | |
| download | minishell-c16cf5fcc4a421608bf3c291ef84a79b7dbe7591.tar.gz minishell-c16cf5fcc4a421608bf3c291ef84a79b7dbe7591.tar.bz2 minishell-c16cf5fcc4a421608bf3c291ef84a79b7dbe7591.zip | |
Merge branch 'eval'
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast.c | 16 | ||||
| -rw-r--r-- | src/builtin/cd.c | 11 | ||||
| -rw-r--r-- | src/builtin/echo.c | 6 | ||||
| -rw-r--r-- | src/builtin/export.c | 6 | ||||
| -rw-r--r-- | src/builtin/unset.c | 5 | ||||
| -rw-r--r-- | src/env.c | 41 | ||||
| -rw-r--r-- | src/eval/eval.c | 148 | ||||
| -rw-r--r-- | src/glob.c | 162 | ||||
| -rw-r--r-- | src/main.c | 64 | ||||
| -rw-r--r-- | src/path.c | 28 | ||||
| -rw-r--r-- | src/preprocess.c | 69 | ||||
| -rw-r--r-- | src/utils.c | 54 |
12 files changed, 480 insertions, 130 deletions
@@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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/builtin/cd.c b/src/builtin/cd.c index 66f1f81..ed0b3cc 100644 --- a/src/builtin/cd.c +++ b/src/builtin/cd.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:10:20 by charles #+# #+# */ -/* Updated: 2020/04/01 22:15:49 by charles ### ########.fr */ +/* Updated: 2020/04/03 12:11:52 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,14 +19,11 @@ int builtin_cd(char **argv, t_env env) { - char *path; - - path = argv[1]; + //change $PWD + (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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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..1d362b3 100644 --- a/src/builtin/export.c +++ b/src/builtin/export.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:11:34 by charles #+# #+# */ -/* Updated: 2020/04/01 22:37:47 by charles ### ########.fr */ +/* Updated: 2020/04/03 12:11:38 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,11 +21,13 @@ 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) 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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); } @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 09:21:24 by cacharle #+# #+# */ -/* Updated: 2020/04/01 23:09:33 by charles ### ########.fr */ +/* Updated: 2020/04/05 14:42:38 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`) @@ -26,26 +28,19 @@ t_env env_from_array(char **envp) { 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)) == NULL) + if ((env = ft_vecnew(ENV_VEC_DEFAULT_SIZE)) == NULL) return (NULL); - env->size = i; - i = 0; - while (envp[i] != NULL) + while (*envp != NULL) { - if ((env->data[i] = ft_strdup(envp[i])) == NULL) + if (ft_vecpush_safe(env, ft_strdup(*envp)) == NULL) { ft_vecdestroy(env, free); return (NULL); } - i++; + envp++; } - return (env); + return (ft_vecpush(env, NULL)); } /** @@ -55,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; @@ -68,3 +64,22 @@ char *env_search(t_env env, char *key) } return (NULL); } + +char *env_search_first_match(t_env env, const char *haystack) +{ + int len; + size_t i; + + if (ft_isdigit(*haystack)) + return (NULL); + len = 0; + 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/eval/eval.c b/src/eval/eval.c index 8c1e509..0270024 100644 --- a/src/eval/eval.c +++ b/src/eval/eval.c @@ -6,7 +6,7 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:21 by charles #+# #+# */ -/* Updated: 2020/04/01 23:15:16 by charles ### ########.fr */ +/* Updated: 2020/05/04 12:00:38 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,24 +18,55 @@ #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 +** \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 */ -static int eval_line(t_eval_state *state, t_line *line) +int fork_wrap( + int fd_in, + int fd_out, + void *passed, + int (*wrapped)(void *param)) { - int status; + int status; + pid_t child_pid; - if (line->right == NULL) - return (eval(state, line->left)); - if ((status = eval(state, line->left)) == -1) + if ((child_pid = fork()) == -1) return (-1); - if ((line->sep == SEP_AND && status != 0) || - (line->sep == SEP_OR && status == 0)) - return (status); - return (eval(state, line->right)); + 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 + )); } /* @@ -45,48 +76,85 @@ static int eval_line(t_eval_state *state, t_line *line) ** \return Executable status or -1 on error */ -static int eval_cmd(t_eval_state *state, t_cmd *cmd) +static int eval_cmd(int fd_in, int fd_out, t_eval_state *state, t_cmd *cmd) { - int child_pid; - char *exec_path; - bool is_builtin; + t_fork_param_execve param; - 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) + 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 (child_pid == 0) + 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); + 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) { - 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) - exit(EXIT_FAILURE); - exit(EXIT_SUCCESS); + return (fork_wrap(fd_in, fd_out, param, &eval_line)); } - wait(&child_pid); - return (WEXITSTATUS(child_pid)); + 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_eval_state *state, t_ast *ast) +int eval(int fd_in, int fd_out, t_eval_state *state, t_ast *ast) { + t_fork_param_line param; + errno = 0; if (ast->tag == TAG_LINE) - return (eval_line(state, &ast->data.line)); + { + 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_CMD) - return (eval_cmd(state, &ast->data.cmd)); + return (eval_cmd(fd_in, fd_out, state, &ast->cmd)); return (-1); } 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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); +} @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/04/01 23:12:51 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 @@ -32,28 +33,28 @@ 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; */ 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 +65,20 @@ 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; - printf("ret: %d %s\n", eval(&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)); */ - 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 +86,11 @@ int main(int argc, char **argv, char **envp) /* free(line); */ /* } */ /* free(line); */ - ft_htdestroy(path, ht_del_str_entry); + /* ft_htdestroy(path, free); */ + /* ms_glob("src#<{(|"); */ + char *j = ms_glob("*/*.c"); + printf("%s\n", j); + free(j); ft_vecdestroy(env, free); return (0); } @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/27 15:51:01 by cacharle #+# #+# */ -/* Updated: 2020/04/01 17:55:28 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 @@ -31,24 +32,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 *tmp; + 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 ((tmp = ft_strjoin3(dirname, "/", entry->d_name)) == NULL) - return (NULL); - if (ft_htset(path, entry->d_name, tmp, ht_del_str_entry) == NULL) - return (NULL); + free(filepath); + return (-1); } - if (closedir(dir) == -1) - return (NULL); - return (path); + return (0); } /* @@ -71,8 +65,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..c30bb70 --- /dev/null +++ b/src/preprocess.c @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* preprocess.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/04/03 08:58:49 by charles #+# #+# */ +/* Updated: 2020/04/05 15:04:06 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include "ms_glob.h" + +static char *iterpolate(char *str, t_env env) +{ + size_t i; + t_ftdstr *dstr; + char *match; + + if ((dstr = ft_dstrnew(str)) == NULL) + return (NULL); + free(str); + i = 0; + while (i < dstr->length) + { + if (dstr->str[i] == '$') + { + if ((match = env_search_first_match(env, dstr->str + i + 1)) == NULL) + ft_dstrerase(dstr, i, utils_var_end(dstr->str + i + 1)); + else + { + if (ft_dstrsubstitute(dstr, match, i, utils_var_end(dstr->str + i + 1)) == NULL) + return (NULL); + } + } + i++; + } + return (ft_dstrunwrap(dstr)); +} + +static char *preprocess_arg(char *arg, t_env env) +{ + if (*arg == '\'') + return (ft_strsubf(arg, 1, ft_strlen(arg) - 1)); + if (*arg == '"') + { + if (ft_strchr(arg, '$') != NULL) + arg = iterpolate(arg, env); + return (ft_strsubf(arg, 1, ft_strlen(arg) - 1)); + } + if (ft_strchr(arg, '$') != NULL) + return (iterpolate(arg, env)); + if (ft_strchr(arg, '*') != NULL) + return (ms_glob(arg)); + return (arg); +} + +char **preprocess_argv(char **argv, t_env env) +{ + int i; + + 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 1649199..dd89457 100644 --- a/src/utils.c +++ b/src/utils.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:56:31 by cacharle #+# #+# */ -/* Updated: 2020/04/01 17:55:34 by charles ### ########.fr */ +/* Updated: 2020/04/05 14:51:52 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,17 +17,47 @@ #include "minishell.h" -/* -** \brief Delete function for a entry containing -** an allocated key and value -** \param entry Hash table entry -*/ +int utils_directory_iter( + char *dirname, + void *param, + int (*f)(char*, struct dirent*, void*) +) +{ + DIR *dir; + struct dirent *entry; -void ht_del_str_entry(t_ftht_entry *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); +} + +/* 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) { - if (entry == NULL) - return ; - free(entry->key); - free(entry->value); - free(entry); + size_t i; + + if (ft_isdigit(*name)) + return (0); + i = 0; + while (ft_isalnum(name[i]) || name[i] == '_') + i++; + return (i); } |
