A POR TODAAS
This commit is contained in:
@@ -6,170 +6,54 @@
|
||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2026/02/13 21:24:45 by sede-san #+# #+# */
|
||||
/* Updated: 2026/02/14 05:45:59 by sede-san ### ########.fr */
|
||||
/* Updated: 2026/02/14 06:56:00 by sede-san ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser.h"
|
||||
#include "errors.h"
|
||||
#include "variables.h"
|
||||
#include "parser_expand_internal.h"
|
||||
|
||||
static char *replace_value(char *original, char *value, int start, int end);
|
||||
static void expand_variable(char **argument, int *i, t_minishell *minishell);
|
||||
static void expand_argument(char **argument, t_minishell *minishell);
|
||||
|
||||
static char *replace_value(
|
||||
char *original,
|
||||
char *value,
|
||||
int start,
|
||||
int end
|
||||
)
|
||||
{
|
||||
const char *before = ft_substr(original, 0, start);
|
||||
const char *after = ft_substr(original, end, ft_strlen(original) - end);
|
||||
const char *expanded = ft_strnjoin(3, before, value, after);
|
||||
|
||||
free((char *)before);
|
||||
free((char *)after);
|
||||
return ((char *)expanded);
|
||||
}
|
||||
|
||||
static void expand_variable(
|
||||
char **argument,
|
||||
int *i,
|
||||
static bool expand_argv(
|
||||
t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
char *expanded;
|
||||
char *variable_name;
|
||||
char *variable_value;
|
||||
const int start = *i + 1;
|
||||
int end;
|
||||
|
||||
end = start;
|
||||
while (ft_isalnum((*argument)[end]) || (*argument)[end] == '_'
|
||||
|| (*argument)[end] == '?')
|
||||
end++;
|
||||
variable_name = ft_substr(*argument, start, end - start);
|
||||
if (variable_name == NULL)
|
||||
return (minishell->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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user