mirror of
https://github.com/Ladebeze66/minishell.git
synced 2026-11-09 13:47:17 +01:00
minishell
This commit is contained in:
121
tokenize/quotes.c
Executable file
121
tokenize/quotes.c
Executable 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
112
tokenize/tokenize.c
Executable 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
89
tokenize/tokenize_symbol.c
Executable 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
87
tokenize/tokenize_utils.c
Executable 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user