diff --git a/inc/parser.h b/inc/parser.h index cfcc5c5..7a67d31 100644 --- a/inc/parser.h +++ b/inc/parser.h @@ -24,5 +24,7 @@ void parser_create_command(t_minishell *msh, char **parser_get_arguments(t_list *list, t_minishell *msh); int parser_validate_command(t_command *command); int parser_count_arguments(t_list *list); +char *parser_concatenate(t_minishell *msh, char *str1, char *str2); +char *parser_process_token(t_minishell *msh, t_list *prev, t_list *t_head); #endif diff --git a/inc/token.h b/inc/token.h index cbdbf41..51c7a15 100644 --- a/inc/token.h +++ b/inc/token.h @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/05 13:11:41 by qmennen #+# #+# */ -/* Updated: 2025/03/05 13:11:58 by qmennen ### ########.fr */ +/* Updated: 2025/03/05 20:54:45 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,5 +16,6 @@ # include "minishell.h" t_token *token_from_list(t_list *list); +t_list *token_list_index(t_list *tokens, int index); #endif diff --git a/src/builtin/builtin_router.c b/src/builtin/builtin_router.c index e6feb99..a63769a 100644 --- a/src/builtin/builtin_router.c +++ b/src/builtin/builtin_router.c @@ -27,5 +27,4 @@ int builtin_router(t_minishell *msh, t_command *cmd) if (is_builtin(cmd->args[0]) < 0) return (FALSE); return (builtin_fn[is_builtin(cmd->args[0])](msh, cmd)); - } diff --git a/src/environment/environment_print.c b/src/environment/environment_print.c index 5fcdfb7..07966a8 100644 --- a/src/environment/environment_print.c +++ b/src/environment/environment_print.c @@ -18,7 +18,7 @@ void environment_print(t_minishell *msh, int export) t_environment *env; env_list = msh->environment; - while(env_list != NULL) + while (env_list != NULL) { env = (t_environment *)env_list->content; if (export) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index e7948bd..6b83d58 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -24,7 +24,7 @@ static int is_dir(char *path) return (S_ISDIR(path_stats.st_mode)); } -static int validate_executable_path(char *path) +static int validate_executable_path(char *path) { if (access(path, X_OK) < 0) { diff --git a/src/executor/executor_execute_pipeline.c b/src/executor/executor_execute_pipeline.c index ef2bce3..6f8925a 100644 --- a/src/executor/executor_execute_pipeline.c +++ b/src/executor/executor_execute_pipeline.c @@ -34,7 +34,7 @@ static int execute_builtin(t_minishell *msh, t_command *cmd) return (exit_status); } -static int executor_execute_command(t_minishell *msh, t_command *cmd) +static int executor_execute_command(t_minishell *msh, t_command *cmd) { if (is_builtin(cmd->args[0]) >= 0) msh->exit_status = execute_builtin(msh, cmd); diff --git a/src/lexer/lexer_parse_input.c b/src/lexer/lexer_parse_input.c index 375be79..5d05f86 100644 --- a/src/lexer/lexer_parse_input.c +++ b/src/lexer/lexer_parse_input.c @@ -41,6 +41,5 @@ t_list *ft_parse_input(t_minishell *msh) break ; } } - // ft_token_free(msh, token); return (list); } diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 801961b..d60e43b 100644 --- a/src/lexer/lexer_read_word.c +++ b/src/lexer/lexer_read_word.c @@ -30,7 +30,6 @@ static int calculate_word_len(t_minishell *msh, t_lexer *lexer) i = lexer->pos; while (is_word_char(lexer->input[i])) { - len++; i++; } @@ -67,8 +66,6 @@ char *lexer_readword(t_minishell *msh, t_lexer *lexer) qts = (c == '"' || c == '\''); if (qts) return (lexer_parse_quotes(msh, lexer)); - // if (!match_quotes(msh, lexer, qts)) - // return (NULL); len = calculate_word_len(msh, lexer); word = read_word(msh, lexer, len); return (word); diff --git a/src/lexer/lexer_token_next.c b/src/lexer/lexer_token_next.c index e8d7e34..52deb97 100644 --- a/src/lexer/lexer_token_next.c +++ b/src/lexer/lexer_token_next.c @@ -22,7 +22,7 @@ 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) +static t_token *process_word(t_minishell *msh, t_lexer *lexer, int pos) { t_token_type word_type; t_token *token; diff --git a/src/parser/parser_alloc_command.c b/src/parser/parser_alloc_command.c index cd9aee4..ecd7e1c 100644 --- a/src/parser/parser_alloc_command.c +++ b/src/parser/parser_alloc_command.c @@ -22,7 +22,6 @@ t_command *parser_alloc_command(t_minishell *msh) command->fd_out = 1; command->redirect_in = NULL; command->redirect_out = NULL; - // command->environment = NULL; command->n_fds = 0; return (command); } diff --git a/src/parser/parser_concatenate.c b/src/parser/parser_concatenate.c new file mode 100644 index 0000000..9eaa80b --- /dev/null +++ b/src/parser/parser_concatenate.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_concatenate.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/05 20:14:54 by qmennen #+# #+# */ +/* Updated: 2025/03/05 20:18:30 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *parser_concatenate(t_minishell *msh, char *str1, char *str2) +{ + char *cat; + + cat = malloc_safe(msh, ft_strlen(str1) + ft_strlen(str2) + 1); + ft_strlcpy(cat, str1, ft_strlen(str1) + 1); + ft_strlcat(cat, str2, ft_strlen(str2) + ft_strlen(str1) + 1); + return (cat); +} diff --git a/src/parser/parser_count_arguments.c b/src/parser/parser_count_arguments.c index da72901..187af50 100644 --- a/src/parser/parser_count_arguments.c +++ b/src/parser/parser_count_arguments.c @@ -25,6 +25,8 @@ int parser_count_arguments(t_list *list) while (current) { token = ((t_token *)current->content); + if (redirect_is_delimiter(token)) + break ; if (token->type < 3 && (!prev || ((t_token *)prev->content)->type < 3)) cmds++; prev = current; @@ -32,5 +34,3 @@ int parser_count_arguments(t_list *list) } return (cmds); } - - diff --git a/src/parser/parser_get_arguments.c b/src/parser/parser_get_arguments.c index 4d47b6b..bfa7ff9 100644 --- a/src/parser/parser_get_arguments.c +++ b/src/parser/parser_get_arguments.c @@ -11,93 +11,46 @@ /* ************************************************************************** */ #include "minishell.h" +#include "typedef.h" -static int parser_should_expand(t_list *value) +static int parser_should_concact(t_minishell *msh, int argi, t_list *cur, t_list *prev) { - t_token *token; - int i; + t_token *c_tkn; + t_token *p_tkn; + char lexer_char; - token = (t_token *)value->content; - if (!token) + if (argi < 1) return (0); - i = 0; - if (token->type == T_DQWORD || token->type == T_WORD) - { - while (token->value[i]) - { - if (token->value[i] == '$' - && (expander_character_valid(token->value[i + 1]) || token->value[i + 1] == '?')) - return (1); - i++; - } + p_tkn = token_from_list(prev); + c_tkn = token_from_list(cur); + lexer_char = 0; + if (!p_tkn || !c_tkn || c_tkn->position <= 0) return (0); - } - return (0); -} - -static int parser_should_concact(t_minishell *msh, int argi, t_list *prev) -{ - t_token *prev_tkn; - char c; - - prev_tkn = token_from_list(prev); - c = 0; - if (!prev_tkn || argi < 1) - return (0); - if (prev_tkn->position > 0) - c = msh->lexer->input[prev_tkn->position - 1]; - return (ft_strcmp(prev_tkn->value, "") == 0 && c && !ft_isspace(c)); -} - -static char *parser_process_token(t_minishell *msh, char **args, t_list *prev, t_list *t_head) -{ - char *str; - t_token *token; - - if (!t_head) - return (NULL); - token = (t_token *)t_head->content; - str = NULL; - if (ft_strcmp(token->value, "") == 0) - return (NULL); - if (parser_should_expand(t_head)) - str = expander_parse_string(token->value, msh); - if (!str) - str = ft_strdup_safe(msh, token->value); - if (str && token->type == T_WORD && ft_strchr(str, '"')) - str = parser_sanitize_string(msh, str, '"'); - else if (str && token->type == T_WORD && ft_strchr(str, '\'')) - str = parser_sanitize_string(msh, str, '\''); - return (str); + lexer_char = msh->lexer->input[c_tkn->position - 1]; + // Determine exact separation position + return (c_tkn->type < 3 && p_tkn->type < 3 && !ft_isspace(lexer_char)); } char **parser_get_arguments(t_list *list, t_minishell *msh) { t_list *current; t_list *prev; + char *str; char **args; int argc; int i; - char *str; - char *cat; argc = parser_count_arguments(list); args = malloc_safe(msh, (argc + 1) * sizeof(char *)); current = list; i = 0; - prev = NULL; while (argc > 0 && current) { - if (token_from_list(current)->type < 3 && (!prev || token_from_list(prev)->type < 3)) + if (token_from_list(current)->type < 3) { - str = parser_process_token(msh, args, prev, current); - if (parser_should_concact(msh, i, prev)) - { - cat = malloc_safe(msh, ft_strlen(str) + ft_strlen(args[i - 1]) + 1); - ft_strlcpy(cat, args[i - 1], ft_strlen(args[i - 1]) + 1); - ft_strlcat(cat, str, ft_strlen(str) + ft_strlen(args[i - 1]) + 1); - args[i - 1] = cat; - } + str = parser_process_token(msh, token_list_index(list, i - 1), current); + if (parser_should_concact(msh, i, current, prev)) + args[i - 1] = parser_concatenate(msh, args[i - 1], str); else if (str) args[i++] = str; argc--; diff --git a/src/parser/parser_process_token.c b/src/parser/parser_process_token.c new file mode 100644 index 0000000..4c5a6c8 --- /dev/null +++ b/src/parser/parser_process_token.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_process_token.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/05 21:12:15 by qmennen #+# #+# */ +/* Updated: 2025/03/05 21:42:44 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int parser_should_expand(t_list *value) +{ + t_token *token; + char *t_val; + int i; + + token = (t_token *)value->content; + if (!token) + return (0); + i = 0; + if (token->type != T_DQWORD && token->type != T_WORD) + return (0); + while (token->value[i]) + { + t_val = token->value; + if (t_val[i] == '$' && expander_character_valid(t_val[i + 1])) + return (1); + else if (t_val[i] == '$' && t_val[i + 1] == '?') + return (1); + i++; + } + return (0); +} + +//TODO: Make an exception for this `echo hey""you "" test`. here echo actually interprets "" as an extra space. Just check if its empty and surrounded by spaces or sth. Can't be asked rn +char *parser_process_token(t_minishell *msh, t_list *prev, t_list *t_head) +{ + char *str; + t_token *token; + t_token *p_token; + + if (!t_head) + return (NULL); + token = (t_token *)t_head->content; + p_token = (t_token *)prev->content; + str = NULL; + if (ft_strcmp(token->value, "") == 0) + return (NULL); + if (parser_should_expand(t_head)) + str = expander_parse_string(token->value, msh); + if (!str) + str = ft_strdup_safe(msh, token->value); + if (str && token->type == T_WORD && ft_strchr(str, '"')) + str = parser_sanitize_string(msh, str, '"'); + else if (str && token->type == T_WORD && ft_strchr(str, '\'')) + str = parser_sanitize_string(msh, str, '\''); + return (str); +} diff --git a/src/prompt/history_write.c b/src/prompt/history_write.c index 4c9b1d9..8cc3e95 100644 --- a/src/prompt/history_write.c +++ b/src/prompt/history_write.c @@ -20,7 +20,7 @@ void history_write(char *line) fd = open(".minishell_history", O_WRONLY | O_APPEND | O_CREAT, 0644); if (fd < 0) return ; - // if (*line) - // ft_putendl_fd(line, fd); + if (*line) + ft_putendl_fd(line, fd); close(fd); } diff --git a/src/token/token_list_index.c b/src/token/token_list_index.c new file mode 100644 index 0000000..663b36f --- /dev/null +++ b/src/token/token_list_index.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_list_index.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/05 20:53:34 by qmennen #+# #+# */ +/* Updated: 2025/03/05 21:00:01 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *token_list_index(t_list *tokens, int index) +{ + t_list *current; + int i; + + i = 0; + current = tokens; + while ((i++) < index && current) + current = current->next; + return (current); +} diff --git a/src/utils/malloc_safe.c b/src/utils/malloc_safe.c index b4d423a..32dd747 100644 --- a/src/utils/malloc_safe.c +++ b/src/utils/malloc_safe.c @@ -15,8 +15,9 @@ void *malloc_safe(t_minishell *msh, size_t size) { void *ptr; + if (size == 0) - return (NULL); + return (NULL); ptr = malloc(size); check_malloc(msh, ptr); return (ptr);