Merge remote-tracking branch 'origin/quinten' into willem

This commit is contained in:
whaffman 2025-03-05 12:52:22 +01:00
commit 32f416694c
9 changed files with 163 additions and 88 deletions

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ */ /* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */ /* +#+ */
/* Created: 2025/02/11 14:03:03 by qmennen #+# #+# */ /* Created: 2025/02/11 14:03:03 by qmennen #+# #+# */
/* Updated: 2025/03/04 18:19:23 by whaffman ######## odam.nl */ /* Updated: 2025/03/05 12:50:03 by whaffman ######## odam.nl */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -15,6 +15,7 @@
# include "minishell.h" # include "minishell.h"
char *parser_sanitize_string(t_minishell *msh, char *str, char c);
t_command *parser_alloc_command(t_minishell *msh); t_command *parser_alloc_command(t_minishell *msh);
t_list *parser_get_commands(t_minishell *msh); t_list *parser_get_commands(t_minishell *msh);
t_list *parser_get_input_redirects(t_list *list); t_list *parser_get_input_redirects(t_list *list);

View File

@ -6,7 +6,7 @@
/* By: marvin <marvin@student.42.fr> +#+ */ /* By: marvin <marvin@student.42.fr> +#+ */
/* +#+ */ /* +#+ */
/* Created: 2025/02/18 20:06:37 by qmennen #+# #+# */ /* Created: 2025/02/18 20:06:37 by qmennen #+# #+# */
/* Updated: 2025/03/04 18:40:35 by whaffman ######## odam.nl */ /* Updated: 2025/03/05 12:52:19 by whaffman ######## odam.nl */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@ -16,15 +16,11 @@ static char *resolve_relative(t_minishell *msh, char *cmd)
{ {
char *executable; char *executable;
if (access(cmd, F_OK) == 0)
{
executable = ft_strdup_safe(msh, cmd); executable = ft_strdup_safe(msh, cmd);
if (!executable) if (!executable)
return (NULL); return (NULL);
return (executable); return (executable);
} }
return (NULL);
}
static char *resolve_path(t_minishell *msh, char *path, char *cmd) static char *resolve_path(t_minishell *msh, char *path, char *cmd)
{ {

View File

@ -24,6 +24,21 @@ static int is_dir(char *path)
return (S_ISDIR(path_stats.st_mode)); return (S_ISDIR(path_stats.st_mode));
} }
static int validate_executable_path(char *path)
{
if (access(path, X_OK) < 0)
{
error_msg(path, "Permission denied");
return (0);
}
if (is_dir(path))
{
error_msg(path, "Is a directory");
return (0);
}
return (1);
}
void executor_child(t_minishell *msh, t_command *command) void executor_child(t_minishell *msh, t_command *command)
{ {
char *path; char *path;
@ -34,18 +49,13 @@ void executor_child(t_minishell *msh, t_command *command)
dup2(command->fd_out, 1); dup2(command->fd_out, 1);
executor_close_fds(command->n_fds); executor_close_fds(command->n_fds);
path = executor_absolute_path(msh, command->args[0]); path = executor_absolute_path(msh, command->args[0]);
if (path == NULL || access(path, F_OK | X_OK) != 0) if (path == NULL)
{ {
errno = 0; errno = 0;
error_msg("minishell", "command not found"); error_msg("minishell", "command not found");
return ; return ;
} }
if (is_dir(path)) else if (! validate_executable_path(path))
{ return ;
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)); execve(path, command->args, environment_get_arr(msh));
} }

View File

@ -35,10 +35,12 @@ t_list *ft_parse_input(t_minishell *msh)
while (TRUE) while (TRUE)
{ {
token = ft_token_next(msh, lexer); token = ft_token_next(msh, lexer);
if (token->type == T_EOF || token->type == T_ERROR)
break ;
ft_lstadd_back(&list, ft_lstnew_safe(msh, token)); ft_lstadd_back(&list, ft_lstnew_safe(msh, token));
if (token->type == T_EOF || token->type == T_ERROR)
{
break ;
} }
ft_token_free(msh, token); }
// ft_token_free(msh, token);
return (list); return (list);
} }

View File

@ -14,35 +14,11 @@
static int is_word_char(char c) static int is_word_char(char c)
{ {
return (ft_isprint(c) if (c == '<' || c == '>' || c == '|' || c == '\0')
&& c != '<' return (0);
&& c != '>' else if (ft_isspace(c))
&& c != '|' return (0);
&& c != '\0' return (ft_isprint(c));
&& !ft_isspace(c));
}
static int match_quotes(t_minishell *msh, t_lexer *lexer)
{
char c;
int i;
int d_qts;
int s_qts;
i = lexer->pos;
c = lexer->input[i];
d_qts = 0;
s_qts = 0;
while (is_word_char(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);
} }
static int calculate_word_len(t_minishell *msh, t_lexer *lexer) static int calculate_word_len(t_minishell *msh, t_lexer *lexer)
@ -54,36 +30,46 @@ static int calculate_word_len(t_minishell *msh, t_lexer *lexer)
i = lexer->pos; i = lexer->pos;
while (is_word_char(lexer->input[i])) while (is_word_char(lexer->input[i]))
{ {
if (lexer->input[i] != '\'' && lexer->input[i] != '"')
len++; len++;
i++; i++;
} }
return (len); return (len);
} }
char *lexer_readword(t_minishell *msh, t_lexer *lexer) char *read_word(t_minishell *msh, t_lexer *lexer, int len)
{ {
int len;
char *word;
char c; char c;
char *dest;
int i;
if (lexer->current_char == '"' || lexer->current_char == '\'') dest = malloc_safe(msh, sizeof(char) * len);
{
return (lexer_parse_quotes(msh, lexer));
}
if (!match_quotes(msh, lexer))
return (NULL);
len = calculate_word_len(msh, lexer);
word = malloc_safe(msh, sizeof(char) * len);
c = lexer->current_char; c = lexer->current_char;
len = 0; i = 0;
while (is_word_char(c)) while (is_word_char(c))
{ {
if (c != '\'' && c != '"') dest[i++] = lexer->current_char;
word[len++] = lexer->current_char;
lexer_readchar(lexer); lexer_readchar(lexer);
c = lexer->current_char; c = lexer->current_char;
} }
word[len] = 0; dest[i] = 0;
return (dest);
}
char *lexer_readword(t_minishell *msh, t_lexer *lexer)
{
int len;
int qts;
char *word;
char c;
c = lexer->current_char;
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); return (word);
} }

