From 3b1ad5500b726e7990da6f19ce895d584a78ba16 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 13:06:44 +0100 Subject: [PATCH 01/26] fix expanding --- src/expander/expander_parse_string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/expander/expander_parse_string.c b/src/expander/expander_parse_string.c index a8752ac..42253bf 100644 --- a/src/expander/expander_parse_string.c +++ b/src/expander/expander_parse_string.c @@ -40,9 +40,9 @@ char *expander_parse_string(char *s, t_minishell *msh) current = variables; i = 0; j = 0; - while (s[i] && current) + while (s[i]) { - if (s[i] == '$' && s[i + 1]) + if (s[i] == '$' && s[i + 1] && current) { i++; i += expander_expand_dollar(s + i, string, &j, current); From 90678d8f0f26729e7dde98b7d044884e285975b9 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 13:09:30 +0100 Subject: [PATCH 02/26] check if the path found is executable --- src/executor/executor_child.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index 904bedd..299b77c 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -22,7 +22,7 @@ void executor_child(t_minishell *msh, t_command *command) dup2(command->fd_out, 1); executor_close_fds(command->n_fds); path = executor_absolute_path(msh, command->args[0]); - if (path == NULL) + if (path == NULL || !access(path, F_OK | X_OK)) { ft_putstr_fd(RED BOLD, 2); ft_putstr_fd(command->args[0], 2); From 13adfc5a0740f244aff4cb278f168c96f9b740a0 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 15:58:18 +0100 Subject: [PATCH 03/26] fix: check if path is a dir --- src/executor/executor_child.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index 299b77c..cebe4c9 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -6,11 +6,24 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/12 21:25:10 by willem #+# #+# */ -/* Updated: 2025/02/26 18:20:34 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 13:50:26 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +#include + +static int is_dir(char *path) +{ + struct stat path_stats; + + if (stat(path, &path_stats) < 0) + { + error_msg("is_dir", "path could not be read"); + return (0); + } + return S_ISDIR(path_stats.st_mode); +} void executor_child(t_minishell *msh, t_command *command) { @@ -22,7 +35,14 @@ void executor_child(t_minishell *msh, t_command *command) dup2(command->fd_out, 1); executor_close_fds(command->n_fds); path = executor_absolute_path(msh, command->args[0]); - if (path == NULL || !access(path, F_OK | X_OK)) + // TODO: If the path variable points to a dir, it exists so the command won't fail (while ofc it should?) + if (is_dir(path)) + { + ft_putstr_fd(RED BOLD, 2); + ft_putstr_fd(command->args[0], 2); + ft_putstr_fd(": " RESET "is a directory\n", 2); + } + if (path == NULL || access(path, F_OK | X_OK) != 0) { ft_putstr_fd(RED BOLD, 2); ft_putstr_fd(command->args[0], 2); From bceabcb382f55b13d64d9de276b09bd90f736707 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:01:11 +0100 Subject: [PATCH 04/26] fix: message --- src/executor/executor_child.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index cebe4c9..41afdb5 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -39,6 +39,7 @@ void executor_child(t_minishell *msh, t_command *command) if (is_dir(path)) { ft_putstr_fd(RED BOLD, 2); + ft_putstr_fd("minishell: ", 2); ft_putstr_fd(command->args[0], 2); ft_putstr_fd(": " RESET "is a directory\n", 2); } From 859b9c181a1069558491ec654e2a0036ec487490 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:02:41 +0100 Subject: [PATCH 05/26] fix: dir check after path confirmed --- src/executor/executor_child.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index 41afdb5..fde3237 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -36,13 +36,6 @@ void executor_child(t_minishell *msh, t_command *command) executor_close_fds(command->n_fds); path = executor_absolute_path(msh, command->args[0]); // TODO: If the path variable points to a dir, it exists so the command won't fail (while ofc it should?) - if (is_dir(path)) - { - ft_putstr_fd(RED BOLD, 2); - ft_putstr_fd("minishell: ", 2); - ft_putstr_fd(command->args[0], 2); - ft_putstr_fd(": " RESET "is a directory\n", 2); - } if (path == NULL || access(path, F_OK | X_OK) != 0) { ft_putstr_fd(RED BOLD, 2); @@ -50,5 +43,12 @@ void executor_child(t_minishell *msh, t_command *command) ft_putstr_fd(": " RESET "command not found\n", 2); return ; } + if (is_dir(path)) + { + ft_putstr_fd(RED BOLD, 2); + ft_putstr_fd("minishell: ", 2); + ft_putstr_fd(command->args[0], 2); + ft_putstr_fd(": " RESET "is a directory\n", 2); + } execve(path, command->args, environment_get_arr(msh)); } From e5569d9b0b6dd1abfce7fcb5f56687d6df15af00 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:05:15 +0100 Subject: [PATCH 06/26] refactor: creating commands --- inc/parser.h | 47 ++++++++++--------- ...r_new_command.c => parser_alloc_command.c} | 2 +- src/parser/parser_create_command.c | 20 ++++++++ src/parser/parser_get_commands.c | 17 +++---- 4 files changed, 51 insertions(+), 35 deletions(-) rename src/parser/{parser_new_command.c => parser_alloc_command.c} (95%) create mode 100644 src/parser/parser_create_command.c diff --git a/inc/parser.h b/inc/parser.h index c07368f..beba406 100644 --- a/inc/parser.h +++ b/inc/parser.h @@ -1,23 +1,24 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* parser.h :+: :+: */ -/* +:+ */ -/* By: qmennen +#+ */ -/* +#+ */ -/* Created: 2025/02/11 14:03:03 by qmennen #+# #+# */ -/* Updated: 2025/02/11 17:19:01 by whaffman ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#ifndef PARSER_H -# define PARSER_H - -# include "minishell.h" - -t_command *parser_command_new(t_minishell *msh, char *cmd); -char **parser_get_arguments(t_list *list, t_minishell *msh); -t_list *parser_get_commands(t_minishell *msh); -t_list *parser_get_input_redirects(t_list *list); - -#endif +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* parser.h :+: :+: */ +/* +:+ */ +/* By: qmennen +#+ */ +/* +#+ */ +/* Created: 2025/02/11 14:03:03 by qmennen #+# #+# */ +/* Updated: 2025/02/11 17:19:01 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#ifndef PARSER_H +# define PARSER_H + +# include "minishell.h" + +t_command *parser_alloc_command(t_minishell *msh, char *cmd); +void parser_create_command(t_minishell *msh, t_command *cmd, t_list **l_tkn); +char **parser_get_arguments(t_list *list, t_minishell *msh); +t_list *parser_get_commands(t_minishell *msh); +t_list *parser_get_input_redirects(t_list *list); + +#endif diff --git a/src/parser/parser_new_command.c b/src/parser/parser_alloc_command.c similarity index 95% rename from src/parser/parser_new_command.c rename to src/parser/parser_alloc_command.c index 3599cba..fc49925 100644 --- a/src/parser/parser_new_command.c +++ b/src/parser/parser_alloc_command.c @@ -12,7 +12,7 @@ #include "minishell.h" -t_command *parser_command_new(t_minishell *msh, char *cmd) +t_command *parser_alloc_command(t_minishell *msh, char *cmd) { t_command *command; diff --git a/src/parser/parser_create_command.c b/src/parser/parser_create_command.c new file mode 100644 index 0000000..723f860 --- /dev/null +++ b/src/parser/parser_create_command.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_create_command.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/27 13:35:02 by qmennen #+# #+# */ +/* Updated: 2025/02/27 13:36:48 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void parser_create_command(t_minishell *msh, t_command *cmd, t_list **l_tkn) +{ + cmd->args = parser_get_arguments(*l_tkn, msh); + cmd->redirect_in = redirect_get_inputs(msh, *l_tkn); + cmd->redirect_out = redirect_get_outputs(msh, *l_tkn); +} diff --git a/src/parser/parser_get_commands.c b/src/parser/parser_get_commands.c index 44e182f..68bbe5a 100644 --- a/src/parser/parser_get_commands.c +++ b/src/parser/parser_get_commands.c @@ -6,19 +6,18 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */ -/* Updated: 2025/02/18 20:36:01 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 13:38:56 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -#include "utils.h" -static int is_command_token(t_token *token) +static int is_command_token(t_token *token) { return (token->type < 3 || redirect_token_type(token)); } -static int validate_redirects(t_list *lst) +static int validate_redirects(t_list *lst) { t_list *token; @@ -46,14 +45,10 @@ t_list *parser_get_commands(t_minishell *msh) while (current) { token = (t_token *) current->content; - command = parser_command_new(msh, ft_strdup_safe(msh, token->value)); - command->args = parser_get_arguments(current, msh); - command->redirect_in = redirect_get_inputs(msh, current); - command->redirect_out = redirect_get_outputs(msh, current); - if (!validate_redirects(command->redirect_in)) - { + command = parser_alloc_command(msh, ft_strdup_safe(msh, token->value)); + parser_create_command(msh, command, ¤t); + if (!validate_redirects(command->redirect_in) || !validate_redirects(command->redirect_out)) break ; - } ft_lstadd_back(&command_list, ft_lstnew_safe(msh, command)); while (current && is_command_token((t_token *)current->content)) current = current->next; From 4cdc9c35304ee3d1d062ee10443973d2713bc6cd Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:09:36 +0100 Subject: [PATCH 07/26] more refactor for parser --- inc/parser.h | 5 ++-- sources.mk | 24 ++++++++++++++++++ src/parser/parser_get_commands.c | 18 ++------------ src/parser/parser_validate_command.c | 37 ++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 sources.mk create mode 100644 src/parser/parser_validate_command.c diff --git a/inc/parser.h b/inc/parser.h index beba406..a3d0483 100644 --- a/inc/parser.h +++ b/inc/parser.h @@ -16,9 +16,10 @@ # include "minishell.h" t_command *parser_alloc_command(t_minishell *msh, char *cmd); -void parser_create_command(t_minishell *msh, t_command *cmd, t_list **l_tkn); -char **parser_get_arguments(t_list *list, t_minishell *msh); t_list *parser_get_commands(t_minishell *msh); t_list *parser_get_input_redirects(t_list *list); +void parser_create_command(t_minishell *msh, t_command *cmd, t_list **l_tkn); +char **parser_get_arguments(t_list *list, t_minishell *msh); +int parser_validate_command(t_command *command); #endif diff --git a/sources.mk b/sources.mk new file mode 100644 index 0000000..e85d1ea --- /dev/null +++ b/sources.mk @@ -0,0 +1,24 @@ +VPATH = src:src/prompt:src/utils:src/lexer:src/token:src/environment:src/executor:src/parser:src/debug:src/expander:src/builtin:src/signal:src/redirect: +SOURCES = history_load.c history_write.c prompt.c print_banner.c check_malloc.c \ +free_command_list.c free_freelist.c free_lexer.c free_minishell.c \ +free_safe.c free_token.c free_token_list.c ft_lstclear_safe.c \ +ft_lstnew_safe.c ft_strdup_safe.c ft_strjoin_safe.c malloc_safe.c \ +error_msg.c free_minishell_line.c ft_substr_safe.c init_minishell.c \ +lexer_read_char.c lexer_new.c lexer_parse_input.c lexer_read_word.c \ +lexer_token_next.c token_new.c token_parse.c environment_add.c \ +environment_del.c environment_free.c environment_free_list.c \ +environment_get.c environment_get_arr.c environment_parse.c \ +environment_print.c executor_close_fds.c executor_absolute_path.c \ +executor_count_fds.c executor_create_pipes.c \ +executor_create_redirects.c executor_open_fds.c \ +executor_execute_pipeline.c executor_fork.c executor_child.c \ +parser_create_command.c parser_get_arguments.c parser_alloc_command.c \ +parser_get_commands.c parser_validate_command.c print_commands.c \ +print_freelist.c expander_is_character.c expander_expand_dollar.c \ +expander_allocate_memory.c expander_get_variable.c \ +expander_parse_variables.c expander_parse_string.c is_builtin.c \ +simple_builtins.c builtin_cd.c builtin_echo.c builtin_env.c \ +builtin_exit.c builtin_export.c builtin_pwd.c builtin_router.c \ +builtin_unset.c signal.c signal_init.c.c redirect_get_inputs.c \ +redirect_get_outputs.c redirect_new.c redirect_new_error.c \ +redirect_process_heredoc.c redirect_valid_type.c main.c \ diff --git a/src/parser/parser_get_commands.c b/src/parser/parser_get_commands.c index 68bbe5a..31ec57d 100644 --- a/src/parser/parser_get_commands.c +++ b/src/parser/parser_get_commands.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */ -/* Updated: 2025/02/27 13:38:56 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 16:07:54 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,20 +17,6 @@ static int is_command_token(t_token *token) return (token->type < 3 || redirect_token_type(token)); } -static int validate_redirects(t_list *lst) -{ - t_list *token; - - token = lst; - while (token) - { - if (((t_redirect *)token->content)->type == T_ERROR) - return (0); - token = token->next; - } - return (1); -} - t_list *parser_get_commands(t_minishell *msh) { t_list *command_list; @@ -47,7 +33,7 @@ t_list *parser_get_commands(t_minishell *msh) token = (t_token *) current->content; command = parser_alloc_command(msh, ft_strdup_safe(msh, token->value)); parser_create_command(msh, command, ¤t); - if (!validate_redirects(command->redirect_in) || !validate_redirects(command->redirect_out)) + if (! parser_validate_command(command)) break ; ft_lstadd_back(&command_list, ft_lstnew_safe(msh, command)); while (current && is_command_token((t_token *)current->content)) diff --git a/src/parser/parser_validate_command.c b/src/parser/parser_validate_command.c new file mode 100644 index 0000000..e15e38d --- /dev/null +++ b/src/parser/parser_validate_command.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_validate_command.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/27 16:06:33 by qmennen #+# #+# */ +/* Updated: 2025/02/27 16:08:49 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int validate_redirects(t_list *lst) +{ + t_list *token; + + token = lst; + while (token) + { + if (((t_redirect *)token->content)->type == T_ERROR) + return (0); + token = token->next; + } + return (1); +} + +int parser_validate_command(t_command *command) +{ + int r_in; + int r_out; + + r_in = validate_redirects(command->redirect_in); + r_out = validate_redirects(command->redirect_out); + return (r_in && r_out); +} From c2f062c6716bb84705e7da2741c4e78f2c753281 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:18:57 +0100 Subject: [PATCH 08/26] refactor: lexer --- src/lexer/lexer_token_next.c | 39 ++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/lexer/lexer_token_next.c b/src/lexer/lexer_token_next.c index d3c1181..12d571c 100644 --- a/src/lexer/lexer_token_next.c +++ b/src/lexer/lexer_token_next.c @@ -11,7 +11,6 @@ /* ************************************************************************** */ #include "minishell.h" -#include "typedef.h" static t_token_type get_word_type(char c) { @@ -23,6 +22,21 @@ static t_token_type get_word_type(char c) return (T_WORD); } +static t_token *process_word(t_minishell *msh, t_lexer *lexer, int pos) +{ + t_token_type word_type; + t_token *token; + char *word; + + word_type = get_word_type(lexer->current_char); + word = lexer_readword(msh, lexer); + if (!word) + return (token_new(msh, T_ERROR, &(lexer->current_char), pos)); + token = token_new(msh, word_type, word, pos); + free_safe(msh, (void **)&word); + return (token); +} + /** * @brief Retrieves the next token from the lexer. * @@ -45,32 +59,23 @@ static t_token_type get_word_type(char c) t_token *ft_token_next(t_minishell *msh, t_lexer *lexer) { t_token *token; - t_token_type word_type; - char *word; int current_pos; + char c; token = NULL; while (ft_isspace(lexer->current_char)) lexer_readchar(lexer); current_pos = lexer->pos; - if (lexer->current_char == '\0') + c = lexer->current_char; + if (c == '\0') token = token_new(msh, T_EOF, NULL, current_pos); - else if (lexer->current_char == '<' || lexer->current_char == '>' - || lexer->current_char == '|') + else if (c == '<' || c == '>' + || c == '|') token = token_parse(msh, lexer); else if (ft_isprint(lexer->current_char)) - { - word_type = get_word_type(lexer->current_char); - word = lexer_readword(msh, lexer); - if (!word) - return (token_new(msh, T_ERROR, &lexer->current_char, current_pos)); - token = token_new(msh, word_type, word, current_pos); - free_safe(msh, (void **)&word); - } + token = process_word(msh, lexer, current_pos); else - { token = token_new(msh, T_ERROR, NULL, current_pos); - printf("token->type: %d\n", token->type); - } + c = lexer->current_char; return (token); } From e5b30c87966581755fde97e529dc8d92dba03d5a Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:21:44 +0100 Subject: [PATCH 09/26] func explains itself really --- src/executor/executor_child.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index fde3237..2d05faa 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/12 21:25:10 by willem #+# #+# */ -/* Updated: 2025/02/27 13:50:26 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 16:20:00 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,7 +22,7 @@ static int is_dir(char *path) error_msg("is_dir", "path could not be read"); return (0); } - return S_ISDIR(path_stats.st_mode); + return (S_ISDIR(path_stats.st_mode)); } void executor_child(t_minishell *msh, t_command *command) @@ -35,7 +35,6 @@ void executor_child(t_minishell *msh, t_command *command) dup2(command->fd_out, 1); executor_close_fds(command->n_fds); path = executor_absolute_path(msh, command->args[0]); - // TODO: If the path variable points to a dir, it exists so the command won't fail (while ofc it should?) if (path == NULL || access(path, F_OK | X_OK) != 0) { ft_putstr_fd(RED BOLD, 2); From dd76e2c521e87fc3a71fef5b0ce6452494470e93 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:21:49 +0100 Subject: [PATCH 10/26] norminette --- src/builtin/builtin_export.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/builtin/builtin_export.c b/src/builtin/builtin_export.c index 8b1120b..74714c7 100644 --- a/src/builtin/builtin_export.c +++ b/src/builtin/builtin_export.c @@ -18,8 +18,8 @@ int builtin_export(t_minishell *msh, t_command *cmd) char **arr; int i; - i = 1; - while (cmd->args[i] != NULL) + i = 0; + while (cmd->args[++i] != NULL) { arr = ft_split(cmd->args[i], '='); if (arr[1] == NULL) @@ -37,7 +37,6 @@ int builtin_export(t_minishell *msh, t_command *cmd) else environment_add(msh, arr[0], arr[1]); ft_free_arr(arr); - i++; } return (SUCCESS); } From abdab3156ce29d2d7f3f9ed5aba42770a0d39109 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:46:34 +0100 Subject: [PATCH 11/26] error message instead of putstrfd --- src/executor/executor_child.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index 2d05faa..d80ae8d 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/12 21:25:10 by willem #+# #+# */ -/* Updated: 2025/02/27 16:20:00 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 16:46:21 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,9 +37,7 @@ void executor_child(t_minishell *msh, t_command *command) path = executor_absolute_path(msh, command->args[0]); if (path == NULL || access(path, F_OK | X_OK) != 0) { - ft_putstr_fd(RED BOLD, 2); - ft_putstr_fd(command->args[0], 2); - ft_putstr_fd(": " RESET "command not found\n", 2); + error_msg("minishell", "command not found"); return ; } if (is_dir(path)) From e366689f91d5543e430a267f7e18e97921c41b72 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:46:47 +0100 Subject: [PATCH 12/26] extract into helper for norminette --- src/executor/executor_absolute_path.c | 50 +++++++++++++++++---------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/executor/executor_absolute_path.c b/src/executor/executor_absolute_path.c index a193c46..a876e87 100644 --- a/src/executor/executor_absolute_path.c +++ b/src/executor/executor_absolute_path.c @@ -12,6 +12,34 @@ #include "minishell.h" +static char *resolve_relative(t_minishell *msh, char *cmd) +{ + char *executable; + + if (access(cmd, F_OK) == 0) + { + executable = ft_strdup_safe(msh, cmd); + if (!executable) + return (NULL); + return (executable); + } + return (NULL); +} + +static char *resolve_path(t_minishell *msh, char *path, char *cmd) +{ + char *executable; + + executable = malloc_safe(msh, ft_strlen(path) + ft_strlen(cmd) + 2); + ft_strlcpy(executable, path, ft_strlen(path) + 1); + ft_strlcat(executable, "/", ft_strlen(path) + 2); + ft_strlcat(executable, cmd, ft_strlen(path) + ft_strlen(cmd) + 2); + if (access(executable, F_OK) == 0) + return (executable); + free_safe(msh, (void **)&executable); + return (NULL); +} + char *executor_absolute_path(t_minishell *msh, char *cmd) { char **path; @@ -20,16 +48,7 @@ char *executor_absolute_path(t_minishell *msh, char *cmd) int i; if (cmd[0] == '/' || cmd[0] == '.') - { - if (access(cmd, F_OK) == 0) - { - executable = ft_strdup_safe(msh, cmd); - if (!executable) - return (NULL); - return (executable); - } - return (NULL); - } + return (resolve_relative(msh, cmd)); path_env = environment_get(msh, "PATH"); if (!path_env) return (NULL); @@ -37,16 +56,9 @@ char *executor_absolute_path(t_minishell *msh, char *cmd) i = 0; while (path[i] != NULL) { - executable = malloc_safe(msh, ft_strlen(path[i]) + ft_strlen(cmd) + 2); - ft_strlcpy(executable, path[i], ft_strlen(path[i]) + 1); - ft_strlcat(executable, "/", ft_strlen(path[i]) + 2); - ft_strlcat(executable, cmd, ft_strlen(path[i]) + ft_strlen(cmd) + 2); - if (access(executable, F_OK) == 0) - { - ft_free_arr(path); + executable = resolve_path(msh, path[i], cmd); + if (executable) return (executable); - } - free_safe(msh, (void **)&executable); i++; } return (ft_free_arr(path), NULL); From 9de806e64875842a1d4dc806a49e39b4574c6d45 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:46:54 +0100 Subject: [PATCH 13/26] limits --- inc/allowed.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inc/allowed.h b/inc/allowed.h index e562c19..7b2859f 100644 --- a/inc/allowed.h +++ b/inc/allowed.h @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 16:13:11 by whaffman #+# #+# */ -/* Updated: 2025/02/06 16:14:44 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 16:36:39 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,6 +26,7 @@ # include # include # include +# include # include # include From 74f29f1f482008cb516aa51555652d4d3dee5e84 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:51:26 +0100 Subject: [PATCH 14/26] Updated readme for reference on eveyrthing changed --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index deeb689..918b5f2 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,14 @@ A lot of amazing shell stuff - libreadline-dev - libncurses-dev +## Comments on work +- Checked if path is a directory and send appropriate message +- `executor_absolute_path` => extracted some code into helpers to make it norminette compliant +- `executor_child` => refactored putstr_fd into error_msg | checked if file on path is exectuable to show permission denied where applicable +- `lexer_token_next` => extracted code for norminette +- `parser` => **A LOT** of work in all files for norminette compliancy +- `expander_parse_string` => Fixed so that $HOME/test.txt returns the correct path and file + ## TODO - [x] Find absolute path for command input ('/', './', 'cmd') - [x]Add heredoc to tokenizer From ae010a33f6748a501d5e0bdf1f835d75c685a91c Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 16:51:59 +0100 Subject: [PATCH 15/26] sys stat already included in allowed.h --- src/executor/executor_child.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index d80ae8d..7f88381 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -6,12 +6,11 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/12 21:25:10 by willem #+# #+# */ -/* Updated: 2025/02/27 16:46:21 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 16:51:43 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -#include static int is_dir(char *path) { From 05b7ae3a6aedb8c9a6aeb143bca79aa24ceae21a Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 18:11:44 +0100 Subject: [PATCH 16/26] norminette made me do it --- inc/redirect.h | 54 ++++++++--------- src/redirect/redirect_get_inputs.c | 7 +-- src/redirect/redirect_get_outputs.c | 81 +++++++++++++------------- src/redirect/redirect_new.c | 89 +++++++++++++++-------------- src/redirect/redirect_new_error.c | 6 +- 5 files changed, 119 insertions(+), 118 deletions(-) diff --git a/inc/redirect.h b/inc/redirect.h index 2da3c94..3a1e568 100644 --- a/inc/redirect.h +++ b/inc/redirect.h @@ -1,27 +1,27 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* redirect.h :+: :+: */ -/* +:+ */ -/* By: Quinten +#+ */ -/* +#+ */ -/* Created: 2025/02/23 12:26:29 by Quinten #+# #+# */ -/* Updated: 2025/02/23 12:26:29 by Quinten ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#ifndef REDIRECT_H -# define REDIRECT_H -# include "minishell.h" - -t_redirect *redirect_new(t_minishell *msh, t_token_type type, char *value); -void redirect_new_error(t_minishell *msh, t_list **redirects); -void redirect_create(t_minishell *msh, t_list **tokens, t_list **redirects, t_token_type type); -t_list *redirect_get_inputs(t_minishell *msh, t_list *list); -t_list *redirect_get_outputs(t_minishell *msh, t_list *list); -int redirect_is_valid(t_list *lst, t_token *token, int mode); -int redirect_token_type(t_token *token); -int redirect_is_delimiter(t_token *token); -int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim); - -#endif +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/23 12:26:29 by Quinten #+# #+# */ +/* Updated: 2025/02/27 18:09:47 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef REDIRECT_H +# define REDIRECT_H +# include "minishell.h" + +t_redirect *redirect_new(t_minishell *msh, t_token_type type, char *value); +void redirect_new_error(t_minishell *msh, t_list **redirects, int flag); +int redirect_create(t_minishell *msh, t_list **tokens, t_list **redirects, t_token_type type); +t_list *redirect_get_inputs(t_minishell *msh, t_list *list); +t_list *redirect_get_outputs(t_minishell *msh, t_list *list); +int redirect_is_valid(t_list *lst, t_token *token, int mode); +int redirect_token_type(t_token *token); +int redirect_is_delimiter(t_token *token); +int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim); + +#endif diff --git a/src/redirect/redirect_get_inputs.c b/src/redirect/redirect_get_inputs.c index 2eaabd3..75d0a10 100644 --- a/src/redirect/redirect_get_inputs.c +++ b/src/redirect/redirect_get_inputs.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/23 12:29:05 by Quinten #+# #+# */ -/* Updated: 2025/02/26 17:38:59 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 18:09:15 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -39,10 +39,9 @@ t_list *redirect_get_inputs(t_minishell *msh, t_list *list) } check_heredoc(msh, current, token); flag = redirect_is_valid(current, token, F_OK | R_OK); - redirect_create(msh, ¤t, &redirects, token->type); + flag && (redirect_create(msh, ¤t, &redirects, token->type)); current = current->next; } - if (flag <= 0) - redirect_new_error(msh, &redirects); + redirect_new_error(msh, &redirects, flag); return (redirects); } diff --git a/src/redirect/redirect_get_outputs.c b/src/redirect/redirect_get_outputs.c index 19a4a4e..cc4e4f5 100644 --- a/src/redirect/redirect_get_outputs.c +++ b/src/redirect/redirect_get_outputs.c @@ -1,41 +1,40 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* redirect_get_outputs.c :+: :+: */ -/* +:+ */ -/* By: Quinten +#+ */ -/* +#+ */ -/* Created: 2025/02/23 12:37:24 by Quinten #+# #+# */ -/* Updated: 2025/02/23 12:37:24 by Quinten ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -t_list *redirect_get_outputs(t_minishell *msh, t_list *list) -{ - t_list *current; - t_list *redirects; - t_token *token; - int flag; - - flag = 1; - redirects = NULL; - current = list; - token = (t_token *)current->content; - while (current && flag && !redirect_is_delimiter(token)) - { - token = (t_token *)current->content; - if (token->type != T_REDIRECT_OUT && token->type != T_APPEND_OUT) - { - current = current->next; - continue ; - } - flag = redirect_is_valid(current, token, -1); - redirect_create(msh, ¤t, &redirects, token->type); - current = current->next; - } - if (flag <= 0) - redirect_new_error(msh, &redirects); - return (redirects); -} +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_get_outputs.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/23 12:37:24 by Quinten #+# #+# */ +/* Updated: 2025/02/27 18:10:57 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *redirect_get_outputs(t_minishell *msh, t_list *list) +{ + t_list *current; + t_list *redirects; + t_token *token; + int flag; + + flag = 1; + redirects = NULL; + current = list; + token = (t_token *)current->content; + while (current && !redirect_is_delimiter(token)) + { + token = (t_token *)current->content; + if (token->type != T_REDIRECT_OUT && token->type != T_APPEND_OUT) + { + current = current->next; + continue; + } + flag = redirect_is_valid(current, token, -1); + flag && (redirect_create(msh, ¤t, &redirects, token->type)); + current = current->next; + } + redirect_new_error(msh, &redirects, flag); + return (redirects); +} diff --git a/src/redirect/redirect_new.c b/src/redirect/redirect_new.c index ee11cf9..79c0951 100644 --- a/src/redirect/redirect_new.c +++ b/src/redirect/redirect_new.c @@ -1,44 +1,45 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* redirect_new.c :+: :+: */ -/* +:+ */ -/* By: Quinten +#+ */ -/* +#+ */ -/* Created: 2025/02/23 12:27:33 by Quinten #+# #+# */ -/* Updated: 2025/02/23 12:27:33 by Quinten ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -t_redirect *redirect_new(t_minishell *msh, t_token_type type, char *value) -{ - t_redirect *result; - - result = malloc_safe(msh, sizeof(t_redirect)); - result->type = type; - result->value = NULL; - if (value) - result->value = value; - return (result); -} - -void redirect_create(t_minishell *msh, t_list **tokens, t_list **redirects, -t_token_type type) -{ - t_list *new; - t_redirect *redir; - t_token *file_token; - char *file_name; - - file_token = (t_token *)((*tokens)->next->content); - file_name = NULL; - if (file_token) - file_name = ft_strdup_safe(msh, file_token->value); - redir = redirect_new(msh, type, file_name); - new = ft_lstnew_safe(msh, redir); - ft_lstadd_back(redirects, new); - if (tokens) - *tokens = (*tokens)->next; -} +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_new.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/23 12:27:33 by Quinten #+# #+# */ +/* Updated: 2025/02/27 18:11:25 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_redirect *redirect_new(t_minishell *msh, t_token_type type, char *value) +{ + t_redirect *result; + + result = malloc_safe(msh, sizeof(t_redirect)); + result->type = type; + result->value = NULL; + if (value) + result->value = value; + return (result); +} + +int redirect_create(t_minishell *msh, t_list **tokens, t_list **redirects, +t_token_type type) +{ + t_list *new; + t_redirect *redir; + t_token *file_token; + char *file_name; + + file_token = (t_token *)((*tokens)->next->content); + file_name = NULL; + if (file_token) + file_name = ft_strdup_safe(msh, file_token->value); + redir = redirect_new(msh, type, file_name); + new = ft_lstnew_safe(msh, redir); + ft_lstadd_back(redirects, new); + if (tokens) + *tokens = (*tokens)->next; + return (1); +} diff --git a/src/redirect/redirect_new_error.c b/src/redirect/redirect_new_error.c index 076e062..24cf75c 100644 --- a/src/redirect/redirect_new_error.c +++ b/src/redirect/redirect_new_error.c @@ -6,17 +6,19 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/26 17:37:12 by qmennen #+# #+# */ -/* Updated: 2025/02/26 17:44:49 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 18:07:25 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void redirect_new_error(t_minishell *msh, t_list **redirects) +void redirect_new_error(t_minishell *msh, t_list **redirects, int flag) { t_list *new; t_redirect *redir; + if (flag) + return ; redir = redirect_new(msh, T_ERROR, NULL); new = ft_lstnew_safe(msh, redir); ft_lstadd_back(redirects, new); From 0d555a5480ea48789d528a89c5fc21f3215d9707 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 18:12:13 +0100 Subject: [PATCH 17/26] norminette okay again --- src/redirect/redirect_get_outputs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/redirect/redirect_get_outputs.c b/src/redirect/redirect_get_outputs.c index cc4e4f5..0ad2f2d 100644 --- a/src/redirect/redirect_get_outputs.c +++ b/src/redirect/redirect_get_outputs.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/23 12:37:24 by Quinten #+# #+# */ -/* Updated: 2025/02/27 18:10:57 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 18:12:04 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,7 +29,7 @@ t_list *redirect_get_outputs(t_minishell *msh, t_list *list) if (token->type != T_REDIRECT_OUT && token->type != T_APPEND_OUT) { current = current->next; - continue; + continue ; } flag = redirect_is_valid(current, token, -1); flag && (redirect_create(msh, ¤t, &redirects, token->type)); From f33d88642d36a06b8b93f0934b205ee6a2cb8df1 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 18:12:53 +0100 Subject: [PATCH 18/26] details --- src/executor/executor_child.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index 7f88381..1e64f47 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/12 21:25:10 by willem #+# #+# */ -/* Updated: 2025/02/27 16:51:43 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 18:12:48 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -44,7 +44,7 @@ void executor_child(t_minishell *msh, t_command *command) ft_putstr_fd(RED BOLD, 2); ft_putstr_fd("minishell: ", 2); ft_putstr_fd(command->args[0], 2); - ft_putstr_fd(": " RESET "is a directory\n", 2); + ft_putstr_fd(": " RESET "Is a directory\n", 2); } execve(path, command->args, environment_get_arr(msh)); } From 15b7de994e4059bd07799964d84b8a20d833dcac Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 18:48:41 +0100 Subject: [PATCH 19/26] WAY better quote handling --- src/lexer/lexer_read_word.c | 51 ++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 78c50f4..9a601b5 100644 --- a/src/lexer/lexer_read_word.c +++ b/src/lexer/lexer_read_word.c @@ -1,17 +1,33 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* lexer_read_word.c :+: :+: */ -/* +:+ */ -/* By: qmennen +#+ */ -/* +#+ */ -/* Created: 2025/02/05 19:03:47 by qmennen #+# #+# */ -/* Updated: 2025/02/26 16:13:59 by whaffman ######## odam.nl */ +/* ::: :::::::: */ +/* lexer_read_word.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/05 19:03:47 by qmennen #+# #+# */ +/* Updated: 2025/02/27 18:47:33 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +static int match_quotes(t_minishell *msh, t_lexer *lexer) +{ + int i; + int qts; + + i = lexer->pos; + qts = 0; + while (lexer->input[i]) + { + if (lexer->input[i] == '\'' || lexer->input[i] == '"') + qts++; + i++; + } + return ((qts % 2) == 0); +} + static char *parse_quotes(t_minishell *msh, t_lexer *lexer) { int start; @@ -28,13 +44,7 @@ static char *parse_quotes(t_minishell *msh, t_lexer *lexer) len = lexer->pos - start; word = malloc_safe(msh, sizeof(char) * len + 1); ft_strlcpy(word, lexer->input + start, len + 1); - if (lexer->current_char == qc) - lexer_readchar(lexer); - else - { - free_safe(msh, (void **)&word); - return (NULL); - } + lexer_readchar(lexer); return (word); } @@ -43,18 +53,19 @@ char *lexer_readword(t_minishell *msh, t_lexer *lexer) int start; int len; char *word; + char c; start = lexer->pos; + if (!match_quotes(msh, lexer)) + return (NULL); if (lexer->current_char == '"' || lexer->current_char == '\'') - { return (parse_quotes(msh, lexer)); - } - while (ft_isprint(lexer->current_char) && lexer->current_char != '<' - && lexer->current_char != '>' && lexer->current_char != '|' - && lexer->current_char != '\0' && !ft_isspace(lexer->current_char) - && lexer->current_char != '"' && lexer->current_char != '\'') + c = lexer->current_char; + while (ft_isprint(c) && c != '<' &&c != '>' && c != '|' && c != '\0' + && !ft_isspace(lexer->current_char)) { lexer_readchar(lexer); + c = lexer->current_char; } len = lexer->pos - start; word = malloc_safe(msh, sizeof(char) * len + 1); From efd4d3f751fa6541cae4a53d018cbadc585af80d Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 18:49:04 +0100 Subject: [PATCH 20/26] extract token conversion funcs --- inc/tokenizer.h | 26 +++++++------- src/token/token_char_convert.c | 38 +++++++++++++++++++++ src/token/token_parse.c | 62 +++++----------------------------- src/token/token_type_convert.c | 32 ++++++++++++++++++ 4 files changed, 93 insertions(+), 65 deletions(-) create mode 100644 src/token/token_char_convert.c create mode 100644 src/token/token_type_convert.c diff --git a/inc/tokenizer.h b/inc/tokenizer.h index cfd415e..42ed9e1 100644 --- a/inc/tokenizer.h +++ b/inc/tokenizer.h @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* tokenizer.h :+: :+: */ -/* +:+ */ -/* By: qmennen +#+ */ -/* +#+ */ -/* Created: 2025/02/05 12:36:00 by whaffman #+# #+# */ -/* Updated: 2025/02/26 15:45:26 by whaffman ######## odam.nl */ +/* ::: :::::::: */ +/* tokenizer.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/05 12:36:00 by whaffman #+# #+# */ +/* Updated: 2025/02/27 18:27:33 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,10 +24,12 @@ t_list *ft_parse_input(t_minishell *msh); /** * Token */ -t_token *ft_token_next(t_minishell *msh, t_lexer *lexer); -t_token *token_new(t_minishell *msh, t_token_type type, char *c, int pos); -void ft_token_free(t_minishell *msh, t_token *token); -void ft_clear_tokenlist(t_minishell *msh, void *content); -t_token *token_parse(t_minishell *msh, t_lexer *lexer); +t_token *ft_token_next(t_minishell *msh, t_lexer *lexer); +t_token *token_new(t_minishell *msh, t_token_type type, char *c, int pos); +void ft_token_free(t_minishell *msh, t_token *token); +void ft_clear_tokenlist(t_minishell *msh, void *content); +t_token *token_parse(t_minishell *msh, t_lexer *lexer); +char *token_type_convert(t_token_type type); +t_token_type token_char_convert(char c, int is_double); #endif // TOKENIZER_H diff --git a/src/token/token_char_convert.c b/src/token/token_char_convert.c new file mode 100644 index 0000000..fbfd1f5 --- /dev/null +++ b/src/token/token_char_convert.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_char_convert.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/27 18:25:34 by qmennen #+# #+# */ +/* Updated: 2025/02/27 18:28:13 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +# include "minishell.h" + +t_token_type token_char_convert(char c, int is_double) +{ + if (c == '<') + { + if (is_double) + return (T_HEREDOC); + return (T_REDIRECT_IN); + } + else if (c == '>') + { + if (is_double) + return (T_APPEND_OUT); + return (T_REDIRECT_OUT); + } + else if (c == '&' && is_double) + return (T_AND); + else if (c == '|') + { + if (is_double) + return (T_OR); + return (T_PIPE); + } + return (T_ERROR); +} diff --git a/src/token/token_parse.c b/src/token/token_parse.c index f18eb52..5974479 100644 --- a/src/token/token_parse.c +++ b/src/token/token_parse.c @@ -1,61 +1,17 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* token_parse.c :+: :+: */ -/* +:+ */ -/* By: qmennen +#+ */ -/* +#+ */ -/* Created: 2025/02/05 19:10:17 by qmennen #+# #+# */ -/* Updated: 2025/02/26 16:15:19 by whaffman ######## odam.nl */ +/* ::: :::::::: */ +/* token_parse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/05 19:10:17 by qmennen #+# #+# */ +/* Updated: 2025/02/27 18:27:40 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -static t_token_type token_from_char(char c, int is_double) -{ - if (c == '<') - { - if (is_double) - return (T_HEREDOC); - return (T_REDIRECT_IN); - } - else if (c == '>') - { - if (is_double) - return (T_APPEND_OUT); - return (T_REDIRECT_OUT); - } - else if (c == '&' && is_double) - return (T_AND); - else if (c == '|') - { - if (is_double) - return (T_OR); - return (T_PIPE); - } - return (T_ERROR); -} - -static char *char_from_type(t_token_type type) -{ - if (type == T_HEREDOC) - return ("<<"); - else if (type == T_REDIRECT_IN) - return ("<"); - else if (type == T_APPEND_OUT) - return (">>"); - else if (type == T_REDIRECT_OUT) - return (">"); - else if (type == T_AND) - return ("&&"); - else if (type == T_OR) - return ("||"); - else if (type == T_PIPE) - return ("|"); - return (NULL); -} - t_token *token_parse(t_minishell *msh, t_lexer *lexer) { int is_double; @@ -65,8 +21,8 @@ t_token *token_parse(t_minishell *msh, t_lexer *lexer) c = lexer->current_char; is_double = lexer->input[lexer->pos + 1] == c; - type = token_from_char(c, is_double); - token = token_new(msh, type, char_from_type(type), lexer->pos); + type = token_char_convert(c, is_double); + token = token_new(msh, type, token_type_convert(type), lexer->pos); if (is_double) lexer_readchar(lexer); lexer_readchar(lexer); diff --git a/src/token/token_type_convert.c b/src/token/token_type_convert.c new file mode 100644 index 0000000..c42e681 --- /dev/null +++ b/src/token/token_type_convert.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_type_convert.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/27 18:25:34 by qmennen #+# #+# */ +/* Updated: 2025/02/27 18:26:40 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +# include "minishell.h" + +char *token_type_convert(t_token_type type) +{ + if (type == T_HEREDOC) + return ("<<"); + else if (type == T_REDIRECT_IN) + return ("<"); + else if (type == T_APPEND_OUT) + return (">>"); + else if (type == T_REDIRECT_OUT) + return (">"); + else if (type == T_AND) + return ("&&"); + else if (type == T_OR) + return ("||"); + else if (type == T_PIPE) + return ("|"); + return (NULL); +} From 547dacc0ba445dac7c95d711e4dc4443d0794879 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 18:59:00 +0100 Subject: [PATCH 21/26] small fix --- src/parser/parser_get_arguments.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/parser/parser_get_arguments.c b/src/parser/parser_get_arguments.c index b0f2033..1ce6230 100644 --- a/src/parser/parser_get_arguments.c +++ b/src/parser/parser_get_arguments.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/11 16:20:09 by qmennen #+# #+# */ -/* Updated: 2025/02/26 18:35:27 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 18:58:48 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -34,13 +34,23 @@ static int count_cmds(t_list *list) static int parser_should_expand(t_list *value) { t_token *token; + int i; token = (t_token *)value->content; if (!token) return (0); - return ((token->type == T_DQWORD && ft_strchr(token->value, '$')) - || (token->type == T_WORD - && token->value[0] == '$' + i = 0; + if (token->type == T_DQWORD) + { + while (token->value[i]) + { + if (token->value[i] == '$' && !expander_character_valid(token->value[i + 1])) + return (0); + i++; + } + return (1); + } + return ((token->type == T_WORD && token->value[0] == '$' && token->value[1])); } From 48256b2c814713763502152873bb7dbe00f0905d Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 19:04:02 +0100 Subject: [PATCH 22/26] extracting more --- inc/tokenizer.h | 3 ++- src/lexer/lexer_parse_quotes.c | 33 +++++++++++++++++++++++++++++++++ src/lexer/lexer_read_word.c | 24 ++---------------------- 3 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 src/lexer/lexer_parse_quotes.c diff --git a/inc/tokenizer.h b/inc/tokenizer.h index 42ed9e1..bab22bf 100644 --- a/inc/tokenizer.h +++ b/inc/tokenizer.h @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/05 12:36:00 by whaffman #+# #+# */ -/* Updated: 2025/02/27 18:27:33 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 19:03:09 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,7 @@ void ft_lexer_free(t_minishell *msh, t_lexer *lexer); void lexer_readchar(t_lexer *lexer); char *lexer_readword(t_minishell *msh, t_lexer *lexer); t_list *ft_parse_input(t_minishell *msh); +char *lexer_parse_quotes(t_minishell *msh, t_lexer *lexer); /** * Token */ diff --git a/src/lexer/lexer_parse_quotes.c b/src/lexer/lexer_parse_quotes.c new file mode 100644 index 0000000..0edf290 --- /dev/null +++ b/src/lexer/lexer_parse_quotes.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_parse_quotes.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/27 19:02:37 by qmennen #+# #+# */ +/* Updated: 2025/02/27 19:02:54 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *lexer_parse_quotes(t_minishell *msh, t_lexer *lexer) +{ + int start; + int len; + char qc; + char *word; + + qc = lexer->current_char; + word = NULL; + lexer_readchar(lexer); + start = lexer->pos; + while (lexer->current_char != '\0' && lexer->current_char != qc) + lexer_readchar(lexer); + len = lexer->pos - start; + word = malloc_safe(msh, sizeof(char) * len + 1); + ft_strlcpy(word, lexer->input + start, len + 1); + lexer_readchar(lexer); + return (word); +} diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 9a601b5..8c0b996 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/27 18:47:33 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 19:03:15 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,26 +28,6 @@ static int match_quotes(t_minishell *msh, t_lexer *lexer) return ((qts % 2) == 0); } -static char *parse_quotes(t_minishell *msh, t_lexer *lexer) -{ - int start; - int len; - char qc; - char *word; - - qc = lexer->current_char; - word = NULL; - lexer_readchar(lexer); - start = lexer->pos; - while (lexer->current_char != '\0' && lexer->current_char != qc) - lexer_readchar(lexer); - len = lexer->pos - start; - word = malloc_safe(msh, sizeof(char) * len + 1); - ft_strlcpy(word, lexer->input + start, len + 1); - lexer_readchar(lexer); - return (word); -} - char *lexer_readword(t_minishell *msh, t_lexer *lexer) { int start; @@ -59,7 +39,7 @@ char *lexer_readword(t_minishell *msh, t_lexer *lexer) if (!match_quotes(msh, lexer)) return (NULL); if (lexer->current_char == '"' || lexer->current_char == '\'') - return (parse_quotes(msh, lexer)); + return (lexer_parse_quotes(msh, lexer)); c = lexer->current_char; while (ft_isprint(c) && c != '<' &&c != '>' && c != '|' && c != '\0' && !ft_isspace(lexer->current_char)) From e07d4b4d79a91b6a3c8075ab50476e3af0918a27 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 19:21:05 +0100 Subject: [PATCH 23/26] last rework for the day, hello""world now read helloworld correctly --- src/lexer/lexer_read_word.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 8c0b996..7eb8a2a 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/27 19:03:15 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 19:20:22 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,6 +28,22 @@ static int match_quotes(t_minishell *msh, t_lexer *lexer) return ((qts % 2) == 0); } +static int calculate_word_len(t_minishell *msh, t_lexer *lexer) +{ + int i; + int len; + + len = 1; + i = lexer->pos; + while (ft_isprint(lexer->input[i]) && lexer->input[i] != '<' && lexer->input[i]!= '>' && lexer->input[i] != '|' && lexer->input[i] != '\0' && !ft_isspace(lexer->input[i])) + { + if(lexer->input[i] != '\'' && lexer->input[i] != '"') + len++; + i++; + } + return (len); +} + char *lexer_readword(t_minishell *msh, t_lexer *lexer) { int start; @@ -40,15 +56,17 @@ char *lexer_readword(t_minishell *msh, t_lexer *lexer) return (NULL); if (lexer->current_char == '"' || lexer->current_char == '\'') return (lexer_parse_quotes(msh, lexer)); + len = calculate_word_len(msh, lexer); + word = malloc_safe(msh, sizeof(char) * len); c = lexer->current_char; - while (ft_isprint(c) && c != '<' &&c != '>' && c != '|' && c != '\0' - && !ft_isspace(lexer->current_char)) + len = 0; + while (ft_isprint(c) && c != '<' && c != '>' && c != '|' && c != '\0' && !ft_isspace(c)) { + if(c != '\'' && c != '"') + word[len++] = lexer->current_char; lexer_readchar(lexer); c = lexer->current_char; } - len = lexer->pos - start; - word = malloc_safe(msh, sizeof(char) * len + 1); - ft_strlcpy(word, lexer->input + start, len + 1); + word[len] = 0; return (word); } From 2d9b35d12784292e56e30a332bcc80b877f04092 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 19:22:23 +0100 Subject: [PATCH 24/26] ofc last minute bug --- src/lexer/lexer_read_word.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 7eb8a2a..23404fc 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/27 19:20:22 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 19:22:09 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,17 +15,21 @@ static int match_quotes(t_minishell *msh, t_lexer *lexer) { int i; - int qts; + int d_qts; + int s_qts; i = lexer->pos; - qts = 0; + d_qts = 0; + s_qts = 0; while (lexer->input[i]) { - if (lexer->input[i] == '\'' || lexer->input[i] == '"') - qts++; + if (lexer->input[i] == '\'') + s_qts++; + if (lexer->input[i] == '\'') + d_qts++; i++; } - return ((qts % 2) == 0); + return ((s_qts % 2) == 0 && (d_qts % 2) == 0); } static int calculate_word_len(t_minishell *msh, t_lexer *lexer) From d13fb174c5b11afa59db6f5348bc33572f316088 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 19:29:49 +0100 Subject: [PATCH 25/26] quote parsing, love it --- src/lexer/lexer_parse_quotes.c | 10 ++++++++-- src/lexer/lexer_read_word.c | 21 ++++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/lexer/lexer_parse_quotes.c b/src/lexer/lexer_parse_quotes.c index 0edf290..09010f9 100644 --- a/src/lexer/lexer_parse_quotes.c +++ b/src/lexer/lexer_parse_quotes.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/27 19:02:37 by qmennen #+# #+# */ -/* Updated: 2025/02/27 19:02:54 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 19:26:35 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,6 +28,12 @@ char *lexer_parse_quotes(t_minishell *msh, t_lexer *lexer) len = lexer->pos - start; word = malloc_safe(msh, sizeof(char) * len + 1); ft_strlcpy(word, lexer->input + start, len + 1); - lexer_readchar(lexer); + if (lexer->current_char == qc) + lexer_readchar(lexer); + else + { + free_safe(msh, (void **)&word); + return (NULL); + } return (word); } diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 23404fc..45d234f 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/27 19:22:09 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 19:28:50 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,20 +14,23 @@ static int match_quotes(t_minishell *msh, t_lexer *lexer) { - int i; - int d_qts; - int s_qts; + char c; + int i; + int d_qts; + int s_qts; i = lexer->pos; + c = lexer->input[i]; d_qts = 0; s_qts = 0; - while (lexer->input[i]) + while (ft_isprint(c) && c != '<' && c != '>' && c != '|' && c != '\0' && !ft_isspace(c)) { if (lexer->input[i] == '\'') s_qts++; if (lexer->input[i] == '\'') d_qts++; i++; + c = lexer->input[i]; } return ((s_qts % 2) == 0 && (d_qts % 2) == 0); } @@ -56,10 +59,14 @@ char *lexer_readword(t_minishell *msh, t_lexer *lexer) char c; start = lexer->pos; + + if (lexer->current_char == '"' || lexer->current_char == '\'') + { + return (lexer_parse_quotes(msh, lexer)); + + } if (!match_quotes(msh, lexer)) return (NULL); - if (lexer->current_char == '"' || lexer->current_char == '\'') - return (lexer_parse_quotes(msh, lexer)); len = calculate_word_len(msh, lexer); word = malloc_safe(msh, sizeof(char) * len); c = lexer->current_char; From 20e71efa5f7749c536f791a1408cab2786dc9af8 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Thu, 27 Feb 2025 19:30:16 +0100 Subject: [PATCH 26/26] quick todo --- src/lexer/lexer_read_word.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 45d234f..bb12c8d 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/27 19:28:50 by qmennen ### ########.fr */ +/* Updated: 2025/02/27 19:30:09 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,6 +23,7 @@ static int match_quotes(t_minishell *msh, t_lexer *lexer) c = lexer->input[i]; d_qts = 0; s_qts = 0; + //TODO: Normalize this validation. Happens a lot while (ft_isprint(c) && c != '<' && c != '>' && c != '|' && c != '\0' && !ft_isspace(c)) { if (lexer->input[i] == '\'')