diff --git a/Makefile b/Makefile index 304bd12..92b3ad1 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ # **************************************************************************** # # # -# ::: o_ :::::: ::: # -# Makefile :+: / :+::+: :+: # -# +:+ > +:++:+ +:+ # -# By: whaffman +#+ +:+ +#++#++:++#++ # -# +#+ +#+#+ +#++#+ +#+ \o/ # -# Created: 2024/10/15 11:48:46 by whaffman #+#+# #+#+# #+# #+# | # -# Updated: 2024/11/07 15:28:08 by whaffman ### ### ### ### / \ # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: qmennen +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2024/10/15 11:48:46 by whaffman #+# #+# # +# Updated: 2025/02/04 16:57:05 by qmennen ### ########.fr # # # # **************************************************************************** # @@ -22,7 +22,7 @@ LIBFT = $(LIBFT_PATH)/libft.a OBJ_PATH = obj -VPATH = src +VPATH = src:src/tokenizer SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c")) OBJECTS = $(addprefix $(OBJ_PATH)/, $(SOURCES:.c=.o)) @@ -32,7 +32,7 @@ CC = cc RM = rm -rf INCLUDES = -I./$(INC_PATH) -I./$(LIBFT_INC_PATH) -CFLAGS = -Wall -Wextra -Werror -MMD +CFLAGS = -Wall -Wextra -Werror -fsanitize=address,undefined -MMD UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Linux) diff --git a/inc/minishell.h b/inc/minishell.h index 86b4cac..5aa8ca0 100644 --- a/inc/minishell.h +++ b/inc/minishell.h @@ -147,6 +147,8 @@ #ifndef MINISHELL_H # define MINISHELL_H +# define TRUE 1 + # include # include # include @@ -161,5 +163,48 @@ # include # include # include +# include "libft.h" -#endif // MINISHELL_H \ No newline at end of file +typedef enum +{ + T_WORD, + T_PIPE, + T_REDIRECT_IN, + T_REDIRECT_OUT, + T_APPEND_OUT, + T_EOF, + T_ERROR +} TokenType; + +typedef struct s_token +{ + TokenType type; + char *value; + int position; +} t_token; + +typedef struct s_lexer +{ + char *input; + int pos; + int n_pos; + char current_char; +} t_lexer; + +int ft_isspace(const char c); + +/** + * Lexer + */ +t_lexer *ft_lexer_new(const char *input); +void ft_lexer_free(t_lexer *lexer); +void ft_lexer_readchar(t_lexer *lexer); +char *ft_lexer_readword(t_lexer *lexer); +/** + * Token + */ +t_token *ft_token_next(t_lexer *lexer); +t_token *ft_token_new(TokenType type, char *c, int pos); +void ft_token_free(t_token *token); +void ft_clear_tokenlist(void *content); +#endif \ No newline at end of file diff --git a/src/prompt.c b/src/prompt.c index c67e98f..f793030 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -4,6 +4,7 @@ #include #include #include "libft.h" +#include "minishell.h" // /** @@ -69,20 +70,43 @@ void print_prompt(void) free(cwd); } +void print_list(void *content) +{ + t_token *token; + token = (t_token *)content; + ft_printf("%s\n", token->value); +} + int main(int argc, char **argv, char **envp) { (void)argc; - (void)argv; - char **env; - t_enviroment *enviroment = NULL; + (void)envp; + // char **env; + // t_enviroment *enviroment = NULL; + t_lexer *lexer; + t_token *token; + t_list *list; - while (*envp != NULL) - { - env = ft_split(*envp, '='); - add_enviroment(&enviroment, env[0], env[1]); - envp++; - } + // while (*envp != NULL) + // { + // env = ft_split(*envp, '='); + // add_enviroment(&enviroment, env[0], env[1]); + // envp++; + // } - print_enviroment(enviroment); + lexer = ft_lexer_new(argv[1]); + list = NULL; + while (TRUE) + { + token = ft_token_next(lexer); + if (token->type == T_EOF) + break; + ft_lstadd_back(&list, ft_lstnew(token)); + } + ft_lstiter(list, print_list); + ft_lstclear(&list, ft_clear_tokenlist); + ft_token_free(token); + ft_lexer_free(lexer); + // print_enviroment(enviroment); return 0; } \ No newline at end of file diff --git a/src/tokenizer/lexer.c b/src/tokenizer/lexer.c new file mode 100644 index 0000000..186e612 --- /dev/null +++ b/src/tokenizer/lexer.c @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/04 18:04:07 by qmennen #+# #+# */ +/* Updated: 2025/02/04 20:11:48 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_lexer *ft_lexer_new(const char *input) +{ + t_lexer *lexer; + + lexer = malloc(sizeof(t_lexer)); + if (!lexer) + { + perror("failed assigning lexer memory"); + exit(EXIT_FAILURE); + } + lexer->input = ft_strdup(input); + lexer->pos = 0; + lexer->n_pos = 1; + lexer->current_char = '\0'; + if (ft_strlen(input) > 0) + lexer->current_char = *input; + return (lexer); +} + +void ft_lexer_readchar(t_lexer *lexer) +{ + if ((size_t)lexer->n_pos > ft_strlen(lexer->input)) + { + lexer->current_char = '\0'; + return; + } + lexer->current_char = lexer->input[lexer->n_pos]; + lexer->pos = lexer->n_pos; + lexer->n_pos++; +} + +char *ft_lexer_readword(t_lexer *lexer) +{ + int start; + int len; + char quote; + char *word; + + start = lexer->pos; + if (lexer->current_char == '"' || lexer->current_char == '\'') + { + quote = lexer->current_char; + ft_lexer_readchar(lexer); + start = lexer->pos; + while (lexer->current_char != '\0' && lexer->current_char != quote) + ft_lexer_readchar(lexer); + if (lexer->current_char == quote) + { + len = lexer->pos - start; + word = malloc(sizeof(char) * len); + ft_strlcpy(word, lexer->input + start, len + 1); + ft_lexer_readchar(lexer); + return (word); + } + } + start = lexer->pos; + while (ft_isprint(lexer->current_char) && lexer->current_char != '<' && lexer->current_char != '>' && lexer->current_char != '|' && lexer->current_char != '\0') + ft_lexer_readchar(lexer); + len = lexer->pos - start; + word = malloc(sizeof(char) * len); + ft_strlcpy(word, lexer->input + start, len + 1); + return (word); +} + +void ft_lexer_free(t_lexer *lexer) +{ + if (lexer->input) + free(lexer->input); + free(lexer); +} \ No newline at end of file diff --git a/src/tokenizer/tokenizer.c b/src/tokenizer/tokenizer.c new file mode 100644 index 0000000..a7b4ed8 --- /dev/null +++ b/src/tokenizer/tokenizer.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tokenizer.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/04 16:07:58 by qmennen #+# #+# */ +/* Updated: 2025/02/04 20:14:50 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +# include "minishell.h" + +t_token *ft_token_next(t_lexer *lexer) +{ + t_token *token; + char *word; + int current_pos; + + token = NULL; + while (ft_isspace(lexer->current_char)) + ft_lexer_readchar(lexer); + current_pos = lexer->pos; + switch(lexer->current_char) + { + case '\0': + token = ft_token_new(T_EOF, NULL, current_pos); + break; + case '|': + token = ft_token_new(T_PIPE, "|", current_pos); + ft_lexer_readchar(lexer); + break; + case '<': + token = ft_token_new(T_REDIRECT_IN, "<", current_pos); + ft_lexer_readchar(lexer); + break; + case '>': + ft_lexer_readchar(lexer); + if (lexer->current_char == '>') + { + token = ft_token_new(T_APPEND_OUT, ">>", current_pos); + ft_lexer_readchar(lexer); + } + else + token = ft_token_new(T_REDIRECT_OUT, ">", current_pos); + break; + default: + if (ft_isprint(lexer->current_char)) + { + word = ft_lexer_readword(lexer); + token = ft_token_new(T_WORD, word, current_pos); + free(word); + } + } + return (token); +} + +void ft_clear_tokenlist(void *content) +{ + t_token *token; + + token = (t_token *)content; + ft_token_free(token); +} \ No newline at end of file diff --git a/src/tokenizer/tokens.c b/src/tokenizer/tokens.c new file mode 100644 index 0000000..7dec144 --- /dev/null +++ b/src/tokenizer/tokens.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tokens.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/04 18:02:56 by qmennen #+# #+# */ +/* Updated: 2025/02/04 18:22:11 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +# include "minishell.h" + +t_token *ft_token_new(TokenType type, char *c, int pos) +{ + t_token *token; + + token = malloc(sizeof(t_token)); + if (!token) + { + perror("failed assigning token memory"); + exit(EXIT_FAILURE); + } + token->type = type; + token->position = pos; + if (c) + token->value = ft_strdup(c); + else + token->value = NULL; + return (token); +} + +void ft_token_free(t_token *token) +{ + if (token->value) + free(token->value); + free(token); +} \ No newline at end of file diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..bd2a97c --- /dev/null +++ b/src/util.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* util.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/04 16:31:29 by qmennen #+# #+# */ +/* Updated: 2025/02/04 16:32:08 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +# include "minishell.h" + +int ft_isspace(const char c) +{ + return (c == ' ' || c == '\t' || c == '\v' || c == '\n' || c == '\v'); +} \ No newline at end of file