Merge remote-tracking branch 'origin/quinten' into willem
This commit is contained in:
commit
32f416694c
@ -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);
|
||||||
|
|||||||
@ -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 */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|||||||
@ -16,14 +16,10 @@ 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);
|
||||||
{
|
if (!executable)
|
||||||
executable = ft_strdup_safe(msh, cmd);
|
return (NULL);
|
||||||
if (!executable)
|
return (executable);
|
||||||
return (NULL);
|
|
||||||
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)
|
||||||
|
|||||||
@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ static t_token_type get_word_type(char c)
|
|||||||
return (T_WORD);
|
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_type word_type;
|
||||||
t_token *token;
|
t_token *token;
|
||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
39
src/parser/parser_sanitize_string.c
Normal file
39
src/parser/parser_sanitize_string.c
Normal 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);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user