Merge remote-tracking branch 'origin/main' into willem
This commit is contained in:
commit
964a1cec57
46
README.md
46
README.md
@ -25,49 +25,9 @@ A lot of amazing shell stuff
|
|||||||
|
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
- [ ] export without arguments
|
- CTRL+C on input line results in exit code 130 in bash. -> this is signal global
|
||||||
- [ ] ft_free_arr_safe in environment mess
|
- `cat | cat | ls` isn't blocking. (processes appear to be active while parent moves on)
|
||||||
- [ ] builtins not first in pipeline? wtf is happening HAHAHAHAHAH its not using builtin, but core-utils
|
- `echo $USER" $PWD` -> match quotes and throw error.
|
||||||
- [ ] 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
|
|
||||||
- CB command to change banner
|
- CB command to change banner
|
||||||
- __Bonus:__ Command tree for &&, ||, *
|
- __Bonus:__ Command tree for &&, ||, *
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
|
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/05 13:11:41 by qmennen #+# #+# */
|
/* 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_token *token_from_list(t_list *list);
|
||||||
t_list *token_list_index(t_list *tokens, int index);
|
t_list *token_list_index(t_list *tokens, int index);
|
||||||
|
t_token *token_validate_list(t_list *tokens);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* :::::::: */
|
/* ::: :::::::: */
|
||||||
/* lexer_read_word.c :+: :+: */
|
/* lexer_read_word.c :+: :+: :+: */
|
||||||
/* +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: qmennen <qmennen@student.codam.nl> +#+ */
|
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
|
||||||
/* +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/05 19:03:47 by qmennen #+# #+# */
|
/* Created: 2025/02/05 19:03:47 by qmennen #+# #+# */
|
||||||
/* Updated: 2025/03/07 13:42:29 by whaffman ######## odam.nl */
|
/* 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);
|
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)
|
char *lexer_readword(t_minishell *msh, t_lexer *lexer)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@ -68,6 +93,8 @@ char *lexer_readword(t_minishell *msh, t_lexer *lexer)
|
|||||||
qts = (c == '"' || c == '\'');
|
qts = (c == '"' || c == '\'');
|
||||||
if (qts)
|
if (qts)
|
||||||
return (lexer_parse_quotes(msh, lexer));
|
return (lexer_parse_quotes(msh, lexer));
|
||||||
|
if (!match_quotes(lexer))
|
||||||
|
return (NULL);
|
||||||
len = calculate_word_len(lexer);
|
len = calculate_word_len(lexer);
|
||||||
word = read_word(msh, lexer, len);
|
word = read_word(msh, lexer, len);
|
||||||
return (word);
|
return (word);
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* :::::::: */
|
/* ::: :::::::: */
|
||||||
/* lexer_token_next.c :+: :+: */
|
/* lexer_token_next.c :+: :+: :+: */
|
||||||
/* +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: qmennen <qmennen@student.codam.nl> +#+ */
|
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
|
||||||
/* +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/04 16:07:58 by qmennen #+# #+# */
|
/* Created: 2025/02/04 16:07:58 by qmennen #+# #+# */
|
||||||
/* Updated: 2025/02/26 16:14:10 by whaffman ######## odam.nl */
|
/* 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_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);
|
||||||
|
|||||||
13
src/main.c
13
src/main.c
@ -6,17 +6,18 @@
|
|||||||
/* By: qmennen <qmennen@student.codam.nl> +#+ */
|
/* By: qmennen <qmennen@student.codam.nl> +#+ */
|
||||||
/* +#+ */
|
/* +#+ */
|
||||||
/* Created: 2025/02/04 16:19:22 by whaffman #+# #+# */
|
/* 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"
|
#include "minishell.h"
|
||||||
|
|
||||||
int g_signum = 0;
|
int g_signum = 0;
|
||||||
|
|
||||||
static void main_loop(t_minishell *msh)
|
static void main_loop(t_minishell *msh)
|
||||||
{
|
{
|
||||||
|
t_token *error_token;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
g_signum = 0;
|
g_signum = 0;
|
||||||
@ -27,6 +28,14 @@ static void main_loop(t_minishell *msh)
|
|||||||
break ;
|
break ;
|
||||||
msh->lexer = ft_lexer_new(msh);
|
msh->lexer = ft_lexer_new(msh);
|
||||||
msh->tokens = ft_parse_input(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);
|
ft_lstiter(msh->tokens, token_print);
|
||||||
msh->commands = parser_get_commands(msh);
|
msh->commands = parser_get_commands(msh);
|
||||||
executor_execute_pipeline(msh);
|
executor_execute_pipeline(msh);
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
|
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/26 16:46:32 by qmennen #+# #+# */
|
/* 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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim)
|
static int process_heredoc_line(t_minishell *msh, int fd, char *delim)
|
||||||
{
|
{
|
||||||
char *line;
|
char *line;
|
||||||
char *expand;
|
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)
|
||||||
|
{
|
||||||
const int fd = open(".ms_heredoc", O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
const int fd = open(".ms_heredoc", O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -65,23 +86,11 @@ int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim)
|
|||||||
}
|
}
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
line = readline(">");
|
if (! process_heredoc_line(msh, fd, delim->value))
|
||||||
if (!line)
|
|
||||||
{
|
|
||||||
error_msg("warning: here-document delimited by end-of-file, wanted", delim->value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((*line && ft_strcmp(line, delim->value) == 0))
|
|
||||||
break ;
|
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);
|
close(fd);
|
||||||
heredoc->type = T_REDIRECT_IN;
|
heredoc->type = T_REDIRECT_IN;
|
||||||
delim->value = ft_strdup_safe(msh, ".ms_heredoc");
|
delim->value = ft_strdup_safe(msh, ".ms_heredoc");
|
||||||
return (free(line), 1);
|
return (SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/token/token_validate_list.c
Normal file
30
src/token/token_validate_list.c
Normal 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);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user