aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-06-09 10:53:57 +0200
committerCharles <sircharlesaze@gmail.com>2020-06-09 10:53:57 +0200
commitc16cf5fcc4a421608bf3c291ef84a79b7dbe7591 (patch)
tree2c7b814f7e9eee40d34a6cf26b4948c39fecfc4c /src
parent9dca7dc98e46d5b29e236f2970072ffaf582e13e (diff)
parent9fabc25a980550afc6337fd729632462f2680daa (diff)
downloadminishell-c16cf5fcc4a421608bf3c291ef84a79b7dbe7591.tar.gz
minishell-c16cf5fcc4a421608bf3c291ef84a79b7dbe7591.tar.bz2
minishell-c16cf5fcc4a421608bf3c291ef84a79b7dbe7591.zip
Merge branch 'eval'
Diffstat (limited to 'src')
-rw-r--r--src/ast.c16
-rw-r--r--src/builtin/cd.c11
-rw-r--r--src/builtin/echo.c6
-rw-r--r--src/builtin/export.c6
-rw-r--r--src/builtin/unset.c5
-rw-r--r--src/env.c41
-rw-r--r--src/eval/eval.c148
-rw-r--r--src/glob.c162
-rw-r--r--src/main.c64
-rw-r--r--src/path.c28
-rw-r--r--src/preprocess.c69
-rw-r--r--src/utils.c54
12 files changed, 480 insertions, 130 deletions
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 <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);
}
diff --git a/src/env.c b/src/env.c
index 66b4994..41aca6d 100644
--- a/src/env.c
+++ b/src/env.c
@@ -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, &param, &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(&param));
+ }
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, &param,
+ (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 c46324f..d9302ad 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/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);
}
diff --git a/src/path.c b/src/path.c
index f1424cc..d768d07 100644
--- a/src/path.c
+++ b/src/path.c
@@ -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);
}