From c1d3992fc2f372be0e5e8e8d46dddc0a6cd85b21 Mon Sep 17 00:00:00 2001 From: Loic Deridder Date: Sat, 8 Feb 2025 14:13:24 +0100 Subject: [PATCH] expand + bug fixes --- includes/exec/expander.h | 4 +- srcs/builtins/echo.c | 17 ++--- srcs/execution/exec.c | 63 +++++++++++++++++- srcs/expander/expand_tilde.c | 92 ++++++++++++++++++++++++++ srcs/expander/expand_var.c | 121 +++++++++++++++++++++++++++++++++++ srcs/expander/expander.c | 99 ++++++++++++++++------------ 6 files changed, 345 insertions(+), 51 deletions(-) create mode 100644 srcs/expander/expand_tilde.c create mode 100644 srcs/expander/expand_var.c diff --git a/includes/exec/expander.h b/includes/exec/expander.h index bd35919..3dda2ac 100644 --- a/includes/exec/expander.h +++ b/includes/exec/expander.h @@ -6,7 +6,7 @@ /* By: lderidde +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/07 10:21:00 by lderidde #+# #+# */ -/* Updated: 2025/02/07 10:22:10 by lderidde ### ########.fr */ +/* Updated: 2025/02/08 10:52:24 by lderidde ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,8 @@ # include "../minishell.h" +int expand_var(t_ast_n *node, int j); +int expand_tilde(t_ast_n *node, int j); t_ast_n *expand_node(t_ast_n *node); #endif diff --git a/srcs/builtins/echo.c b/srcs/builtins/echo.c index f99af07..c4653bd 100644 --- a/srcs/builtins/echo.c +++ b/srcs/builtins/echo.c @@ -6,7 +6,7 @@ /* By: lderidde +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/24 14:31:56 by lderidde #+# #+# */ -/* Updated: 2025/02/05 12:00:26 by lderidde ### ########.fr */ +/* Updated: 2025/02/08 11:02:58 by lderidde ### ########.fr */ /* */ /* ************************************************************************** */ @@ -78,6 +78,7 @@ static void echo_print(t_ast_n *node, int j, char **envp) { int i; + (void)envp; while (node->args[j]) { i = 0; @@ -85,13 +86,13 @@ static void echo_print(t_ast_n *node, int j, char **envp) { if (print_exit(node->args[j], node)) break ; - if (node->args[j][i] == '$') - { - if (!node->args[j][i + 1] || node->args[j][i + 1] == ' ') - ft_put_c(node->args[j][i++]); - else - i += extractenv(&node->args[j][i], envp); - } + // if (node->args[j][i] == '$') + // { + // if (!node->args[j][i + 1] || node->args[j][i + 1] == ' ') + // ft_put_c(node->args[j][i++]); + // else + // i += extractenv(&node->args[j][i], envp); + // } else ft_put_c(node->args[j][i++]); } diff --git a/srcs/execution/exec.c b/srcs/execution/exec.c index 7a3d57c..10749ea 100644 --- a/srcs/execution/exec.c +++ b/srcs/execution/exec.c @@ -6,11 +6,14 @@ /* By: lderidde +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/27 11:22:33 by lderidde #+# #+# */ -/* Updated: 2025/02/07 12:31:44 by lderidde ### ########.fr */ +/* Updated: 2025/02/08 14:09:45 by lderidde ### ########.fr */ /* */ /* ************************************************************************** */ #include "../../includes/minishell.h" +#include +#include +#include // #include // #include // #include @@ -68,6 +71,61 @@ void read_input(t_ast_n *node, int j) ft_fprintf(node->fds[1], "%s", buf); } +void read_hereinput(char *limiter) +{ + char buf[100000]; + char c; + int r; + int i; + + r = 0; + i = 0; + ft_fprintf(2, "heredoc> "); + r = read(0, &c, 1); + while (r && c != '\n' && c != '\0') + { + if (c != '\n' && c != '\0') + buf[i++] = c; + r = read(0, &c, 1); + } + buf[i] = '\0'; + if (ft_strncmp(buf, limiter, ft_strlen(limiter)) == 0) + { + ft_fprintf(1, "%s", buf); + exit(EXIT_SUCCESS); + } + buf[i++] = '\n'; + buf[i] = '\0'; + ft_fprintf(1, "%s", buf); +} + +void parse_heredoc(char *limiter) +{ + int fd; + pid_t pid; + + fd = open(".heredoc", O_WRONLY | O_CREAT | O_APPEND, 0666); + pid = fork(); + if (pid == 0) + { + dup2(fd, STDOUT_FILENO); + close (fd); + while (1) + read_hereinput(limiter); + } + else if (pid > 0) + { + waitpid(pid, NULL, 0); + close (fd); + } + else + { + close (fd); + perror("fork"); + exit (EXIT_FAILURE); + } +} + void here_doc(t_ast_n *node, int i) { pid_t pid; @@ -92,7 +150,7 @@ void here_doc(t_ast_n *node, int i) waitpid(pid, NULL, 0); } else if (pid < 0) - perror("fork"); + exit (err_msg_cmd("fork", NULL, "failed to fork", 1)); } void save_stds(t_ast_n *node) @@ -234,6 +292,7 @@ int exec(t_ast_n *node) { char *path; + expand_node(node); path = find_path(node->cmd, node->msh->env); if (!path) return_error(node->cmd, "command not found", 127); diff --git a/srcs/expander/expand_tilde.c b/srcs/expander/expand_tilde.c new file mode 100644 index 0000000..65ecc8b --- /dev/null +++ b/srcs/expander/expand_tilde.c @@ -0,0 +1,92 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_tilde.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lderidde +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/07 12:56:32 by lderidde #+# #+# */ +/* Updated: 2025/02/08 13:15:52 by lderidde ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../includes/minishell.h" + +static int get_new_len(t_ast_n *node, int j) +{ + int i; + int len; + + i = -1; + len = ft_strlen(node->args[j]); + while (node->args[j][++i]) + { + if (node->args[j][i] == '~') + { + len += ft_strlen(get_var_value("HOME", node->msh->env)) - 1; + } + } + return (len); +} + +size_t ft_astrlcat(char *dst, const char *src, size_t dstsize) +{ + size_t dst_len; + size_t src_len; + size_t i; + + if (!dst || !src) + return (0); + dst_len = ft_strlen(dst); + src_len = ft_strlen(src); + if (dstsize <= dst_len) + return (dstsize + src_len); + i = -1; + while (src[++i] && (dst_len + i) < (dstsize - 1)) + dst[dst_len + i] = src[i]; + dst[dst_len + i] = '\0'; + return (dst_len + src_len); +} + +void expander_tilde(t_ast_n *node, int j) +{ + int i; + int len; + int save; + char *new; + + i = -1; + len = get_new_len(node, j); + new = ft_calloc(len + 1, sizeof(char)); + if (!new) + return ; + save = len; + len = 0; + while (++i < save) + { + if (node->args[j][len] != '~') + new[i] = node->args[j][len++]; + else + { + ft_astrlcat(new, get_var_value("HOME", node->msh->env), -1); + i = ft_strlen(new) - 1; + len++; + } + } + ft_free(&node->args[j]); + node->args[j] = new; +} + +int expand_tilde(t_ast_n *node, int j) +{ + int i; + + i = 0; + while (node->args[j][i]) + { + if (node->args[j][i] == '~') + return (expander_tilde(node, j), 1); + i++; + } + return (0); +} diff --git a/srcs/expander/expand_var.c b/srcs/expander/expand_var.c new file mode 100644 index 0000000..f4881b3 --- /dev/null +++ b/srcs/expander/expand_var.c @@ -0,0 +1,121 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_var.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lderidde +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/07 12:58:25 by lderidde #+# #+# */ +/* Updated: 2025/02/08 10:53:48 by lderidde ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../includes/minishell.h" + +static int is_validchar(char c) +{ + if (ft_isalnum(c) || c == '_') + return (1); + return (0); +} + +static int get_var_len(t_ast_n *node, int j , int *i) +{ + int len; + int ret; + char *str; + + len = *i + 1; + while (node->args[j][len] && is_validchar(node->args[j][len])) + len++; + str = ft_substr(node->args[j], *i + 1, (size_t)len - (*i + 1)); + *i = len; + ret = ft_strlen(get_var_value(str, node->msh->env)); + ft_free(&str); + return (ret - (len - (*i + 1))); +} + +static char *extract_env(char *str, char **envp) +{ + int i; + char *var; + char *tmp; + + i = 1; + while (str[i] && is_validchar(str[i])) + i++; + if (i > 1) + tmp = ft_substr(str, 1, i - 1); + var = get_var_value(tmp, envp); + free(tmp); + return (var); +} + +static int get_new_len(t_ast_n *node, int j) +{ + int i; + int len; + + i = 0; + len = ft_strlen(node->args[j]); + while (node->args[j][i]) + { + if (node->args[j][i] == '$') + { + len += get_var_len(node, j , &i); + i--; + } + i++; + } + return (len); +} + +int valid_next(char c) +{ + if (c != '\0' && is_validchar(c)) + return (1); + return (0); +} + +void expander_var(t_ast_n *node, int j) +{ + int i; + int k; + int len; + char *new; + + i = -1; + len = get_new_len(node, j); + new = ft_calloc(len + 1, sizeof(char)); + if (!new) + return ; + k = 0; + while (node->args[j][k] && ++i < len) + { + if (node->args[j][k] != '$') + new[i] = node->args[j][k++]; + else if (node->args[j][k] == '$' && valid_next(node->args[j][k + 1])) + { + ft_strlcat(new, extract_env(&node->args[j][k], node->msh->env), -1); + i = ft_strlen(new) - 1; + while (node->args[j][++k] && is_validchar(node->args[j][k])) + continue ; + } + } + ft_free(&node->args[j]); + node->args[j] = new; +} + +int expand_var(t_ast_n *node, int j) +{ + int i; + + i = 0; + while (node->args[j][i]) + { + if (node->args[j][i] == '$') + return (expander_var(node, j), 1); + i++; + } + return (0); +} diff --git a/srcs/expander/expander.c b/srcs/expander/expander.c index 3984ba6..bdf515b 100644 --- a/srcs/expander/expander.c +++ b/srcs/expander/expander.c @@ -6,66 +6,85 @@ /* By: lderidde +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/07 10:23:02 by lderidde #+# #+# */ -/* Updated: 2025/02/07 12:31:57 by lderidde ### ########.fr */ +/* Updated: 2025/02/08 14:10:50 by lderidde ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../../includes/minishell.h" +#include "../../includes/exec/expander.h" -int get_new_len(t_ast_n *node, int j) +int remove_quote(t_ast_n *node, int j) { - int i; - int len; - - i = 0; - len = ft_strlen(node->args[j]); - while (node->args[j][++i]) - { - if (node->args[j][i] == '~') - { - len += ft_strlen(get_var_value("HOME", node->msh->env)) - 1; - } - } - return (len); -} - -void expand_tilde(t_ast_n *node, int j) -{ - int i; - int len; - int save; char *new; + int ret; - i = -1; - len = get_new_len(node, j); - new = ft_calloc(len + 1, sizeof(char)); - if (!new) - return ; - save = len; - len = 0; - while (++i < save) + ret = 0; + if (node->args[j][0]) { - if (node->args[j][len] != '~') - new[i] = node->args[j][len++]; - else - { - ft_strlcat(new, get_var_value("HOME", node->msh->env), -1); - i = ft_strlen(new) - 1; - len++; - } + if (node->args[j][0] == '\'' || node->args[j][0] == '\"') + ret = 1; } + new = ft_strtrim(node->args[j], "'\""); ft_free(&node->args[j]); node->args[j] = new; + return (ret); +} + +char **arrange_tabs(t_ast_n *node, char **tab, int j) +{ + int save; + int i; + int k; + int len; + char **new_arg; + + i = 0; + k = 0; + len = 0; + save = count_var(node->args) + count_var(tab); + new_arg = ft_calloc(sizeof(char *), save); + while (i < save - 1) + { + if (i == j) + { + while (tab[k]) + new_arg[i++] = ft_strdup(tab[k++]); + len++; + } + else + new_arg[i++] = ft_strdup(node->args[len++]); + } + return (new_arg); +} + +void split_tab(t_ast_n *node, int j) +{ + char **tab; + char **new_arg; + + + tab =ft_split(node->args[j], " "); + new_arg = arrange_tabs(node, tab, j); + free_tab(tab); + free_tab(node->args); + node->args = new_arg; } t_ast_n *expand_node(t_ast_n *node) { int i; + int check; i = -1; while (node->args[++i]) { - expand_tilde(node, i); + check = 0; + if (expand_tilde(node, i)) + check = 1; + if (expand_var(node, i)) + check = 1; + if (check && !remove_quote(node, i)) + split_tab(node, i); + (void)check; } return (node); }