From 9f6f48c0efa63765f0692eab0f00142967cc8d7a Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Wed, 19 Feb 2025 15:24:06 +0100 Subject: [PATCH] expansion --- inc/expander.h | 11 ++-- src/expander/expander_allocate_memory.c | 40 +++++++++++++ src/expander/expander_expand_dollar.c | 45 ++++++++++++++ .../{expander.c => expander_get_variable.c} | 47 +++------------ ...r_count_vars.c => expander_is_character.c} | 21 ++----- src/expander/expander_parse_string.c | 58 +++++++++++++++++++ src/expander/expander_parse_variables.c | 37 ++++++++++++ src/lexer/lexer_read_word.c | 2 +- src/parser/parser_get_arguments.c | 15 ++++- 9 files changed, 213 insertions(+), 63 deletions(-) create mode 100644 src/expander/expander_allocate_memory.c create mode 100644 src/expander/expander_expand_dollar.c rename src/expander/{expander.c => expander_get_variable.c} (51%) rename src/expander/{expander_count_vars.c => expander_is_character.c} (65%) create mode 100644 src/expander/expander_parse_string.c create mode 100644 src/expander/expander_parse_variables.c diff --git a/inc/expander.h b/inc/expander.h index b926783..3e61de9 100644 --- a/inc/expander.h +++ b/inc/expander.h @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/18 19:00:51 by qmennen #+# #+# */ -/* Updated: 2025/02/18 20:40:04 by qmennen ### ########.fr */ +/* Updated: 2025/02/19 15:19:50 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,8 +15,11 @@ #include "minishell.h" - -size_t expander_count_vars(const char *s); -char *expander_parse_string(char *s, t_minishell *minishell); +t_environment *expander_get_var(const char *s, int idx, t_minishell *minishell); +t_list *expander_parse_variables(const char *s, t_minishell *minishell); +char *expander_allocate_memory(const char *s, t_list *variables); +char *expander_parse_string(char *s, t_minishell *minishell); +int expander_character_valid(const char c); +int expander_expand_dollar(char *src, char *dest, int *j, t_list *variables); #endif diff --git a/src/expander/expander_allocate_memory.c b/src/expander/expander_allocate_memory.c new file mode 100644 index 0000000..286ed37 --- /dev/null +++ b/src/expander/expander_allocate_memory.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expander_allocate_memory.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 13:57:19 by qmennen #+# #+# */ +/* Updated: 2025/02/19 13:57:36 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *expander_allocate_memory(const char *s, t_list *variables) +{ + int size; + t_list *current; + t_environment *env; + char *string; + + size = 0; + current = variables; + while (current) + { + if (current->content == NULL) + { + current = current->next; + continue; + } + env = (t_environment *)current->content; + size += (ft_strlen(env->value) - ft_strlen(env->name)); + current = current->next; + } + size += ft_strlen(s); + string = malloc(size); + if (!string) + perror("expander malloc"); + return (string); +} diff --git a/src/expander/expander_expand_dollar.c b/src/expander/expander_expand_dollar.c new file mode 100644 index 0000000..414e19c --- /dev/null +++ b/src/expander/expander_expand_dollar.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expander_expand_dollar.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 15:05:58 by qmennen #+# #+# */ +/* Updated: 2025/02/19 15:22:40 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int get_var_len(const char *source, int idx) +{ + int i; + + i = 0; + while (expander_character_valid(source[idx + i])) + i++; + return (i); +} + +int expander_expand_dollar(char *src, char *dest, int *j, t_list *variables) +{ + int i; + int v_len; + t_environment *env; + + i = 0; + v_len = 0; + if (variables && variables->content) + { + env = (t_environment *)variables->content; + v_len = ft_strlen(env->name); + while (env->value[i]) + { + dest[(*j)++] = env->value[i++]; + } + } + else + v_len = get_var_len(src, (*j) + 1); + return (v_len); +} diff --git a/src/expander/expander.c b/src/expander/expander_get_variable.c similarity index 51% rename from src/expander/expander.c rename to src/expander/expander_get_variable.c index 8307e2c..924798a 100644 --- a/src/expander/expander.c +++ b/src/expander/expander_get_variable.c @@ -1,63 +1,30 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* expander.c :+: :+: :+: */ +/* expander_get_variable.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/02/18 19:00:35 by qmennen #+# #+# */ -/* Updated: 2025/02/18 21:04:00 by qmennen ### ########.fr */ +/* Created: 2025/02/19 13:59:03 by qmennen #+# #+# */ +/* Updated: 2025/02/19 13:59:14 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ -#include "environment.h" -#include "libft.h" #include "minishell.h" -#include "typedef.h" -static size_t len_var_name(const char *s, int idx) -{ - size_t i; - - i = 0; - while (s[idx + i] && ft_isalpha(s[idx + i])) - i++; - return (i); -} - -t_environment *get_var(const char *s, int idx, t_minishell *minishell) +t_environment *expander_get_var(const char *s, int idx, t_minishell *minishell) { int i; t_environment *env; char *name; i = 0; - while (s[idx + i] && ft_isalpha(s[idx + i])) + while (expander_character_valid(s[idx + i])) i++; name = ft_substr(s, idx, i); - if (!name) - perror("name"); + if (!name || !*name) + return (NULL); env = environment_get(minishell->environment, name); free(name); return (env); } - -char *expander_parse_string(char *s, t_minishell *minishell) -{ - int i; - t_environment *env; - t_list *var_list; - - i = 0; - while (s[i]) - { - if (s[i] == '$') - { - env = get_var(s, i, minishell); - if (env) - ft_lstadd_back(&var_list, ft_lstnew(env->value)); - } - i++; - } - return ft_strdup(""); -} diff --git a/src/expander/expander_count_vars.c b/src/expander/expander_is_character.c similarity index 65% rename from src/expander/expander_count_vars.c rename to src/expander/expander_is_character.c index eceae4c..161a0c8 100644 --- a/src/expander/expander_count_vars.c +++ b/src/expander/expander_is_character.c @@ -1,29 +1,18 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* expander_count_vars.c :+: :+: :+: */ +/* expander_is_character.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/02/18 20:38:17 by qmennen #+# #+# */ -/* Updated: 2025/02/18 20:39:53 by qmennen ### ########.fr */ +/* Created: 2025/02/19 13:15:11 by qmennen #+# #+# */ +/* Updated: 2025/02/19 13:15:55 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -size_t expander_count_vars(const char *s) +int expander_character_valid(const char c) { - size_t vars; - size_t i; - - i = 0; - vars = 0; - while (s[i]) - { - if (s[i] == '$' && ft_isalpha(s[i + 1])) - vars++; - i++; - } - return (vars); + return (ft_isalnum(c) || c == '_'); } diff --git a/src/expander/expander_parse_string.c b/src/expander/expander_parse_string.c new file mode 100644 index 0000000..f5e1406 --- /dev/null +++ b/src/expander/expander_parse_string.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expander_parse_string.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/18 19:00:35 by qmennen #+# #+# */ +/* Updated: 2025/02/19 15:20:04 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void free_variables(t_list *variables) +{ + t_list *current; + t_list *last; + + current = variables; + while (current) + { + last = current; + current = current->next; + free(last); + } +} + +char *expander_parse_string(char *s, t_minishell *minishell) +{ + t_list *variables; + t_list *current; + char *string; + int i; + int j; + + variables = expander_parse_variables(s, minishell); + string = expander_allocate_memory(s, variables); + i = 0; + j = 0; + current = variables; + while (s[i]) + { + if (s[i] == '$' && s[i + 1]) + { + i++; + i += expander_expand_dollar(s, string, &j, current); + if (current) + current = current->next; + } + else + string[j++] = s[i++]; + } + + string[j] = 0; + free_variables(variables); + return (string); +} diff --git a/src/expander/expander_parse_variables.c b/src/expander/expander_parse_variables.c new file mode 100644 index 0000000..b3e9023 --- /dev/null +++ b/src/expander/expander_parse_variables.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expander_parse_variables.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 13:58:13 by qmennen #+# #+# */ +/* Updated: 2025/02/19 15:07:23 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *expander_parse_variables(const char *s, t_minishell *minishell) +{ + + int i; + t_list *var_list; + t_environment *env; + + i = 0; + var_list = NULL; + while (s[i]) + { + if (s[i] == '$') + { + env = expander_get_var(s, i + 1, minishell); + if (env) + ft_lstadd_back(&var_list, ft_lstnew(env)); + else + ft_lstadd_back(&var_list, ft_lstnew(NULL)); + } + i++; + } + return (var_list); +} diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 083240a..1bbd225 100644 --- a/src/lexer/lexer_read_word.c +++ b/src/lexer/lexer_read_word.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/05 19:03:47 by qmennen #+# #+# */ -/* Updated: 2025/02/18 17:02:17 by qmennen ### ########.fr */ +/* Updated: 2025/02/19 14:12:19 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/parser/parser_get_arguments.c b/src/parser/parser_get_arguments.c index efa6e05..0cdb42b 100644 --- a/src/parser/parser_get_arguments.c +++ b/src/parser/parser_get_arguments.c @@ -31,6 +31,17 @@ static int count_cmds(t_list *list) return (cmds); } +static int parser_should_expand(t_list *value) +{ + t_token *token; + + token = (t_token *)value->content; + if (!token) + return (0); + return (token->type == T_DQWORD || (token->type == T_WORD && + token->value[0] == '$' && token->value[1])); +} + char **parser_get_arguments(t_list *list, t_minishell *minishell) { t_list *current; @@ -49,11 +60,11 @@ char **parser_get_arguments(t_list *list, t_minishell *minishell) i = -1; while ((++i) < cmds && current) { - if (((t_token *)current->content)->type == T_DQWORD) + if (parser_should_expand(current)) { args[i] = expander_parse_string(((t_token *)current->content)->value, minishell); } - if (((t_token *)current->content)->type == T_WORD || + else if (((t_token *)current->content)->type == T_WORD || ((t_token *)current->content)->type == T_SQWORD) args[i] = ft_strdup(((t_token *)current->content)->value); current = current->next;