feat: added variable expansion
quote removal is not implemented yet in this commit
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/10/22 18:37:38 by sede-san #+# #+# */
|
||||
/* Updated: 2026/02/12 03:06:20 by sede-san ### ########.fr */
|
||||
/* Updated: 2026/02/12 20:55:49 by sede-san ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -22,6 +22,18 @@ static t_list *ft_lstfind(
|
||||
bool (*pre)(void *)
|
||||
);
|
||||
|
||||
static void expand_variable(
|
||||
char **argument,
|
||||
int *i,
|
||||
t_minishell *minishell
|
||||
);
|
||||
|
||||
static void expand(
|
||||
t_list **commands,
|
||||
t_minishell *minishell
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Converts a command line string into a list of commands.
|
||||
*
|
||||
@@ -42,9 +54,8 @@ t_list *parse(
|
||||
return (NULL);
|
||||
tokens = lex(line);
|
||||
commands = parse_tokens(tokens);
|
||||
(void)minishell;
|
||||
// expand_variables(commands, minishell);
|
||||
ft_lstclear(&tokens, (void (*)(void *))token_clear);
|
||||
expand(&commands, minishell);
|
||||
return (commands);
|
||||
}
|
||||
|
||||
@@ -95,6 +106,97 @@ static t_list *parse_tokens(
|
||||
return (commands);
|
||||
}
|
||||
|
||||
static void expand_variable(
|
||||
char **argument,
|
||||
int *i,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
char *expanded;
|
||||
char *variable;
|
||||
char *variable_name;
|
||||
const int start = *i + 1;
|
||||
int end;
|
||||
|
||||
end = start;
|
||||
while (ft_isalnum((*argument)[end]))
|
||||
end++;
|
||||
variable_name = ft_substr(*argument, start, end - start);
|
||||
if (variable_name == NULL)
|
||||
return (minishell->exit = true, malloc_error());
|
||||
variable = get_env(variable_name, minishell);
|
||||
free(variable_name);
|
||||
if (variable == NULL)
|
||||
variable = "";
|
||||
expanded = ft_strnjoin(3,
|
||||
ft_substr(*argument, 0, *i),
|
||||
variable,
|
||||
ft_substr(*argument,end, ft_strlen(*argument) - end));
|
||||
if (expanded == NULL)
|
||||
return (minishell->exit = true, malloc_error());
|
||||
*i += ft_strlen(variable) - 1;
|
||||
free(*argument);
|
||||
*argument = expanded;
|
||||
}
|
||||
|
||||
static void expand_argument(
|
||||
char **argument,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
bool in_single_quote;
|
||||
bool in_double_quote;
|
||||
int i;
|
||||
|
||||
in_single_quote = false;
|
||||
in_double_quote = false;
|
||||
i = 0;
|
||||
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
|
||||
{
|
||||
if ((*argument)[i] == '\'' && !in_double_quote)
|
||||
in_single_quote = !in_single_quote;
|
||||
else if ((*argument)[i] == '"' && !in_single_quote)
|
||||
in_double_quote = !in_double_quote;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void expand(
|
||||
t_list **commands,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
t_list *current_command;
|
||||
t_command *command;
|
||||
int i;
|
||||
|
||||
current_command = *commands;
|
||||
while (current_command != NULL)
|
||||
{
|
||||
command = (t_command *)current_command->content;
|
||||
i = 0;
|
||||
while (i < command->argc)
|
||||
{
|
||||
expand_argument(&command->argv[i], minishell);
|
||||
if (command->argv[i] == NULL)
|
||||
ft_lstclear(commands, (void (*)(void *))command_clear);
|
||||
i++;
|
||||
}
|
||||
if (command == NULL)
|
||||
return (ft_lstclear(commands, (void (*)(void *))command_clear));
|
||||
current_command = current_command->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a new command from a list of tokens.
|
||||
*
|
||||
@@ -203,25 +305,38 @@ void command_add_tokens(
|
||||
words_add(tokens, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts a list of arguments into an array.
|
||||
*
|
||||
* @param args The list of arguments to convert.
|
||||
* @param argc The number of arguments in the list.
|
||||
*
|
||||
* @return An array of arguments or `NULL` on error.
|
||||
*
|
||||
* @note The `args` list is cleared after the conversion and set to NULL.
|
||||
*/
|
||||
char **args_to_array(
|
||||
t_list *args,
|
||||
t_list **args,
|
||||
size_t argc
|
||||
)
|
||||
{
|
||||
char **argv;
|
||||
size_t i;
|
||||
char **argv;
|
||||
t_list *arg;
|
||||
size_t i;
|
||||
|
||||
argv = (char **)malloc(sizeof(char *) * (argc + 1));
|
||||
if (argv == NULL)
|
||||
return (NULL);
|
||||
i = 0;
|
||||
while (args != NULL)
|
||||
arg = *args;
|
||||
while (arg != NULL)
|
||||
{
|
||||
argv[i] = (char *)args->content;
|
||||
args = args->next;
|
||||
argv[i] = (char *)arg->content;
|
||||
arg = arg->next;
|
||||
i++;
|
||||
}
|
||||
argv[i] = NULL;
|
||||
ft_lstclear_nodes(args);
|
||||
return (argv);
|
||||
}
|
||||
|
||||
@@ -253,7 +368,7 @@ void words_add(
|
||||
token = (t_token *)arg->content;
|
||||
}
|
||||
*tokens = arg;
|
||||
(*command)->argv = args_to_array(args, (*command)->argc);
|
||||
(*command)->argv = args_to_array(&args, (*command)->argc);
|
||||
ft_lstclear_nodes(&args);
|
||||
}
|
||||
|
||||
@@ -374,52 +489,56 @@ t_list *ft_lstfind(
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void print_command_info(
|
||||
t_command *command
|
||||
)
|
||||
{
|
||||
printf("Command:\n");
|
||||
printf(" argc: %d\n", command->argc);
|
||||
printf(" argv: [");
|
||||
for (int i = 0; i < command->argc; i++)
|
||||
{
|
||||
printf("%s", command->argv[i]);
|
||||
if (i < command->argc - 1)
|
||||
printf(", ");
|
||||
}
|
||||
printf("]\n");
|
||||
printf(" path: %s\n", command->path);
|
||||
printf(" redirections:\n");
|
||||
t_list *redirection_node = command->redirections;
|
||||
while (redirection_node != NULL)
|
||||
{
|
||||
t_redirection *redirection = (t_redirection *)redirection_node->content;
|
||||
printf(" type: %d, target: %s\n", redirection->type, redirection->target);
|
||||
redirection_node = redirection_node->next;
|
||||
}
|
||||
printf(" heredocs:\n");
|
||||
t_list *heredoc_node = command->heredocs;
|
||||
while (heredoc_node != NULL)
|
||||
{
|
||||
t_redirection *heredoc = (t_redirection *)heredoc_node->content;
|
||||
printf(" type: %d, target: %s\n", heredoc->type, heredoc->target);
|
||||
heredoc_node = heredoc_node->next;
|
||||
}
|
||||
}
|
||||
// void print_command_info(
|
||||
// t_command *command
|
||||
// )
|
||||
// {
|
||||
// printf("Command:\n");
|
||||
// printf(" argc: %d\n", command->argc);
|
||||
// printf(" argv: [");
|
||||
// for (int i = 0; i < command->argc; i++)
|
||||
// {
|
||||
// printf("%s", command->argv[i]);
|
||||
// if (i < command->argc - 1)
|
||||
// printf(", ");
|
||||
// }
|
||||
// printf("]\n");
|
||||
// printf(" path: %s\n", command->path);
|
||||
// printf(" redirections:\n");
|
||||
// t_list *redirection_node = command->redirections;
|
||||
// while (redirection_node != NULL)
|
||||
// {
|
||||
// t_redirection *redirection = (t_redirection *)redirection_node->content;
|
||||
// printf(" type: %d, target: %s\n", redirection->type, redirection->target);
|
||||
// redirection_node = redirection_node->next;
|
||||
// }
|
||||
// printf(" heredocs:\n");
|
||||
// t_list *heredoc_node = command->heredocs;
|
||||
// while (heredoc_node != NULL)
|
||||
// {
|
||||
// t_redirection *heredoc = (t_redirection *)heredoc_node->content;
|
||||
// printf(" type: %d, target: %s\n", heredoc->type, heredoc->target);
|
||||
// heredoc_node = heredoc_node->next;
|
||||
// }
|
||||
// }
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
t_list *commands;
|
||||
char *line;
|
||||
// int main(int argc, char const *argv[], char **envp)
|
||||
// {
|
||||
// t_minishell minishell;
|
||||
// t_list *commands;
|
||||
// char *line;
|
||||
|
||||
if (argc != 2)
|
||||
return (EXIT_FAILURE);
|
||||
line = ft_strdup(argv[1]);
|
||||
commands = parse(line, NULL);
|
||||
ft_lstiter(commands, (void (*)(void *))print_command_info);
|
||||
if (line != NULL)
|
||||
free(line);
|
||||
if (commands != NULL)
|
||||
ft_lstclear(&commands, (void (*)(void *))command_clear);
|
||||
return 0;
|
||||
}
|
||||
// if (argc != 2)
|
||||
// return (EXIT_FAILURE);
|
||||
|
||||
// minishell_init(&minishell, envp);
|
||||
|
||||
// line = ft_strdup(argv[1]);
|
||||
// commands = parse(line, NULL);
|
||||
// ft_lstiter(commands, (void (*)(void *))print_command_info);
|
||||
// if (line != NULL)
|
||||
// free(line);
|
||||
// if (commands != NULL)
|
||||
// ft_lstclear(&commands, (void (*)(void *))command_clear);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user