View File

@ -31,7 +31,9 @@ static t_token *process_word(t_minishell *msh, t_lexer *lexer, int pos)
word_type = get_word_type(lexer->current_char); word_type = get_word_type(lexer->current_char);
word = lexer_readword(msh, lexer); word = lexer_readword(msh, lexer);
if (!word) if (!word)
{
return (token_new(msh, T_ERROR, &(lexer->current_char), pos)); return (token_new(msh, T_ERROR, &(lexer->current_char), pos));
}
token = token_new(msh, word_type, word, pos); token = token_new(msh, word_type, word, pos);
free_safe(msh, (void **)&word); free_safe(msh, (void **)&word);
return (token); return (token);

View File

@ -10,22 +10,27 @@
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "libft.h"
#include "minishell.h" #include "minishell.h"
#include "parser.h"
#include "utils.h"
static int count_cmds(t_list *list) static int count_cmds(t_list *list)
{ {
int cmds; int cmds;
t_list *current; t_list *current;
t_list *prev;
t_token *token; t_token *token;
cmds = 0; cmds = 0;
current = list; current = list;
prev = NULL;
while (current) while (current)
{ {
token = ((t_token *)current->content); token = ((t_token *)current->content);
if (token->type >= 3) if (token->type < 3 && (!prev || ((t_token *)prev->content)->type < 3))
break ;
cmds++; cmds++;
prev = current;
current = current->next; current = current->next;
} }
return (cmds); return (cmds);
@ -40,40 +45,74 @@ static int parser_should_expand(t_list *value)
if (!token) if (!token)
return (0); return (0);
i = 0; i = 0;
if (token->type == T_DQWORD) if (token->type == T_DQWORD || token->type == T_WORD)
{ {
while (token->value[i]) while (token->value[i])
{ {
if (token->value[i] == '$' if (token->value[i] == '$'
&& !expander_character_valid(token->value[i + 1])) && (expander_character_valid(token->value[i + 1]) || token->value[i + 1] == '?'))
return (0); return (1);
i++; i++;
} }
return (1); return (0);
} }
return ((token->type == T_WORD && token->value[0] == '$' return (0);
&& token->value[1])); }
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);
} }
char **parser_get_arguments(t_list *list, t_minishell *msh) char **parser_get_arguments(t_list *list, t_minishell *msh)
{ {
t_list *current; t_list *current;
t_list *prev;
char **args; char **args;
int cmds; int argc;
int i; int i;
char *str;
char *cat;
cmds = count_cmds(list); argc = count_cmds(list);
args = malloc_safe(msh, (cmds + 1) * sizeof(char *)); args = malloc_safe(msh, (argc + 1) * sizeof(char *));
current = list; current = list;
i = -1; i = 0;
while ((++i) < cmds && current) prev = NULL;
while (argc > 0 && current)
{ {
if (parser_should_expand(current)) if (((t_token *)current->content)->type < 3 && (!prev || ((t_token *)prev->content)->type < 3))
args[i] = expander_parse_string( {
((t_token *)current->content)->value, msh); str = parser_process_token(msh, args, prev, current);
else if (((t_token *)current->content)->type < 3) if (i > 0 && prev && ft_strcmp(((t_token *)prev->content)->value, "") == 0)
args[i] = ft_strdup_safe(msh, {
((t_token *)current->content)->value); 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;
}
else if (str)
args[i++] = str;
argc--;
}
prev = current;
current = current->next; current = current->next;
} }
args[i] = 0; args[i] = 0;

View File

@ -0,0 +1,39 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser_sanitize_string.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/05 10:56:27 by qmennen #+# #+# */
/* Updated: 2025/03/05 11:09:25 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *parser_sanitize_string(t_minishell *msh, char *str, char c)
{
int i;
int j;
int qts;
char *dest;
i = 0;
qts = 0;
while (str[i++])
if (str[i] == c)
qts++;
dest = malloc_safe(msh, ft_strlen(str) - qts + 1);
i = 0;
j = 0;
while (str[i])
{
if (str[i] != c)
dest[j++] = str[i];
i++;
}
dest[j] = 0;
free_safe(msh, (void **)&str);
return (dest);
}