From dd6101edecab707783265f29a4cf11cef90b2874 Mon Sep 17 00:00:00 2001 From: marcnava-42cursus Date: Sat, 14 Feb 2026 06:14:59 +0100 Subject: [PATCH] A POR TODAAS --- src/parser/parser_expand.c | 215 ++++++------------------ src/parser/parser_expand_internal.h | 35 ++++ src/parser/parser_expand_variable.c | 82 +++++++++ src/parser/parser_expand_word.c | 100 +++++++++++ src/variables/environment/environment.c | 4 +- 5 files changed, 269 insertions(+), 167 deletions(-) create mode 100644 src/parser/parser_expand_internal.h create mode 100644 src/parser/parser_expand_variable.c create mode 100644 src/parser/parser_expand_word.c diff --git a/src/parser/parser_expand.c b/src/parser/parser_expand.c index 342b07d..07c1bf1 100644 --- a/src/parser/parser_expand.c +++ b/src/parser/parser_expand.c @@ -6,170 +6,54 @@ /* By: sede-san exit = true, malloc_error()); - variable_value = get_var(variable_name, minishell); - free(variable_name); - if (variable_value == NULL) - variable_value = ""; - expanded = replace_value(*argument, variable_value, start - 1, end); - if (expanded == NULL) - return (minishell->exit = true, malloc_error()); - *i += ft_strlen(variable_value); - free(*argument); - *argument = expanded; -} - -static void toggle_quotes( - char quote, - bool *in_single_quote, - bool *in_double_quote -) -{ - if (quote == '\'' && !*in_double_quote) - *in_single_quote = !*in_single_quote; - else if (quote == '\"' && !*in_single_quote) - *in_double_quote = !*in_double_quote; -} - -static void remove_quotes( - char **argument, - int start, - int end, - int length -) -{ - char *before; - char *quoted; - char *after; - - if ((*argument)[start] != '\'' && (*argument)[start] != '\"') - return ; - before = ft_substr(*argument, 0, start); - quoted = ft_substr(*argument, start + 1, end - start - 1); - after = ft_substr(*argument, end + 1, ft_strlen(*argument) - end - 1); - free(*argument); - *argument = ft_strnjoin(3, before, quoted, after); - free((char *)before); - free((char *)after); - free((char *)quoted); -} - -static void check_boundaries( - bool in_single_quote, - bool in_double_quote, - int *quote_boundaries, - int i -) -{ - if ((in_single_quote || in_double_quote) && quote_boundaries[0] == -1) - quote_boundaries[0] = i; - else if (!in_single_quote && !in_double_quote - && quote_boundaries[0] != -1 && quote_boundaries[1] == -1) - quote_boundaries[1] = i; -} - -static void handle_quotes( - char **argument, - int *i, - bool *in_single_quote, - t_minishell *minishell -) -{ - bool in_double_quote; - int quote_boundaries[2]; - - quote_boundaries[0] = -1; - quote_boundaries[1] = -1; - in_double_quote = false; - while ((*argument)[*i] != '\0') - { - if ((*argument)[*i] == '$' && !*in_single_quote) - { - expand_variable(argument, i, minishell); - if (*argument == NULL) - return (minishell->exit = true, malloc_error()); - } - else - { - toggle_quotes((*argument)[*i], in_single_quote, &in_double_quote); - check_boundaries( - *in_single_quote, in_double_quote, quote_boundaries, *i); - (*i)++; - } - } - if (*in_single_quote || in_double_quote) - return (syntax_error_unexpected_token(NULL)); - return (remove_quotes( - argument, quote_boundaries[0], quote_boundaries[1], *i)); -} - -static void expand_argument( - char **argument, - t_minishell *minishell -) -{ - bool in_single_quote; int i; + char *expanded; - in_single_quote = false; i = 0; - while ((*argument)[i] != '\0') + while (i < command->argc) { - if ((*argument)[i] == '$' && !in_single_quote) - { - expand_variable(argument, &i, minishell); - if (*argument == NULL) - return (minishell->exit = true, malloc_error()); - } - else - handle_quotes(argument, &i, &in_single_quote, minishell); + expanded = parser_expand_word(command->argv[i], minishell, true); + if (expanded == NULL) + return (false); + free(command->argv[i]); + command->argv[i] = expanded; + i++; } + return (true); +} + +static bool expand_redirections( + t_list *redirections, + t_minishell *minishell, + bool expand_vars +) +{ + t_redirection *redirection; + char *expanded; + + while (redirections != NULL) + { + redirection = (t_redirection *)redirections->content; + expanded = parser_expand_word(redirection->target, minishell, + expand_vars); + if (expanded == NULL) + return (false); + free(redirection->target); + redirection->target = expanded; + redirections = redirections->next; + } + return (true); } void expand( @@ -177,24 +61,23 @@ void expand( t_minishell *minishell ) { - t_list *current_command; + t_list *current; t_command *command; - int i; - current_command = *commands; - while (current_command != NULL) + if (commands == NULL || *commands == NULL) + return ; + current = *commands; + while (current != NULL) { - command = (t_command *)current_command->content; - i = 0; - while (i < command->argc) + command = (t_command *)current->content; + if (!expand_argv(command, minishell) + || !expand_redirections(command->redirections, minishell, true) + || !expand_redirections(command->heredocs, minishell, false)) { - expand_argument(&command->argv[i], minishell); - if (command->argv[i] == NULL) - ft_lstclear(commands, (void (*)(void *))command_clear); - i++; + ft_lstclear(commands, (void (*)(void *))command_clear); + *commands = NULL; + return ; } - if (command == NULL) - return (ft_lstclear(commands, (void (*)(void *))command_clear)); - current_command = current_command->next; + current = current->next; } } diff --git a/src/parser/parser_expand_internal.h b/src/parser/parser_expand_internal.h new file mode 100644 index 0000000..2083490 --- /dev/null +++ b/src/parser/parser_expand_internal.h @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_expand_internal.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: sede-san exit = true; + malloc_error(); +} + +static bool is_var_char( + char c +) +{ + return (ft_isalnum(c) || c == '_'); +} + +static char *dup_or_error( + const char *value, + t_minishell *minishell +) +{ + char *dup; + + dup = ft_strdup(value); + if (dup == NULL) + return (parser_expand_malloc_error(minishell), NULL); + return (dup); +} + +static char *expand_named_variable( + const char *word, + size_t *i, + t_minishell *minishell +) +{ + char *name; + char *value; + size_t start; + + start = *i; + while (word[*i] != '\0' && is_var_char(word[*i])) + (*i)++; + name = ft_substr(word, start, *i - start); + if (name == NULL) + return (parser_expand_malloc_error(minishell), NULL); + value = get_var(name, minishell); + free(name); + if (value == NULL) + value = ""; + return (dup_or_error(value, minishell)); +} + +char *parser_expand_variable(const char *word, size_t *i, + t_minishell *minishell) +{ + char *expanded; + + (*i)++; + if (word[*i] == '?') + { + expanded = ft_itoa(minishell->exit_status); + if (expanded == NULL) + return (parser_expand_malloc_error(minishell), NULL); + return ((*i)++, expanded); + } + if (word[*i] == '\0' || !is_var_char(word[*i])) + return (dup_or_error("$", minishell)); + return (expand_named_variable(word, i, minishell)); +} diff --git a/src/parser/parser_expand_word.c b/src/parser/parser_expand_word.c new file mode 100644 index 0000000..9d24191 --- /dev/null +++ b/src/parser/parser_expand_word.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_expand_word.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: sede-san exit_status = 2, NULL); + return (result); +} diff --git a/src/variables/environment/environment.c b/src/variables/environment/environment.c index 6b72f39..095f9fc 100644 --- a/src/variables/environment/environment.c +++ b/src/variables/environment/environment.c @@ -71,7 +71,9 @@ void set_env( } } val = value; - if (val != NULL) + if (val == NULL) + val = ft_strdup(""); + else val = ft_strdup(value); if (val == NULL) {