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

This commit is contained in:
whaffman 2025-03-19 14:58:18 +01:00
commit 964a1cec57
7 changed files with 113 additions and 79 deletions

View File

@ -25,49 +25,9 @@ A lot of amazing shell stuff
## TODO
- [ ] export without arguments
- [ ] ft_free_arr_safe in environment mess
- [ ] builtins not first in pipeline? wtf is happening HAHAHAHAHAH its not using builtin, but core-utils
- [ ] Remove -c option parsing as split can break
- [ ] Only `""` as input shows command not found, that invalid
- [ ] CTRL+\ during `sleep 5` should do nothing, but returns a new prompt
- [ ] echo "hello" > /root/protected.txt gives the error but still prints
- [ ] cat < filenoexit returns `minishell: minishell: unable to write to temp file: No such file or directory` but we're not writin
- [x] Find absolute path for command input ('/', './', 'cmd')
- [x]Add heredoc to tokenizer
- [x] Environment to `t_list`
- [x] Get environment array (export)
- [x] Set environment variable (export)
- [x] Simple builtin export
- [x] builtins
- [x] Preliminary signals
- [x] Define struct for commands, something like (
```c
typedef struct s_command
{
char *command;
char *path;
char **args;
int fd_in;
int fd_out;
} t_command;
```
)
- [x] Make the `executor`, run a command
- [x] Make a parser to create a command list
- [x] Add redirects, appends, pipe etc. File descriptor functions
a command can have multiple redirects but only the last is used for stdout
Redirects take precedence over pipes, but pipes are still created and managed.
should it close the unused pipe-end?
all redirects are opened and closed, but only last fd is used.
multiple HEREDOCs can be nested, only last is used.
- [x] Expand \$ vars & support \$ ~?
* [x] $var
* [x] $?
* [ ] ~
- [x] export without arguments
- [ ] ft_free_arr_safe in environment mess
- [x] builtins not first in pipeline? wtf is happening HAHAHAHAHAH its not using builtin, but core-utils
- CTRL+C on input line results in exit code 130 in bash. -> this is signal global
- `cat | cat | ls` isn't blocking. (processes appear to be active while parent moves on)
- `echo $USER" $PWD` -> match quotes and throw error.
- CB command to change banner
- __Bonus:__ Command tree for &&, ||, *

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/05 13:11:41 by qmennen #+# #+# */
/* Updated: 2025/03/05 20:54:45 by qmennen ### ########.fr */
/* Updated: 2025/03/18 16:22:39 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -17,5 +17,6 @@
t_token *token_from_list(t_list *list);
t_list *token_list_index(t_list *tokens, int index);
t_token *token_validate_list(t_list *tokens);
#endif

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* lexer_read_word.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 19:03:47 by qmennen #+# #+# */
/* Updated: 2025/03/07 13:42:29 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* lexer_read_word.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/05 19:03:47 by qmennen #+# #+# */
/* Updated: 2025/03/18 16:23:02 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -57,6 +57,31 @@ char *read_word(t_minishell *msh, t_lexer *lexer, int len)
return (dest);
}
int match_quotes(t_lexer *lexer)
{
char c;
int i;
int sq;
int dq;
sq = 0;
dq = 0;
i = lexer->pos;
c = lexer->current_char;
while (c && !ft_isspace(c) && !(c == '>' || c == '<' || c == '|'))
{
c = lexer->input[i];
if (c == '\'')
sq++;
else if (c == '"')
dq++;
i++;
}
if (sq == 0 && dq == 0)
return (1);
return (dq % 2 == 0 && sq % 2 == 0);
}
char *lexer_readword(t_minishell *msh, t_lexer *lexer)
{
int len;
@ -68,6 +93,8 @@ char *lexer_readword(t_minishell *msh, t_lexer *lexer)
qts = (c == '"' || c == '\'');
if (qts)
return (lexer_parse_quotes(msh, lexer));
if (!match_quotes(lexer))
return (NULL);
len = calculate_word_len(lexer);
word = read_word(msh, lexer, len);
return (word);

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* lexer_token_next.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:07:58 by qmennen #+# #+# */
/* Updated: 2025/02/26 16:14:10 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* lexer_token_next.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/04 16:07:58 by qmennen #+# #+# */
/* Updated: 2025/03/18 16:18:23 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -31,9 +31,7 @@ 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

@ -6,17 +6,18 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:19:22 by whaffman #+# #+# */
/* Updated: 2025/03/19 14:50:28 by whaffman ######## odam.nl */
/* Updated: 2025/03/19 14:58:06 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "libft.h"
#include "minishell.h"
int g_signum = 0;
static void main_loop(t_minishell *msh)
{
t_token *error_token;
while (TRUE)
{
g_signum = 0;
@ -27,6 +28,14 @@ static void main_loop(t_minishell *msh)
break ;
msh->lexer = ft_lexer_new(msh);
msh->tokens = ft_parse_input(msh);
error_token = token_validate_list(msh->tokens);
if (error_token)
{
printf(BOLD RED"minishell"RESET": syntax error near position %i\n",
(error_token->position + 1));
free_minishell_line(msh);
continue ;
}
ft_lstiter(msh->tokens, token_print);
msh->commands = parser_get_commands(msh);
executor_execute_pipeline(msh);

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/26 16:46:32 by qmennen #+# #+# */
/* Updated: 2025/03/18 14:32:19 by qmennen ### ########.fr */
/* Updated: 2025/03/18 14:40:51 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -52,10 +52,31 @@ int fork_for_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim)
return (0);
}
static int process_heredoc_line(t_minishell *msh, int fd, char *delim)
{
char *line;
char *expand;
line = readline(">");
if (!line)
{
error_msg("warning: here-document delimited by end-of-file, wanted",
delim);
return (FAILURE);
}
if ((*line && ft_strcmp(line, delim) == 0))
return (free(line), FAILURE);
if (!*line)
ft_strlcat(line, "\n", 1);
expand = expander_parse_string(line, msh);
ft_putendl_fd(expand, fd);
free_safe(msh, (void **)&expand);
free(line);
return (SUCCESS);
}
int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim)
{
char *line;
char *expand;
const int fd = open(".ms_heredoc", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0)
@ -65,23 +86,11 @@ int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim)
}
while (TRUE)
{
line = readline(">");
if (!line)
{
error_msg("warning: here-document delimited by end-of-file, wanted", delim->value);
break;
}
if ((*line && ft_strcmp(line, delim->value) == 0))
if (! process_heredoc_line(msh, fd, delim->value))
break ;
if (!*line)
ft_strlcat(line, "\n", 1);
expand = expander_parse_string(line, msh);
ft_putendl_fd(expand, fd);
free_safe(msh, (void **)&expand);
free(line);
}
close(fd);
heredoc->type = T_REDIRECT_IN;
delim->value = ft_strdup_safe(msh, ".ms_heredoc");
return (free(line), 1);
return (SUCCESS);
}

View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* token_validate_list.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/18 16:08:44 by qmennen #+# #+# */
/* Updated: 2025/03/18 16:23:11 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "token.h"
t_token *token_validate_list(t_list *tokens)
{
t_list *current;
t_token *token;
current = tokens;
token = token_from_list(current);
while (current)
{
token = token_from_list(current);
if (token->type == T_ERROR)
return (token);
current = current->next;
}
return (NULL);
}