minishell

This commit is contained in:
2023-12-12 17:32:54 +01:00
commit 196e143285
92 changed files with 4905 additions and 0 deletions

121
tokenize/quotes.c Executable file
View File

@@ -0,0 +1,121 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* quotes.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/26 10:40:11 by fgras-ca #+# #+# */
/* Updated: 2023/12/07 16:19:24 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
int are_only_quotes(char **tokens)
{
int i;
i = 0;
while (tokens && tokens[i])
{
if (ft_strcmp(tokens[i], "\"\"") != 0
&& ft_strcmp(tokens[i], "''") != 0)
return (0);
i++;
}
return (1);
}
void handle_normal_state(char input_char, t_Tokenizer *tk)
{
if (input_char == '\'')
{
tk->state = SINGLE_QUOTE;
}
else if (input_char == '\"')
{
tk->state = DOUBLE_QUOTE;
}
else
{
tk->token[(tk->token_length)++] = input_char;
tk->symbol = true;
}
}
void handle_double_quote_state(char input_char, t_Tokenizer *tk)
{
if (input_char != '\"')
{
tk->token[(tk->token_length)++] = input_char;
if (input_char == '$')
{
tk->variable = 0;
}
if (is_simple_symbol(input_char) == true)
tk->symbol = false;
}
else
{
if (tk->token_length > 0 && tk->token[tk->token_length - 1] == ' ')
{
tk->token[(tk->token_length)++] = input_char;
}
else
{
tk->state = NORMAL;
tk->symbol = true;
}
}
}
void handle_single_quote_state(char input_char, t_Tokenizer *tk)
{
if (input_char != '\'')
{
tk->token[(tk->token_length)++] = input_char;
if (input_char == '$')
{
tk->variable = 1;
}
if (is_simple_symbol(input_char) == true)
{
tk->symbol = false;
}
}
else
{
if (tk->token_length > 0 && tk->token[tk->token_length - 1] == ' ')
{
tk->token[(tk->token_length)++] = input_char;
}
else
{
tk->state = NORMAL;
}
}
}
char **handle_unclosed_quotes(char ***tokens, int token_pos)
{
int i;
i = 0;
if (tokens == NULL || *tokens == NULL)
{
return (NULL);
}
write(2, RED"Error: quote not closed\n"RST, 32);
if (token_pos > 0)
{
while (i < token_pos)
{
free((*tokens)[i]);
i++;
}
free(*tokens);
}
*tokens = NULL;
return (NULL);
}

112
tokenize/tokenize.c Executable file
View File

@@ -0,0 +1,112 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tokenize.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/21 20:09:39 by fgras-ca #+# #+# */
/* Updated: 2023/12/09 01:03:54 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
bool handle_quotes(char current_char, t_Tokenizer *tk)
{
if ((tk->state == NORMAL && (current_char == '\'' || current_char == '\"'))
|| (tk->state == SINGLE_QUOTE && current_char == '\'')
|| (tk->state == DOUBLE_QUOTE && current_char == '\"'))
{
if (tk->state == NORMAL)
{
if (current_char == '\'')
{
tk->state = SINGLE_QUOTE;
}
else
{
tk->state = DOUBLE_QUOTE;
}
}
else
tk->state = NORMAL;
tk->input_pos++;
return (true);
}
return (false);
}
void process_remaining_chars(char current_char, char *input, t_Tokenizer *tk)
{
if (tk->state != NORMAL)
{
process_char(current_char, tk);
tk->input_pos++;
return ;
}
if (current_char == ' ' || current_char == '\t')
{
if (tk->token_length > 0)
{
add_token_to_list(tk);
}
handle_spaces_and_tabs(input, tk);
}
else if (is_special_symbol(current_char, input[tk->input_pos + 1]))
add_special_symbol(input, tk);
else
{
process_char(current_char, tk);
tk->variable = 0;
tk->input_pos++;
}
}
void process_input_char(char *input, t_Tokenizer *tk)
{
char current_char;
current_char = input[tk->input_pos];
if (!handle_quotes(current_char, tk))
{
process_remaining_chars(current_char, input, tk);
}
}
void tokenize_loop(char *input, t_Tokenizer *tk)
{
while (input[tk->input_pos] != '\0')
{
process_input_char(input, tk);
}
if (tk->token_length > 0)
{
add_token_to_list(tk);
}
}
char **tokenize_and_parse_input(char *input, t_minishell *shell, int fd)
{
char **result;
if (is_only_spaces(input))
return (NULL);
init_vars(shell->tokenizer, input);
tokenize_loop(input, shell->tokenizer);
if (shell->tokenizer->state == SINGLE_QUOTE
|| shell->tokenizer->state == DOUBLE_QUOTE)
{
result = handle_unclosed_quotes(&shell->tokenizer->tokens,
shell->tokenizer->token_pos);
free(shell->tokenizer->token);
return (result);
}
add_token_to_list(shell->tokenizer);
if (shell->tokenizer->tokens != NULL)
shell->tokenizer->tokens[shell->tokenizer->token_pos] = NULL;
parse_tokens(shell->tokenizer->tokens, shell, fd);
free(shell->tokenizer->token);
free_tokens(shell->tokenizer->tokens);
return (NULL);
}

89
tokenize/tokenize_symbol.c Executable file
View File

@@ -0,0 +1,89 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tokenize_symbol.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/03 17:34:50 by fgras-ca #+# #+# */
/* Updated: 2023/12/07 16:19:24 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void handle_spaces_and_tabs(char *input, t_Tokenizer *tk)
{
while (input[tk->input_pos] == ' ' || input[tk->input_pos] == '\t')
{
tk->input_pos++;
}
}
void add_special_symbol(char *input, t_Tokenizer *tk)
{
if (tk->token_length > 0)
{
add_token_to_list(tk);
}
tk->token[0] = input[tk->input_pos++];
tk->token_length = 1;
if ((tk->token[0] == '>' && input[tk->input_pos] == '>')
|| (tk->token[0] == '<' && input[tk->input_pos] == '<'))
{
tk->token[tk->token_length++] = input[tk->input_pos++];
}
tk->token[tk->token_length] = '\0';
add_token_to_list(tk);
}
void handle_empty_quotes(char *input, t_Tokenizer *tk)
{
char quote_type;
int start_pos;
int i;
quote_type = input[tk->input_pos];
start_pos = tk->input_pos;
tk->input_pos++;
while (input[tk->input_pos] != quote_type && input[tk->input_pos] != '\0')
{
tk->input_pos++;
}
if (input[tk->input_pos] == quote_type)
{
if (tk->input_pos - start_pos > 1)
{
i = start_pos + 1;
while (i < tk->input_pos)
{
tk->token[tk->token_length++] = input[i];
i++;
}
add_token_to_list(tk);
}
tk->input_pos++;
}
}
bool is_special_symbol(char c, char next_c)
{
if (c == '|' || c == '<' || c == '>')
{
return (true);
}
if ((c == '>' && next_c == '>') || (c == '<' && next_c == '<'))
{
return (true);
}
return (false);
}
bool is_simple_symbol(char c)
{
if (c == '|' || c == '<' || c == '>')
{
return (true);
}
return (false);
}

87
tokenize/tokenize_utils.c Executable file
View File

@@ -0,0 +1,87 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tokenize_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/01 17:41:31 by fgras-ca #+# #+# */
/* Updated: 2023/12/10 11:23:56 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void free_tokens(char **tokens)
{
int i;
if (tokens != NULL)
{
i = 0;
while (tokens[i] != NULL)
{
free(tokens[i]);
i++;
}
free(tokens);
}
}
void add_token_to_list(t_Tokenizer *tk)
{
char *token_to_add;
if (tk->token_length > 0)
{
tk->token[tk->token_length] = '\0';
token_to_add = strdup(tk->token);
if (token_to_add != NULL)
{
tk->tokens[tk->token_pos++] = token_to_add;
}
tk->token_length = 0;
tk->within_single_quotes = false;
tk->within_double_quotes = false;
}
if (tk->token != NULL)
{
free(tk->token);
}
tk->token = malloc(1000);
if (tk->token != NULL)
{
ft_memset(tk->token, 0, 1000);
}
}
void process_char(char input_char, t_Tokenizer *tk)
{
if (tk->state == NORMAL)
{
handle_normal_state(input_char, tk);
}
else if (tk->state == SINGLE_QUOTE)
{
handle_single_quote_state(input_char, tk);
}
else if (tk->state == DOUBLE_QUOTE)
{
handle_double_quote_state(input_char, tk);
}
}
void init_vars(t_Tokenizer *tk, char *input)
{
tk->state = NORMAL;
tk->tokens = malloc(MAX_ARGS * sizeof(char *));
tk->token = malloc(ft_strlen(input) + 1);
tk->token_length = 0;
tk->input_pos = 0;
tk->token_pos = 0;
if (!(tk->tokens) || !(tk->token))
{
write(STDERR_FILENO, "Minishell: allocation error\n", 29);
exit(EXIT_FAILURE);
}
}