diff options
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | include/ast.h | 28 | ||||
| -rw-r--r-- | include/env.h | 24 | ||||
| -rw-r--r-- | include/minishell.h | 13 | ||||
| -rw-r--r-- | include/token.h | 16 | ||||
| -rw-r--r-- | lib/libft/Makefile | 2 | ||||
| -rw-r--r-- | lib/libft/ft_isspace.c | 20 | ||||
| -rw-r--r-- | lib/libft/ft_memset.c | 14 | ||||
| -rw-r--r-- | lib/libft/ft_strncpy.c | 21 | ||||
| -rw-r--r-- | lib/libft/libft.h | 6 | ||||
| -rw-r--r-- | src/collect_redirs.c | 99 | ||||
| -rw-r--r-- | src/free_node.c | 23 | ||||
| -rw-r--r-- | src/free_token.c | 23 | ||||
| -rw-r--r-- | src/main.c | 6 | ||||
| -rw-r--r-- | src/new_node.c | 27 | ||||
| -rw-r--r-- | src/parse_cmd.c | 52 | ||||
| -rw-r--r-- | src/parser.c | 84 | ||||
| -rw-r--r-- | src/print_ast.c | 59 | ||||
| -rw-r--r-- | src/repl.c | 16 | ||||
| -rw-r--r-- | src/tokenizer.c | 116 |
20 files changed, 567 insertions, 85 deletions
@@ -12,7 +12,8 @@ HEADERS = -I include -I $(LIB_DIR)/libft VPATH := src SRC := main.c debug_tools.c init.c signal_handling.c repl.c new_token.c \ - free_token.c new_node.c free_node.c + free_token.c new_node.c free_node.c tokenizer.c parser.c \ + parse_cmd.c collect_redirs.c print_ast.c OBJ_DIR := _obj OBJ := $(addprefix $(OBJ_DIR)/, $(SRC:%.c=%.o)) diff --git a/include/ast.h b/include/ast.h index e6ad25d..cd2f9c9 100644 --- a/include/ast.h +++ b/include/ast.h @@ -6,32 +6,20 @@ /* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 11:48:27 by dkaiser #+# #+# */ -/* Updated: 2024/06/28 14:56:55 by dkaiser ### ########.fr */ +/* Updated: 2024/08/11 12:20:56 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ -#include "stdlib.h" #include "debug_tools.h" - -typedef struct s_sequence -{ - struct s_node **nodes; -} t_sequence; +#include "stdlib.h" enum e_node_type { - ASSIGN_NODE, PIPE_NODE, CMD_NODE, STRING_NODE }; -typedef struct s_assign -{ - char *var; - char *value; -} t_assign; - typedef struct s_pipe { struct s_node *left; @@ -40,10 +28,10 @@ typedef struct s_pipe enum e_redirection_type { - INPUT_FILE, - INPUT_LIMITER, - OUTPUT_OVERRIDE, - OUTPUT_APPEND + INPUT_FILE = 1, + INPUT_LIMITER = 2, + OUTPUT_OVERRIDE = 4, + OUTPUT_APPEND = 8 }; typedef struct s_redirection @@ -60,7 +48,6 @@ typedef struct s_cmd union u_node_content { - struct s_assign assign; struct s_pipe pipe; struct s_cmd cmd; char *string; @@ -73,7 +60,8 @@ typedef struct s_node } t_node; t_node *new_node(int type); -t_node *new_assign_node(char *var, char *value); t_node *new_pipe_node(t_node *left, t_node *right); t_node *new_cmd_node(char **args, t_redirection redirs[2]); t_node *new_string_node(char *string); + +void free_node(t_node *node); diff --git a/include/env.h b/include/env.h index 1ea6f2e..12d8db0 100644 --- a/include/env.h +++ b/include/env.h @@ -6,18 +6,20 @@ /* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/08 16:53:39 by dkaiser #+# #+# */ -/* Updated: 2024/08/08 17:05:11 by dkaiser ### ########.fr */ +/* Updated: 2024/09/13 16:26:16 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ -typedef struct s_env { - char *name; - char *value; - struct s_env *next; -} t_env; +typedef struct s_env +{ + char *name; + char *value; + struct s_env *next; +} t_env; + +char *env_get(t_env *env, char *name); +void env_export(t_env *env, char *name, char *value); +void env_unset(t_env *env, char *name); +char **env_to_strlst(t_env *env); +t_env **env_from_strlst(char **lst); -char *env_get(t_env *env, char *name); -void env_export(t_env *env, char *name, char *value); -void env_unset(t_env *env, char *name); -char **env_to_strlst(t_env *env); -t_env **env_from_strlst(char **lst); diff --git a/include/minishell.h b/include/minishell.h index c108d93..6997b15 100644 --- a/include/minishell.h +++ b/include/minishell.h @@ -6,7 +6,7 @@ /* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/22 17:14:49 by dkaiser #+# #+# */ -/* Updated: 2024/08/08 17:10:12 by dkaiser ### ########.fr */ +/* Updated: 2024/08/11 12:22:07 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,9 +26,14 @@ # include <termios.h> # include <unistd.h> -int init(void); -int init_signal_handling(void); +int init(void); +int init_signal_handling(void); -void repl(const char *prompt); +void repl(const char *prompt); +t_list *parse(t_token *tokens); +t_node *parse_cmd(t_token *tokens); +t_redirection *collect_redirs(t_token **tokens); + +void print_ast(t_node *ast); #endif diff --git a/include/token.h b/include/token.h index 38e758f..54a65f2 100644 --- a/include/token.h +++ b/include/token.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* token.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 13:27:18 by dkaiser #+# #+# */ -/* Updated: 2024/06/28 14:59:19 by dkaiser ### ########.fr */ +/* Updated: 2024/08/29 15:26:23 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,10 +17,10 @@ enum e_token_type { - STRING_TOKEN, - PIPE_TOKEN, - REDIR_TOKEN, - NEWLINE_TOKEN + STRING_TOKEN = 1, + PIPE_TOKEN = 2, + REDIR_TOKEN = 4, + NEWLINE_TOKEN = 8 }; union u_token_content @@ -45,5 +45,9 @@ t_token *new_redir_token(int type, t_token *previous, t_token *next); void free_token(t_token *token); +void free_token_and_connect(t_token *token); +void free_tokens(t_token *tokens); +void tokenizer(char *s, t_token **token_list, + char quote_check); #endif diff --git a/lib/libft/Makefile b/lib/libft/Makefile index 3c2fb91..6f2950c 100644 --- a/lib/libft/Makefile +++ b/lib/libft/Makefile @@ -10,6 +10,7 @@ SRC = ft_atoi.c \ ft_isascii.c \ ft_isdigit.c \ ft_isprint.c \ + ft_isspace.c \ ft_itoa.c \ ft_memchr.c \ ft_memcmp.c \ @@ -30,6 +31,7 @@ SRC = ft_atoi.c \ ft_strlen.c \ ft_strmapi.c \ ft_strncmp.c \ + ft_strncpy.c \ ft_strnstr.c \ ft_strrchr.c \ ft_strtrim.c \ diff --git a/lib/libft/ft_isspace.c b/lib/libft/ft_isspace.c new file mode 100644 index 0000000..63f21fa --- /dev/null +++ b/lib/libft/ft_isspace.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isspace.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/11 13:59:45 by chuhlig #+# #+# */ +/* Updated: 2024/08/11 14:04:23 by chuhlig ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_isspace(char c) +{ + if (c == ' ' || c == '\t') + return (1); + return (0); +} diff --git a/lib/libft/ft_memset.c b/lib/libft/ft_memset.c index 58c5e1e..085df1d 100644 --- a/lib/libft/ft_memset.c +++ b/lib/libft/ft_memset.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* ft_memset.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/05 09:58:19 by dkaiser #+# #+# */ -/* Updated: 2024/03/10 13:13:09 by dkaiser ### ########.fr */ +/* Updated: 2024/07/11 23:52:13 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,3 +35,13 @@ void *ft_memset(void *b, int c, size_t len) /* printf("ft_memset: %s\n", ft_memset((char *)str, 'A' + 255, 5)); */ /* printf("memset: %s\n", memset((char *)str, 'A' + 255, 5)); */ /* } */ + +// void *ft_memset(void *b, int c, size_t len) +// { +// void *savearg; + +// savearg = b; +// while (len--) +// *(unsigned char *)b++ = (unsigned char)c; +// return (savearg); +// }
\ No newline at end of file diff --git a/lib/libft/ft_strncpy.c b/lib/libft/ft_strncpy.c new file mode 100644 index 0000000..a1a2293 --- /dev/null +++ b/lib/libft/ft_strncpy.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strncpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/05 13:41:47 by chuhlig #+# #+# */ +/* Updated: 2024/08/09 15:26:40 by chuhlig ### ########.fr */ +/* */ +/* ************************************************************************** */ + +char *ft_strncpy(char *s1, char *s2, int n) +{ + int i; + + i = -1; + while (++i < n && s2[i]) + s1[i] = s2[i]; + return (s1); +} diff --git a/lib/libft/libft.h b/lib/libft/libft.h index 2de723b..abb739d 100644 --- a/lib/libft/libft.h +++ b/lib/libft/libft.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* libft.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/10 16:37:54 by dkaiser #+# #+# */ -/* Updated: 2024/06/24 16:44:44 by dkaiser ### ########.fr */ +/* Updated: 2024/08/11 14:01:57 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,6 +24,7 @@ int ft_isalpha(int c); int ft_isdigit(int c); int ft_isalnum(int c); int ft_isprint(int c); +int ft_isspace(char c); int ft_isascii(int c); int ft_strlen(const char *str); void *ft_memset(void *b, int c, size_t len); @@ -57,6 +58,7 @@ void ft_putchar_fd(char c, int fd); void ft_putstr_fd(char *s, int fd); void ft_putendl_fd(char *s, int fd); void ft_putnbr_fd(int n, int fd); +char *ft_strncpy(char *s1, char *s2, int n); typedef struct s_list { diff --git a/src/collect_redirs.c b/src/collect_redirs.c new file mode 100644 index 0000000..9ac1605 --- /dev/null +++ b/src/collect_redirs.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* collect_redirs.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/02 13:49:31 by dkaiser #+# #+# */ +/* Updated: 2024/09/17 19:48:48 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static t_token *collect_redir(t_token **tokens, t_redirection *result, + t_token *cur); +static void collect_and_check_redir(t_token **tokens, t_redirection *result, + t_token **cur); +static void set_redir(t_redirection *redir, int type, char *specifier); +static int is_output_redir(int i); + +t_redirection *collect_redirs(t_token **tokens) +{ + t_redirection *result; + t_token *cur; + + cur = *tokens; + result = malloc(sizeof(t_redirection) * 2); + if (result == NULL) + return (free_tokens(*tokens), NULL); + set_redir(&result[0], 0, NULL); + set_redir(&result[1], 0, NULL); + while (cur != NULL && cur->next != NULL) + { + if (cur->type == REDIR_TOKEN && cur->next->type == STRING_TOKEN) + collect_and_check_redir(tokens, result, &cur); + else if (cur->type == REDIR_TOKEN) + return (free(result), NULL); + else + cur = cur->next; + } + if (cur && cur->type == REDIR_TOKEN) + return (free(result), NULL); + return (result); +} + +static void collect_and_check_redir(t_token **tokens, t_redirection *result, + t_token **cur) +{ + int is_redir_only; + + is_redir_only = 0; + if ((*cur)->previous == NULL && (*cur)->next->next == NULL) + is_redir_only = 1; + *cur = collect_redir(tokens, result, *cur); + if (is_redir_only) + *tokens = NULL; +} + +static t_token *collect_redir(t_token **tokens, t_redirection *result, + t_token *cur) +{ + set_redir(&result[is_output_redir(cur->content.redir_type)], + cur->content.redir_type, cur->next->content.string); + cur = cur->next; + free_token_and_connect(cur->previous); + if (cur->next != NULL) + { + if (cur->previous == NULL) + *tokens = cur->next; + cur = cur->next; + free_token_and_connect(cur->previous); + } + else + { + free_token(cur); + return (NULL); + } + return (cur); +} + +static void set_redir(t_redirection *redir, int type, char *specifier) +{ + redir->type = type; + redir->specifier = specifier; +} + +static int is_output_redir(int i) +{ + if (i & (INPUT_FILE | INPUT_LIMITER)) + return (0); + else if (i & (OUTPUT_APPEND | OUTPUT_OVERRIDE)) + return (1); + else + { + panic(UNREACHABLE); + return (-1); + } +} diff --git a/src/free_node.c b/src/free_node.c index 8f32c12..6eae059 100644 --- a/src/free_node.c +++ b/src/free_node.c @@ -6,21 +6,18 @@ /* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 11:41:46 by dkaiser #+# #+# */ -/* Updated: 2024/06/28 14:55:50 by dkaiser ### ########.fr */ +/* Updated: 2024/08/11 12:26:20 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ #include "ast.h" -static void free_assign_node(t_node *node); static void free_pipe_node(t_node *node); static void free_cmd_node(t_node *node); void free_node(t_node *node) { - if (node->type == ASSIGN_NODE) - free_assign_node(node); - else if (node->type == PIPE_NODE) + if (node->type == PIPE_NODE) free_pipe_node(node); else if (node->type == CMD_NODE) free_cmd_node(node); @@ -31,12 +28,6 @@ void free_node(t_node *node) free(node); } -static void free_assign_node(t_node *node) -{ - free(node->content.assign.var); - free(node->content.assign.value); -} - static void free_pipe_node(t_node *node) { free_node(node->content.pipe.left); @@ -48,12 +39,16 @@ static void free_cmd_node(t_node *node) int i; i = 0; - while (node->content.cmd.args[i] != NULL) + while (node->content.cmd.args != NULL && node->content.cmd.args[i] != NULL) { free(node->content.cmd.args[i]); i++; } free(node->content.cmd.args); - free(node->content.cmd.redirs[0].specifier); - free(node->content.cmd.redirs[1].specifier); + if (node->content.cmd.redirs[0].type != 0 + && node->content.cmd.redirs[0].specifier != NULL) + free(node->content.cmd.redirs[0].specifier); + if (node->content.cmd.redirs[1].type != 0 + && node->content.cmd.redirs[0].specifier != NULL) + free(node->content.cmd.redirs[1].specifier); } diff --git a/src/free_token.c b/src/free_token.c index 9f5c4e9..9b035ac 100644 --- a/src/free_token.c +++ b/src/free_token.c @@ -6,7 +6,7 @@ /* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 14:38:57 by dkaiser #+# #+# */ -/* Updated: 2024/06/28 14:55:12 by dkaiser ### ########.fr */ +/* Updated: 2024/08/02 14:23:56 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,11 +14,28 @@ void free_token(t_token *token) { - if (token->type == STRING_TOKEN) - free(token->content.string); if (token->previous != NULL) token->previous->next = NULL; if (token->next != NULL) token->next->previous = NULL; free(token); } + +void free_token_and_connect(t_token *token) +{ + if (token->previous != NULL) + token->previous->next = token->next; + if (token->next != NULL) + token->next->previous = token->previous; + free(token); +} + +void free_tokens(t_token *tokens) +{ + while (tokens->next != NULL) + { + tokens = tokens->next; + free_token(tokens->previous); + } + free_token(tokens); +} @@ -3,14 +3,14 @@ /* ::: :::::::: */ /* main.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/22 17:14:03 by dkaiser #+# #+# */ -/* Updated: 2024/06/25 13:58:24 by dkaiser ### ########.fr */ +/* Updated: 2024/07/18 16:44:14 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ -#include "minishell.h" +#include "../include/minishell.h" int main(void) { diff --git a/src/new_node.c b/src/new_node.c index 4cdbf9a..c58d291 100644 --- a/src/new_node.c +++ b/src/new_node.c @@ -6,7 +6,7 @@ /* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 11:21:03 by dkaiser #+# #+# */ -/* Updated: 2024/06/28 15:04:15 by dkaiser ### ########.fr */ +/* Updated: 2024/09/17 18:46:35 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,22 +23,12 @@ t_node *new_node(int type) return (node); } -t_node *new_assign_node(char *var, char *value) -{ - t_node *node; - - node = new_node(ASSIGN_NODE); - if (node == NULL) - return (NULL); - node->content.assign.var = var; - node->content.assign.value = value; - return (node); -} - t_node *new_pipe_node(t_node *left, t_node *right) { t_node *node; + if (left == NULL || right == NULL) + return (NULL); node = new_node(PIPE_NODE); if (node == NULL) return (NULL); @@ -55,9 +45,14 @@ t_node *new_cmd_node(char **args, t_redirection redirs[2]) if (node == NULL) return (NULL); node->content.cmd.args = args; - node->content.cmd.redirs[0] = redirs[0]; - node->content.cmd.redirs[1] = redirs[1]; - return (node); + if (redirs != NULL) + { + node->content.cmd.redirs[0] = redirs[0]; + node->content.cmd.redirs[1] = redirs[1]; + free(redirs); + return (node); + } + return (NULL); } t_node *new_string_node(char *string) diff --git a/src/parse_cmd.c b/src/parse_cmd.c new file mode 100644 index 0000000..2755cae --- /dev/null +++ b/src/parse_cmd.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/08 15:06:25 by dkaiser #+# #+# */ +/* Updated: 2024/08/11 12:20:06 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static char **collect_args(t_token **tokens); + +t_node *parse_cmd(t_token *tokens) +{ + char **args; + t_redirection *redirs; + + redirs = collect_redirs(&tokens); + args = collect_args(&tokens); + return (new_cmd_node(args, redirs)); +} + +static char **collect_args(t_token **tokens) +{ + t_token *cur; + char **result; + int i; + + cur = *tokens; + i = 0; + while (cur != NULL && ++i) + cur = cur->next; + result = malloc(sizeof(char *) * (i + 1)); + if (result == NULL) + return (free_tokens(*tokens), NULL); + cur = *tokens; + i = 0; + while (cur != NULL && cur->type == STRING_TOKEN) + { + if (cur->previous) + free_token(cur->previous); + result[i] = cur->content.string; + i++; + cur = cur->next; + } + result[i] = NULL; + return (result); +} diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..06c1df7 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/29 15:53:29 by dkaiser #+# #+# */ +/* Updated: 2024/09/17 19:03:48 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "minishell.h" +#include "token.h" + +static t_token *find_token_by_type(t_token *tokens, int type); +t_token *split_at_first(t_token **tokens, int type); +static t_node *parse_statement(t_token *tokens); + +t_list *parse(t_token *tokens) +{ + t_node *result; + + if ((*tokens).type == PIPE_TOKEN) + result = NULL; + else + result = parse_statement(tokens); + if (result == NULL) + printf("Parsing error.\n"); + return (ft_lstnew(result)); +} + +static t_node *parse_statement(t_token *tokens) +{ + t_token *left_side_tokens; + + left_side_tokens = split_at_first(&tokens, PIPE_TOKEN); + if (left_side_tokens == NULL) + { + free_tokens(tokens); + return (NULL); + } + else if (tokens != NULL) + { + return (new_pipe_node(parse_cmd(left_side_tokens), + parse_statement(tokens))); + } + else + { + return (parse_cmd(left_side_tokens)); + } +} + +t_token *split_at_first(t_token **tokens, int type) +{ + t_token *split; + t_token *result; + + split = find_token_by_type(*tokens, type); + if (split == NULL) + { + result = *tokens; + *tokens = NULL; + return (result); + } + result = *tokens; + *tokens = split->next; + if (result == split) + result = NULL; + free_token(split); + return (result); +} + +static t_token *find_token_by_type(t_token *tokens, int type) +{ + while (tokens != NULL) + { + if (tokens->type == type) + return (tokens); + tokens = tokens->next; + } + return (NULL); +} diff --git a/src/print_ast.c b/src/print_ast.c new file mode 100644 index 0000000..d42a67d --- /dev/null +++ b/src/print_ast.c @@ -0,0 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* print_ast.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/22 15:16:53 by dkaiser #+# #+# */ +/* Updated: 2024/09/17 15:09:04 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void print_ast_rec(t_node *ast, int indent); +static void print_cmd_node(t_node *ast, int indent); + +void print_ast(t_node *ast) +{ + if (DEBUG) + { + printf("\e[94m[AST]\n"); + print_ast_rec(ast, 0); + printf("\e[0m\n"); + } +} + +static void print_ast_rec(t_node *ast, int indent) +{ + if (!ast) + panic("Can't print AST!"); + else if (ast->type == CMD_NODE) + print_cmd_node(ast, indent); + else if (ast->type == PIPE_NODE) + { + printf("\n%*s%s", indent, "", "* PIPE"); + print_ast_rec(ast->content.pipe.left, indent + 2); + print_ast_rec(ast->content.pipe.right, indent + 2); + } +} + +static void print_cmd_node(t_node *ast, int indent) +{ + int i; + + printf("\n%*s%s", indent, "", "* CMD"); + i = 0; + printf("\n%*sARGS:", indent + 2, ""); + while (ast->content.cmd.args != NULL && ast->content.cmd.args[i] != NULL) + { + printf(" '%s'", ast->content.cmd.args[i]); + i++; + } + printf("\n%*sREDIRS:", indent + 2, ""); + printf("\n%*sIN: %d %s", indent + 4, "", ast->content.cmd.redirs[0].type, + ast->content.cmd.redirs[0].specifier); + printf("\n%*sOUT: %d %s", indent + 4, "", ast->content.cmd.redirs[1].type, + ast->content.cmd.redirs[1].specifier); +} @@ -3,25 +3,35 @@ /* ::: :::::::: */ /* repl.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 16:07:04 by dkaiser #+# #+# */ -/* Updated: 2024/06/25 15:03:00 by dkaiser ### ########.fr */ +/* Updated: 2024/09/13 16:26:35 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ -#include "minishell.h" +#include "../include/minishell.h" +#include "token.h" void repl(const char *prompt) { char *input; + t_token *token_list; + t_list *lines; while (1) { input = readline(prompt); if (input == NULL) return ; + if (input[0] == '\0') + continue ; add_history(input); + token_list = NULL; + tokenizer(input, &token_list, '\0'); + lines = parse(token_list); + if (lines) + print_ast(lines->content); free(input); } } diff --git a/src/tokenizer.c b/src/tokenizer.c new file mode 100644 index 0000000..ab8a6ac --- /dev/null +++ b/src/tokenizer.c @@ -0,0 +1,116 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tokenizer.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/28 20:55:50 by chuhlig #+# #+# */ +/* Updated: 2024/08/29 15:26:55 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include "token.h" + +void print_token(t_token *token) +{ + if (DEBUG) + { + if (token->type == STRING_TOKEN) + { + printf("STRING_TOKEN: %s\n", token->content.string); + } + else if (token->type == REDIR_TOKEN) + { + printf("REDIR_TOKEN: %d\n", token->content.redir_type); + } + else if (token->type == PIPE_TOKEN) + { + printf("PIPE_TOKEN\n"); + } + else if (token->type == NEWLINE_TOKEN) + { + printf("NEWLINE_TOKEN\n"); + } + } +} + +void snap_string_token(char *string, int start_of_string, int i, + t_token **token_list) +{ + char *line; + int len; + + len = i - start_of_string + 1; + if (len > 0) + { + line = (char *)malloc(len + 1); + if (!line) + { + exit(EXIT_FAILURE); + } + ft_strncpy(line, string + start_of_string, len); + line[len] = '\0'; + while (*line == ' ' || *line == '\t') + line++; + if (*line != '\0') + { + *token_list = new_str_token(line, *token_list, NULL); + print_token(*token_list); + } + } +} + +void handle_special_chars(char *s, int *i, int *start, t_token **token_list) +{ + snap_string_token(s, *start, *i - 1, token_list); + if (s[*i] == '<' && s[*i + 1] == '<') + *token_list = new_redir_token(INPUT_LIMITER, *token_list, NULL); + else if (s[*i] == '>' && s[*i + 1] == '>') + *token_list = new_redir_token(OUTPUT_APPEND, *token_list, NULL); + else if (s[*i] == '<') + *token_list = new_redir_token(INPUT_FILE, *token_list, NULL); + else if (s[*i] == '>') + *token_list = new_redir_token(OUTPUT_OVERRIDE, *token_list, NULL); + else if (s[*i] == '|') + *token_list = new_token(PIPE_TOKEN, *token_list, NULL); + else if (s[*i] == '\n') + *token_list = new_token(NEWLINE_TOKEN, *token_list, NULL); + print_token(*token_list); + if (s[*i] == '<' && s[*i + 1] == '<') + (*i)++; + if (s[*i] == '>' && s[*i + 1] == '>') + (*i)++; + *start = *i + 1; +} + +void tokenizer(char *s, t_token **token_list, char quote_check) +{ + int pos; + int i; + int f; + + pos = 0; + i = -1; + f = 0; + while (s[++i]) + { + if (!f && ft_strchr("|<>\n", s[i])) + handle_special_chars(s, &i, &pos, token_list); + else if (f && s[i] == quote_check) + f = 0; + else if (!f && ft_strchr("\'\"", s[i])) + { + f = 1; + quote_check = s[i]; + } + if ((!f && (ft_isspace(s[i + 1]))) || i == ft_strlen(s) - 1) + { + snap_string_token(s, pos, i, token_list); + pos = i + 1; + } + } + while ((*token_list)->previous) + *token_list = (*token_list)->previous; +} |
