diff --git a/Makefile b/Makefile index 9108b49..dd9ca2f 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ LIBFT = $(LIBFT_PATH)/libft.a OBJ_PATH = obj -VPATH = src:src/environment:src/prompt:src/lexer:src/token:src/utils:src/executor:src/parser +VPATH = src:src/environment:src/prompt:src/lexer:src/token:src/utils:src/executor:src/parser:src/expander SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c")) OBJECTS = $(addprefix $(OBJ_PATH)/, $(SOURCES:.c=.o)) diff --git a/inc/expander.h b/inc/expander.h new file mode 100644 index 0000000..4d22de6 --- /dev/null +++ b/inc/expander.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expander.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/18 19:00:51 by qmennen #+# #+# */ +/* Updated: 2025/02/18 19:05:14 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef EXPANDER_H +# define EXPANDER_H + +#include "minishell.h" + +char *expander_parse_string(char *s, t_minishell *minishell); + +#endif diff --git a/inc/minishell.h b/inc/minishell.h index 7c820b9..5543c1b 100644 --- a/inc/minishell.h +++ b/inc/minishell.h @@ -21,6 +21,7 @@ # include "tokenizer.h" # include "executor.h" # include "parser.h" +# include "expander.h" # include "utils.h" # define TRUE 1 diff --git a/inc/parser.h b/inc/parser.h index 8caaa0a..f757caa 100644 --- a/inc/parser.h +++ b/inc/parser.h @@ -16,7 +16,7 @@ # include "minishell.h" t_command *parser_command_new(char *cmd); -char **parser_get_arguments(t_list *list); -t_list *parser_get_commands(t_list *list); +char **parser_get_arguments(t_list *list, t_minishell *minishell); +t_list *parser_get_commands(t_minishell *minishell); #endif diff --git a/inc/typedef.h b/inc/typedef.h index b4ab084..c3b4b8a 100644 --- a/inc/typedef.h +++ b/inc/typedef.h @@ -16,6 +16,8 @@ typedef enum e_token_type { T_WORD, + T_DQWORD, + T_SQWORD, T_PIPE, T_REDIRECT_IN, T_REDIRECT_OUT, diff --git a/src/expander/expander.c b/src/expander/expander.c new file mode 100644 index 0000000..7910737 --- /dev/null +++ b/src/expander/expander.c @@ -0,0 +1,86 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expander.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/18 19:00:35 by qmennen #+# #+# */ +/* Updated: 2025/02/18 20:00:51 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include + +static size_t len_prefix(const char *s) +{ + size_t i; + + i = 0; + while (s[i] != '$' && s[i]) + i++; + return (i); +} + +static size_t len_var_name(const char *s) +{ + size_t start; + size_t i; + + start = len_prefix(s); + if (start == ft_strlen(s)) + return (0); + start++; + i = 0; + while (s[start + i]) + i++; + return (i); +} + +static char *get_env_value(char *s) +{ + int start; + + start = 0; + while (s[start] != '$' && s[start]) + start++; + if (s[start] != '$' || !s[start + 1]) + return (NULL); + start++; + return ft_substr(s, start, len_var_name(s)); +} + +static char *expand_string(char *s, t_environment *env) +{ + char *final_str; + + final_str = ft_calloc(1, ft_strlen(env->value) + len_prefix(s) + 1); + if (!final_str) + { + perror("malloc"); + exit(EXIT_FAILURE); + } + ft_strlcat(final_str, s, len_prefix(s) + 1); + ft_strlcat(final_str, env->value, ft_strlen(env->value)); + return (final_str); +} + +char *expander_parse_string(char *s, t_minishell *minishell) +{ + size_t l1; + char *result; + char *name; + t_environment *env; + + l1 = len_prefix(s); + if (l1 == ft_strlen(s)) + return (ft_strdup(s)); + name = get_env_value(s); + if (!name) + return (ft_strdup("")); + env = environment_get(minishell->environment, name); + result = expand_string(s, env); + free(name); + return (result); +} diff --git a/src/lexer/lexer_parse_input.c b/src/lexer/lexer_parse_input.c index 861e4eb..466d668 100644 --- a/src/lexer/lexer_parse_input.c +++ b/src/lexer/lexer_parse_input.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/05 19:09:20 by qmennen #+# #+# */ -/* Updated: 2025/02/05 19:09:26 by qmennen ### ########.fr */ +/* Updated: 2025/02/18 17:18:10 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/lexer/lexer_token_next.c b/src/lexer/lexer_token_next.c index 99dfdea..0aab9db 100644 --- a/src/lexer/lexer_token_next.c +++ b/src/lexer/lexer_token_next.c @@ -11,6 +11,17 @@ /* ************************************************************************** */ #include "minishell.h" +#include "typedef.h" + +static t_token_type get_word_type(char c) +{ + if (c == '\'') + return (T_SQWORD); + else if (c == '"') + return (T_DQWORD); + else + return (T_WORD); +} /** * @brief Retrieves the next token from the lexer. @@ -33,9 +44,10 @@ */ t_token *ft_token_next(t_lexer *lexer) { - t_token *token; - char *word; - int current_pos; + t_token *token; + t_token_type word_type; + char *word; + int current_pos; token = NULL; while (ft_isspace(lexer->current_char)) @@ -48,10 +60,11 @@ t_token *ft_token_next(t_lexer *lexer) token = token_parse(lexer); else if (ft_isprint(lexer->current_char)) { + word_type = get_word_type(lexer->current_char); word = lexer_readword(lexer); if (!word) return (token_new(T_ERROR, &lexer->current_char, current_pos)); - token = token_new(T_WORD, word, current_pos); + token = token_new(word_type, word, current_pos); free(word); } else diff --git a/src/main.c b/src/main.c index eac3a5c..fd282ac 100644 --- a/src/main.c +++ b/src/main.c @@ -38,7 +38,7 @@ int main(int argc, char **argv, char **envp) minishell->lexer = ft_lexer_new(minishell->line); minishell->tokens = ft_parse_input(minishell->lexer); ft_lstiter(minishell->tokens, token_print); - //minishell->commands = parser_get_commands(minishell->tokens); + minishell->commands = parser_get_commands(minishell); simple_builtins(minishell); free_minishell_line(minishell); ft_lstclear(&minishell->commands, free_command_list); diff --git a/src/parser/parser_get_arguments.c b/src/parser/parser_get_arguments.c index 2b428ce..efa6e05 100644 --- a/src/parser/parser_get_arguments.c +++ b/src/parser/parser_get_arguments.c @@ -16,12 +16,14 @@ static int count_cmds(t_list *list) { int cmds; t_list *current; + t_token *token; cmds = 0; current = list; while (current) { - if (((t_token *)current->content)->type != T_WORD) + token = ((t_token *)current->content); + if (token->type >= 3) break ; cmds++; current = current->next; @@ -29,7 +31,7 @@ static int count_cmds(t_list *list) return (cmds); } -char **parser_get_arguments(t_list *list) +char **parser_get_arguments(t_list *list, t_minishell *minishell) { t_list *current; char **args; @@ -47,7 +49,12 @@ char **parser_get_arguments(t_list *list) i = -1; while ((++i) < cmds && current) { - if (((t_token *)current->content)->type == T_WORD) + if (((t_token *)current->content)->type == T_DQWORD) + { + args[i] = expander_parse_string(((t_token *)current->content)->value, minishell); + } + 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; } diff --git a/src/parser/parser_get_commands.c b/src/parser/parser_get_commands.c index 786e143..a911dcf 100644 --- a/src/parser/parser_get_commands.c +++ b/src/parser/parser_get_commands.c @@ -1,35 +1,18 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* parser_get_commands.c :+: :+: */ -/* +:+ */ -/* By: qmennen +#+ */ -/* +#+ */ -/* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */ -/* Updated: 2025/02/12 20:49:00 by willem ######## odam.nl */ +/* ::: :::::::: */ +/* parser_get_commands.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */ +/* Updated: 2025/02/18 19:29:38 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -// static void print_cmds(void *content) -// { -// t_command *cmd; -// int i; - -// cmd = (t_command *)content; -// printf("cmd: %s\n", cmd->command); -// printf("args: "); -// i = 0; -// while (cmd->args[i]) -// { -// printf("%s ", cmd->args[i]); -// i++; -// } -// printf("\n"); -// } - -t_list *parser_get_commands(t_list *list) +t_list *parser_get_commands(t_minishell *minishell) { t_list *command_list; t_list *current; @@ -37,14 +20,14 @@ t_list *parser_get_commands(t_list *list) t_token *token; command_list = NULL; - if (!list) + if (!minishell->tokens) return (NULL); - current = list; + current = minishell->tokens; while (current) { token = (t_token *) current->content; command = parser_command_new(ft_strdup(token->value)); - command->args = parser_get_arguments(current); + command->args = parser_get_arguments(current, minishell); ft_lstadd_back(&command_list, ft_lstnew(command)); while (current && ((t_token *)current->content)->type == T_WORD) current = current->next;