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> +#+ */
|
||||
/* +#+ */
|
||||
/* 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"
|
||||
|
||||
char *parser_sanitize_string(t_minishell *msh, char *str, char c);
|
||||
t_command *parser_alloc_command(t_minishell *msh);
|
||||
t_list *parser_get_commands(t_minishell *msh);
|
||||
t_list *parser_get_input_redirects(t_list *list);
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: marvin <marvin@student.42.fr> +#+ */
|
||||
/* +#+ */
|
||||
/* 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;
|
||||
|
||||
if (access(cmd, F_OK) == 0)
|
||||
{
|
||||
executable = ft_strdup_safe(msh, cmd);
|
||||
if (!executable)
|
||||
return (NULL);
|
||||
return (executable);
|
||||
}
|
||||
return (NULL);
|
||||
executable = ft_strdup_safe(msh, cmd);
|
||||
if (!executable)
|
||||
return (NULL);
|
||||
return (executable);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
char *path;
|
||||
@ -34,18 +49,13 @@ 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) != 0)
|
||||
if (path == NULL)
|
||||
{
|
||||
errno = 0;
|
||||
error_msg("minishell", "command not found");
|
||||
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);
|
||||
}
|
||||
else if (! validate_executable_path(path))
|
||||
return ;
|
||||
execve(path, command->args, environment_get_arr(msh));
|
||||
}
|
||||
|
||||
@ -35,10 +35,12 @@ t_list *ft_parse_input(t_minishell *msh)
|
||||
while (TRUE)
|
||||
{
|
||||
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));
|
||||
if (token->type == T_EOF || token->type == T_ERROR)
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
ft_token_free(msh, token);
|
||||
// ft_token_free(msh, token);
|
||||
return (list);
|
||||
}
|
||||
|
||||
@ -14,35 +14,11 @@
|
||||
|
||||
static int is_word_char(char c)
|
||||
{
|
||||
return (ft_isprint(c)
|
||||
&& c != '<'
|
||||
&& c != '>'
|
||||
&& c != '|'
|
||||
&& c != '\0'
|
||||
&& !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);
|
||||
if (c == '<' || c == '>' || c == '|' || c == '\0')
|
||||
return (0);
|
||||
else if (ft_isspace(c))
|
||||
return (0);
|
||||
return (ft_isprint(c));
|
||||
}
|
||||
|
||||
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;
|
||||
while (is_word_char(lexer->input[i]))
|
||||
{
|
||||
if (lexer->input[i] != '\'' && lexer->input[i] != '"')
|
||||
len++;
|
||||
|
||||
len++;
|
||||
i++;
|
||||
}
|
||||
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 *dest;
|
||||
int i;
|
||||
|
||||
if (lexer->current_char == '"' || lexer->current_char == '\'')
|
||||
{
|
||||
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);
|
||||
dest = malloc_safe(msh, sizeof(char) * len);
|
||||
c = lexer->current_char;
|
||||
len = 0;
|
||||
i = 0;
|
||||
while (is_word_char(c))
|
||||
{
|
||||
if (c != '\'' && c != '"')
|
||||
word[len++] = lexer->current_char;
|
||||
dest[i++] = lexer->current_char;
|
||||
lexer_readchar(lexer);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -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 = 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);
|
||||
|
||||
@ -10,22 +10,27 @@
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "libft.h"
|
||||
#include "minishell.h"
|
||||
#include "parser.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int count_cmds(t_list *list)
|
||||
{
|
||||
int cmds;
|
||||
t_list *current;
|
||||
t_list *prev;
|
||||
t_token *token;
|
||||
|
||||
cmds = 0;
|
||||
current = list;
|
||||
prev = NULL;
|
||||
while (current)
|
||||
{
|
||||
token = ((t_token *)current->content);
|
||||
if (token->type >= 3)
|
||||
break ;
|
||||
cmds++;
|
||||
if (token->type < 3 && (!prev || ((t_token *)prev->content)->type < 3))
|
||||
cmds++;
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
return (cmds);
|
||||
@ -40,40 +45,74 @@ static int parser_should_expand(t_list *value)
|
||||
if (!token)
|
||||
return (0);
|
||||
i = 0;
|
||||
if (token->type == T_DQWORD)
|
||||
if (token->type == T_DQWORD || token->type == T_WORD)
|
||||
{
|
||||
while (token->value[i])
|
||||
{
|
||||
if (token->value[i] == '$'
|
||||
&& !expander_character_valid(token->value[i + 1]))
|
||||
return (0);
|
||||
&& (expander_character_valid(token->value[i + 1]) || token->value[i + 1] == '?'))
|
||||
return (1);
|
||||
i++;
|
||||
}
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
return ((token->type == T_WORD && token->value[0] == '$'
|
||||
&& token->value[1]));
|
||||
return (0);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
t_list *current;
|
||||
t_list *prev;
|
||||
char **args;
|
||||
int cmds;
|
||||
int argc;
|
||||
int i;
|
||||
char *str;
|
||||
char *cat;
|
||||
|
||||
cmds = count_cmds(list);
|
||||
args = malloc_safe(msh, (cmds + 1) * sizeof(char *));
|
||||
argc = count_cmds(list);
|
||||
args = malloc_safe(msh, (argc + 1) * sizeof(char *));
|
||||
current = list;
|
||||
i = -1;
|
||||
while ((++i) < cmds && current)
|
||||
i = 0;
|
||||
prev = NULL;
|
||||
while (argc > 0 && current)
|
||||
{
|
||||
if (parser_should_expand(current))
|
||||
args[i] = expander_parse_string(
|
||||
((t_token *)current->content)->value, msh);
|
||||
else if (((t_token *)current->content)->type < 3)
|
||||
args[i] = ft_strdup_safe(msh,
|
||||
((t_token *)current->content)->value);
|
||||
if (((t_token *)current->content)->type < 3 && (!prev || ((t_token *)prev->content)->type < 3))
|
||||
{
|
||||
str = parser_process_token(msh, args, prev, current);
|
||||
if (i > 0 && prev && ft_strcmp(((t_token *)prev->content)->value, "") == 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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