refactor: work on expansion

This commit is contained in:
Quinten 2025-03-05 11:32:12 +01:00
parent 029c3cbcb0
commit b3b6ed6d88
9 changed files with 156 additions and 81 deletions

View File

@ -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, char *cmd);
t_list *parser_get_commands(t_minishell *msh);
t_list *parser_get_input_redirects(t_list *list);

View File

@ -51,5 +51,10 @@ void token_print(void *param)
if (!DEBUG)
return ;
token = (t_token *)param;
if (token->type == T_ERROR)
{
printf("Error: %d\n", token->type);
return ;
}
printf("token type %i, value %s\n", token->type, token->value);
}

View File

@ -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)

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -10,7 +10,10 @@
/* */
/* ************************************************************************** */
#include "libft.h"
#include "minishell.h"
#include "parser.h"
#include "utils.h"
static int count_cmds(t_list *list)
{
@ -23,7 +26,7 @@ static int count_cmds(t_list *list)
while (current)
{
token = ((t_token *)current->content);
if (token->type >= 3)
if (token->type > 2)
break ;
cmds++;
current = current->next;
@ -40,41 +43,72 @@ 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 i;
char *str;
char *cat;
cmds = count_cmds(list);
args = malloc_safe(msh, (cmds + 1) * sizeof(char *));
current = list;
i = -1;
while ((++i) < cmds && current)
i = 0;
prev = NULL;
while (cmds > 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);
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;
prev = current;
current = current->next;
cmds--;
}
args[i] = 0;
return (args);

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);
}