From bce0f37b8e25284bd25683d2ae132cfef37489a9 Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Fri, 18 Nov 2016 23:16:32 +0100 Subject: [PATCH] major stuff today: wrote a proper lexer based on finite state machines, quoting OK. next is finishing the parser, and history of line editing module --- 42sh/Makefile | 9 +- 42sh/includes/exec.h | 4 +- 42sh/includes/lexer.h | 86 +++++++++++++++++++ 42sh/includes/line_editing.h | 17 +--- 42sh/includes/minishell.h | 31 ++++++- 42sh/includes/{lexer_parser.h => parser.h} | 52 +++-------- 42sh/includes/quote.h | 16 ---- 42sh/libft | 2 +- 42sh/src/lexer-parser/token_next.c | 0 .../src/{lexer-parser => lexer}/ft_tokenize.c | 55 +++++++++--- 42sh/src/lexer/lexer_backslash.c | 11 +++ 42sh/src/lexer/lexer_default.c | 18 ++++ 42sh/src/lexer/lexer_delim.c | 14 +++ 42sh/src/lexer/lexer_dquote.c | 19 ++++ 42sh/src/lexer/lexer_great.c | 24 ++++++ 42sh/src/lexer/lexer_greatand.c | 20 +++++ 42sh/src/lexer/lexer_less.c | 25 ++++++ 42sh/src/lexer/lexer_lessand.c | 20 +++++ 42sh/src/lexer/lexer_number.c | 24 ++++++ 42sh/src/lexer/lexer_quote.c | 13 +++ 42sh/src/lexer/lexer_sep.c | 21 +++++ 42sh/src/lexer/lexer_word.c | 15 ++++ .../{lexer-parser => lexer}/token_append.c | 2 +- .../{lexer-parser => lexer}/token_cmp_type.c | 2 +- 42sh/src/{lexer-parser => lexer}/token_free.c | 2 +- .../{lexer-parser => lexer}/token_getnext.c | 4 +- 42sh/src/{lexer-parser => lexer}/token_init.c | 2 +- .../src/{lexer-parser => lexer}/token_print.c | 2 +- 42sh/src/line-editing/ft_interactive_sh.c | 3 +- 42sh/src/line-editing/ft_key_default.c | 2 +- 42sh/src/line-editing/ft_key_del.c | 3 +- 42sh/src/line-editing/ft_key_enter.c | 14 +-- 42sh/src/line-editing/ft_set_termios.c | 2 +- 42sh/src/main/main.c | 20 ++--- 42sh/src/main/qstate_update.c | 35 ++++++++ 42sh/src/{lexer-parser => parser}/ft_parse.c | 2 +- .../{lexer-parser => parser}/parse_dgreat.c | 2 +- .../{lexer-parser => parser}/parse_dless.c | 2 +- .../{lexer-parser => parser}/parse_great.c | 2 +- .../{lexer-parser => parser}/parse_greatand.c | 2 +- .../src/{lexer-parser => parser}/parse_less.c | 2 +- .../{lexer-parser => parser}/parse_lessand.c | 2 +- .../parse_separator.c | 2 +- .../src/{lexer-parser => parser}/parse_word.c | 2 +- 42sh/src/{lexer-parser => parser}/tree_type.c | 2 +- 42sh/src/quote/quote_update.c | 24 ------ 46 files changed, 477 insertions(+), 156 deletions(-) create mode 100644 42sh/includes/lexer.h rename 42sh/includes/{lexer_parser.h => parser.h} (69%) delete mode 100644 42sh/includes/quote.h delete mode 100644 42sh/src/lexer-parser/token_next.c rename 42sh/src/{lexer-parser => lexer}/ft_tokenize.c (57%) create mode 100644 42sh/src/lexer/lexer_backslash.c create mode 100644 42sh/src/lexer/lexer_default.c create mode 100644 42sh/src/lexer/lexer_delim.c create mode 100644 42sh/src/lexer/lexer_dquote.c create mode 100644 42sh/src/lexer/lexer_great.c create mode 100644 42sh/src/lexer/lexer_greatand.c create mode 100644 42sh/src/lexer/lexer_less.c create mode 100644 42sh/src/lexer/lexer_lessand.c create mode 100644 42sh/src/lexer/lexer_number.c create mode 100644 42sh/src/lexer/lexer_quote.c create mode 100644 42sh/src/lexer/lexer_sep.c create mode 100644 42sh/src/lexer/lexer_word.c rename 42sh/src/{lexer-parser => lexer}/token_append.c (97%) rename 42sh/src/{lexer-parser => lexer}/token_cmp_type.c (73%) rename 42sh/src/{lexer-parser => lexer}/token_free.c (83%) rename 42sh/src/{lexer-parser => lexer}/token_getnext.c (94%) rename 42sh/src/{lexer-parser => lexer}/token_init.c (97%) rename 42sh/src/{lexer-parser => lexer}/token_print.c (87%) create mode 100644 42sh/src/main/qstate_update.c rename 42sh/src/{lexer-parser => parser}/ft_parse.c (98%) rename 42sh/src/{lexer-parser => parser}/parse_dgreat.c (98%) rename 42sh/src/{lexer-parser => parser}/parse_dless.c (98%) rename 42sh/src/{lexer-parser => parser}/parse_great.c (98%) rename 42sh/src/{lexer-parser => parser}/parse_greatand.c (98%) rename 42sh/src/{lexer-parser => parser}/parse_less.c (98%) rename 42sh/src/{lexer-parser => parser}/parse_lessand.c (98%) rename 42sh/src/{lexer-parser => parser}/parse_separator.c (89%) rename 42sh/src/{lexer-parser => parser}/parse_word.c (97%) rename 42sh/src/{lexer-parser => parser}/tree_type.c (97%) delete mode 100644 42sh/src/quote/quote_update.c diff --git a/42sh/Makefile b/42sh/Makefile index 14073819..4afe0b9c 100644 --- a/42sh/Makefile +++ b/42sh/Makefile @@ -25,7 +25,7 @@ D_FLAGS = MKDIR = mkdir -p RM = /bin/rm -rf -.PHONY: all clean fclean re tags test +.PHONY: all clean fclean re libft all: $(NAME) @@ -52,7 +52,12 @@ $(D_OBJ)/%.o: $(D_SRC)/line-editing/%.c includes/line_editing.h @$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS) @echo "Compiling "$<"..." -$(D_OBJ)/%.o: $(D_SRC)/lexer-parser/%.c includes/lexer_parser.h +$(D_OBJ)/%.o: $(D_SRC)/lexer/%.c includes/lexer.h + @$(MKDIR) $(D_OBJ) + @$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS) + @echo "Compiling "$<"..." + +$(D_OBJ)/%.o: $(D_SRC)/parser/%.c includes/parser.h @$(MKDIR) $(D_OBJ) @$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS) @echo "Compiling "$<"..." diff --git a/42sh/includes/exec.h b/42sh/includes/exec.h index 1353830c..dbfedeb0 100644 --- a/42sh/includes/exec.h +++ b/42sh/includes/exec.h @@ -1,7 +1,9 @@ #ifndef EXEC_H # define EXEC_H -# include "lexer_parser.h" +# include "minishell.h" + +typedef long long t_type; typedef struct s_exec t_exec; struct s_exec diff --git a/42sh/includes/lexer.h b/42sh/includes/lexer.h new file mode 100644 index 00000000..0ecbc7d9 --- /dev/null +++ b/42sh/includes/lexer.h @@ -0,0 +1,86 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/10 15:31:42 by jhalford #+# #+# */ +/* Updated: 2016/11/14 18:22:04 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LEXER_H +# define LEXER_H + +# include "minishell.h" + +# define TK_LESS 0x0001 +# define TK_GREAT 0x0002 +# define TK_DLESS 0x0004 +# define TK_DGREAT 0x0008 +# define TK_LESSAND 0x0010 +# define TK_GREATAND 0x0020 +# define TK_SEMI 0x0040 +# define TK_PIPE 0x0080 +# define TK_WORD 0x0100 +# define TK_COMMAND 0x0200 + +# define TK_REDIR 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 + +typedef long long t_type; +typedef enum e_lexstate t_lexstate; +typedef struct s_token t_token; +typedef int t_lexer(t_list **alst, + char *str); + +enum e_lexstate +{ + DEFAULT, + DELIM, + SEP, + WORD, + NUMBER, + GREAT, + LESS, + GREATAND, + LESSAND, + QUOTE, + DQUOTE, + BACKSLASH, +}; + +struct s_token +{ + t_type type; + char *data; + int size; +}; + +extern t_lexer *g_lexer[]; + +/* t_token *token_getnext(int *pos,char *line); */ +t_token *token_init(); +int ft_tokenize(t_list **alst, char *str, t_lexstate state); +int token_append(t_token *token, char c); +void token_free(void *data, size_t size); +int token_cmp_type(t_type data, t_type ref); +void token_print(t_list *lst); + +int ft_is_delim(char c); + +t_lexer lexer_default; +t_lexer lexer_delim; +t_lexer lexer_sep; +t_lexer lexer_word; +t_lexer lexer_number; +t_lexer lexer_greatand; +t_lexer lexer_lessand; +t_lexer lexer_quote; +t_lexer lexer_dquote; +t_lexer lexer_backslash; + +t_lexer lexer_less; +t_lexer lexer_great; + +#endif diff --git a/42sh/includes/line_editing.h b/42sh/includes/line_editing.h index 463a7eed..8ddd3bdc 100644 --- a/42sh/includes/line_editing.h +++ b/42sh/includes/line_editing.h @@ -13,7 +13,7 @@ #ifndef LINE_EDITING_H # define LINE_EDITING_H -# include "libft.h" +# include "minishell.h" # include # include @@ -45,26 +45,11 @@ typedef struct s_data t_data; -struct s_data -{ - char **env; - t_dlist *history; - t_dlist *input_mem; - - char *input; - int input_pos; - t_quote state_now; - t_quote state_last; - char quoted; - char backslash; -}; - extern t_stof g_keys[]; int ft_set_termios(t_data *data, int input_mode); int ft_interactive_sh(t_data *data); int ft_prompt(void); -int ft_input_is_escaped(t_dlist *input_chain); int ft_history_add(t_data *data); typedef int key_press(t_data *data, char *buf); diff --git a/42sh/includes/minishell.h b/42sh/includes/minishell.h index 55c4ed72..c3e0616c 100644 --- a/42sh/includes/minishell.h +++ b/42sh/includes/minishell.h @@ -14,20 +14,47 @@ # define MINISHELL_H # include "libft.h" + # include "line_editing.h" -# include "lexer_parser.h" +# include "lexer.h" +# include "parser.h" # include "exec.h" + # include # include # include # include +typedef enum e_qstate t_qstate; +typedef struct s_data t_data; + +enum e_qstate +{ + Q_NONE, + Q_QUOTE, + Q_DQUOTE, + Q_BACKSLASH, +}; + +struct s_data +{ + char **env; + t_dlist *history; + + char *input; + int input_pos; + t_qstate state_now; + t_qstate state_last; +}; + extern t_stof g_builtins[]; extern pid_t g_pid; void sig_handler(int signo); int data_init(t_data *data); +void qstate_update(t_data *data, char c); + int ft_cmd_process(char **argv, char ***env_p); int ft_cmd_exec(char *execpath, char **argv, char ***env_p); char **ft_cmd_getav(char *cmd); @@ -44,6 +71,4 @@ void ft_expand_dollar(char **av, char **env); char *ft_findexec(char **path, char *file); -int ft_tokenize(t_list **alst, char *str); - #endif diff --git a/42sh/includes/lexer_parser.h b/42sh/includes/parser.h similarity index 69% rename from 42sh/includes/lexer_parser.h rename to 42sh/includes/parser.h index 168bf89e..576ae7e8 100644 --- a/42sh/includes/lexer_parser.h +++ b/42sh/includes/parser.h @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* token.h :+: :+: :+: */ +/* parser.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -10,30 +10,22 @@ /* */ /* ************************************************************************** */ -#ifndef TOKEN_H -# define TOKEN_H +#ifndef PARSER_H +# define PARSER_H -# include "libft.h" - -# define TK_LESS 0x0001 -# define TK_GREAT 0x0002 -# define TK_DLESS 0x0004 -# define TK_DGREAT 0x0008 -# define TK_LESSAND 0x0010 -# define TK_GREATAND 0x0020 -# define TK_SEMI 0x0040 -# define TK_PIPE 0x0080 -# define TK_WORD 0x0100 -# define TK_COMMAND 0x0200 - -# define TK_REDIR 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 +# include "minishell.h" typedef long long t_type; -typedef struct s_token t_token; typedef struct s_parser t_parser; typedef struct s_astnode t_astnode; typedef struct s_redir t_redir; +struct s_parser +{ + t_type type; + int (*f)(t_btree **ast, t_list *start, t_list *token); +}; + struct s_redir { int n; @@ -41,20 +33,7 @@ struct s_redir { char *word; int fd; - } u_word; -}; - -struct s_token -{ - t_type type; - char *data; - int size; -}; - -struct s_parser -{ - t_type type; - int (*f)(t_btree **ast, t_list *start, t_list *token); + } word; }; struct s_astnode @@ -69,14 +48,6 @@ struct s_astnode extern t_parser g_parser[]; -t_token *token_init(); -t_token *token_getnext(int *pos,char *line); -int ft_tokenize(t_list **alst, char *str); -int token_append(t_token *token, char c); -void token_free(void *data, size_t size); -int token_cmp_type(t_type data, t_type ref); -void token_print(t_list *lst); - int ft_parse(t_btree **ast, t_list *token); int parse_separator(t_btree **ast, t_list *start, t_list *lst); int parse_less(t_btree **ast, t_list *start, t_list *lst); @@ -88,4 +59,5 @@ int parse_greatand(t_btree **ast, t_list *start, t_list *lst); int parse_word(t_btree **ast, t_list *start, t_list *lst); void tree_type(t_btree *tree); + #endif diff --git a/42sh/includes/quote.h b/42sh/includes/quote.h deleted file mode 100644 index 91d62be9..00000000 --- a/42sh/includes/quote.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef LINE_EDITING_H -# define LINE_EDITING_H - -typedef enum e_quote t_quote; - -enum e_quote -{ - NONE, - QUOTE, - DQUOTE, - BACKSLASH, -}; - -void quote_update(t_data *data, char c); - -#endif diff --git a/42sh/libft b/42sh/libft index 202926ba..3741ee4a 160000 --- a/42sh/libft +++ b/42sh/libft @@ -1 +1 @@ -Subproject commit 202926ba40a54535c54650272db67a60a9598e1d +Subproject commit 3741ee4abd2986790543bb1877371570da39a435 diff --git a/42sh/src/lexer-parser/token_next.c b/42sh/src/lexer-parser/token_next.c deleted file mode 100644 index e69de29b..00000000 diff --git a/42sh/src/lexer-parser/ft_tokenize.c b/42sh/src/lexer/ft_tokenize.c similarity index 57% rename from 42sh/src/lexer-parser/ft_tokenize.c rename to 42sh/src/lexer/ft_tokenize.c index acd22aae..24f27ff3 100644 --- a/42sh/src/lexer-parser/ft_tokenize.c +++ b/42sh/src/lexer/ft_tokenize.c @@ -10,22 +10,53 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "lexer.h" -int ft_tokenize(t_list **alst, char *str) +t_lexer *g_lexer[] = +{ + &lexer_default, + &lexer_delim, + &lexer_sep, + &lexer_word, + &lexer_number, + &lexer_great, + &lexer_less, + &lexer_greatand, + &lexer_lessand, + &lexer_quote, + &lexer_dquote, + &lexer_backslash, +}; + +int ft_is_delim(char c) +{ + return (c == ' ' || c == '\t' || c == '\n'); +} + +int ft_tokenize(t_list **alst, char *str, t_lexstate state) { t_token *token; - char *cmd; - int pos; - pos = 0; - cmd = ft_strdup(str); - while ((token = token_getnext(&pos, cmd))) - { + if (!*str) + return (0); + token = token_init(); + if (!*alst) *alst = ft_lstnew(token, sizeof(*token)); - alst = &(*alst)->next; - free(token); + if (ft_is_delim(*str)) + state = DELIM; + if (*str == ';' || *str == '|') + state = SEP; + else if (*str == '\'') + { + state = QUOTE; + str++; } - ft_strdel(&cmd); - return (0); + else if (*str == '\"') + { + state = DQUOTE; + str++; + } + else if (*str == '\\') + state = BACKSLASH; + return ((*g_lexer[state])(alst, str)); } diff --git a/42sh/src/lexer/lexer_backslash.c b/42sh/src/lexer/lexer_backslash.c new file mode 100644 index 00000000..85b837c4 --- /dev/null +++ b/42sh/src/lexer/lexer_backslash.c @@ -0,0 +1,11 @@ +#include "lexer.h" + +int lexer_backslash(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + token->type = TK_WORD; + token_append(token, str[1]); + return (ft_tokenize(alst, str + 2, WORD)); +} diff --git a/42sh/src/lexer/lexer_default.c b/42sh/src/lexer/lexer_default.c new file mode 100644 index 00000000..3c6e0006 --- /dev/null +++ b/42sh/src/lexer/lexer_default.c @@ -0,0 +1,18 @@ +#include "lexer.h" + +int lexer_default(t_list **alst, char *str) +{ + t_lexstate state; + + state = DEFAULT; + if (*str == '>') + state = GREAT; + else if (*str == '<') + state = LESS; + else if (ft_isdigit(*str)) + state = NUMBER; + else + state = WORD; + token_append((*alst)->content ,*str); + return (ft_tokenize(alst, str + 1, state)); +} diff --git a/42sh/src/lexer/lexer_delim.c b/42sh/src/lexer/lexer_delim.c new file mode 100644 index 00000000..ce046ef5 --- /dev/null +++ b/42sh/src/lexer/lexer_delim.c @@ -0,0 +1,14 @@ +#include "lexer.h" + +int lexer_delim(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + while (ft_is_delim(*str)) + str++; + if (*token->data) + return (ft_tokenize(&(*alst)->next, str, DEFAULT)); + else + return (ft_tokenize(alst, str, DEFAULT)); +} diff --git a/42sh/src/lexer/lexer_dquote.c b/42sh/src/lexer/lexer_dquote.c new file mode 100644 index 00000000..07506b13 --- /dev/null +++ b/42sh/src/lexer/lexer_dquote.c @@ -0,0 +1,19 @@ +#include "lexer.h" + +int lexer_dquote(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + token->type = WORD; + if (*str == '\"') + return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + if (*str == '\\') + { + token_append(token, *str); + token_append(token, *(str + 1)); + return (lexer_dquote(alst, str + 2)); + } + token_append(token, *str); + return (lexer_dquote(alst, str + 1)); +} diff --git a/42sh/src/lexer/lexer_great.c b/42sh/src/lexer/lexer_great.c new file mode 100644 index 00000000..7bab4c4b --- /dev/null +++ b/42sh/src/lexer/lexer_great.c @@ -0,0 +1,24 @@ +#include "lexer.h" + +int lexer_great(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + if (*str == '&') + { + token_append(token, *str); + return (lexer_greatand(alst, str + 1)); + } + else if (*str == '>') + { + token->type = TK_DGREAT; + token_append(token, *str); + return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + } + else + { + token->type = TK_GREAT; + return (ft_tokenize(&(*alst)->next, str, DEFAULT)); + } +} diff --git a/42sh/src/lexer/lexer_greatand.c b/42sh/src/lexer/lexer_greatand.c new file mode 100644 index 00000000..f113b528 --- /dev/null +++ b/42sh/src/lexer/lexer_greatand.c @@ -0,0 +1,20 @@ +#include "lexer.h" + +int lexer_greatand(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + token->type = GREATAND; + if (ft_isdigit(*str)) + { + token_append(token, *str); + return (lexer_greatand(alst, str + 1)); + } + else if (*str == '-') + { + token_append(token, *str); + return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + } + return (ft_tokenize(alst, str, DEFAULT)); +} diff --git a/42sh/src/lexer/lexer_less.c b/42sh/src/lexer/lexer_less.c new file mode 100644 index 00000000..41a23e16 --- /dev/null +++ b/42sh/src/lexer/lexer_less.c @@ -0,0 +1,25 @@ +#include "lexer.h" + +int lexer_less(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + if (*str == '&') + { + token_append(token, *str); + return (lexer_lessand(alst, str + 1)); + } + else if (*str == '<') + { + token->type = TK_DLESS; + token_append(token, *str); + return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + } + else + { + token->type = TK_LESS; + token_append(token, *str); + return (ft_tokenize(alst, str + 1, DEFAULT)); + } +} diff --git a/42sh/src/lexer/lexer_lessand.c b/42sh/src/lexer/lexer_lessand.c new file mode 100644 index 00000000..1db08f40 --- /dev/null +++ b/42sh/src/lexer/lexer_lessand.c @@ -0,0 +1,20 @@ +#include "lexer.h" + +int lexer_lessand(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + token->type = LESSAND; + if (ft_isdigit(*str)) + { + token_append(token, *str); + return (lexer_lessand(alst, str + 1)); + } + else if (*str == '-') + { + token_append(token, *str); + return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + } + return (ft_tokenize(alst, str, DEFAULT)); +} diff --git a/42sh/src/lexer/lexer_number.c b/42sh/src/lexer/lexer_number.c new file mode 100644 index 00000000..7021468b --- /dev/null +++ b/42sh/src/lexer/lexer_number.c @@ -0,0 +1,24 @@ +#include "lexer.h" + +int lexer_number(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + if (*str == '>') + { + token_append(token, *str); + return (lexer_great(alst, str + 1)); + } + else if (*str == '<') + { + token_append(token, *str); + return (lexer_less(alst, str + 1)); + } + else if (ft_isdigit(*str)) + { + token_append(token, *str); + return (lexer_number(alst, str + 1)); + } + return (ft_tokenize(alst, str, DEFAULT)); +} diff --git a/42sh/src/lexer/lexer_quote.c b/42sh/src/lexer/lexer_quote.c new file mode 100644 index 00000000..8c9d1bc4 --- /dev/null +++ b/42sh/src/lexer/lexer_quote.c @@ -0,0 +1,13 @@ +#include "lexer.h" + +int lexer_quote(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + token->type = TK_WORD; + if (*str == '\'') + return (ft_tokenize(&(*alst)->next, str + 1, WORD)); + token_append(token, *str); + return (lexer_quote(alst, str + 1)); +} diff --git a/42sh/src/lexer/lexer_sep.c b/42sh/src/lexer/lexer_sep.c new file mode 100644 index 00000000..84f59752 --- /dev/null +++ b/42sh/src/lexer/lexer_sep.c @@ -0,0 +1,21 @@ +#include "lexer.h" + +int lexer_sep(t_list **alst, char *str) +{ + t_token *token; + + if (*alst) + { + token = (*alst)->content; + if (*token->data) + return (lexer_sep(&(*alst)->next, str)); + } + else + { + token = token_init(); + *alst = ft_lstnew(token, sizeof(*token)); + } + token->type = *str == ';' ? TK_SEMI : TK_PIPE; + token_append(token, *str); + return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); +} diff --git a/42sh/src/lexer/lexer_word.c b/42sh/src/lexer/lexer_word.c new file mode 100644 index 00000000..bbd35cc8 --- /dev/null +++ b/42sh/src/lexer/lexer_word.c @@ -0,0 +1,15 @@ +#include "lexer.h" + +int lexer_word(t_list **alst, char *str) +{ + t_token *token; + + token = (*alst)->content; + token->type = TK_WORD; + if (*str == '>') + return (ft_tokenize(&(*alst)->next, str, GREAT)); + else if (*str == '<') + return (ft_tokenize(&(*alst)->next, str, LESS)); + token_append(token, *str); + return (ft_tokenize(alst, str + 1, WORD)); +} diff --git a/42sh/src/lexer-parser/token_append.c b/42sh/src/lexer/token_append.c similarity index 97% rename from 42sh/src/lexer-parser/token_append.c rename to 42sh/src/lexer/token_append.c index 082892b4..c08e5c5a 100644 --- a/42sh/src/lexer-parser/token_append.c +++ b/42sh/src/lexer/token_append.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "lexer.h" int token_append(t_token *token, char c) { diff --git a/42sh/src/lexer-parser/token_cmp_type.c b/42sh/src/lexer/token_cmp_type.c similarity index 73% rename from 42sh/src/lexer-parser/token_cmp_type.c rename to 42sh/src/lexer/token_cmp_type.c index e2739738..dec67384 100644 --- a/42sh/src/lexer-parser/token_cmp_type.c +++ b/42sh/src/lexer/token_cmp_type.c @@ -1,4 +1,4 @@ -#include "lexer_parser.h" +#include "lexer.h" int token_cmp_type(t_type data, t_type ref) { diff --git a/42sh/src/lexer-parser/token_free.c b/42sh/src/lexer/token_free.c similarity index 83% rename from 42sh/src/lexer-parser/token_free.c rename to 42sh/src/lexer/token_free.c index 8af65706..58bb294c 100644 --- a/42sh/src/lexer-parser/token_free.c +++ b/42sh/src/lexer/token_free.c @@ -1,4 +1,4 @@ -#include "lexer_parser.h" +#include "lexer.h" void token_free(void *data, size_t size) { diff --git a/42sh/src/lexer-parser/token_getnext.c b/42sh/src/lexer/token_getnext.c similarity index 94% rename from 42sh/src/lexer-parser/token_getnext.c rename to 42sh/src/lexer/token_getnext.c index 1ca30452..8773a754 100644 --- a/42sh/src/lexer-parser/token_getnext.c +++ b/42sh/src/lexer/token_getnext.c @@ -1,8 +1,8 @@ -#include "lexer_parser.h" +#include "lexer.h" static int is_separator(char c) { - return (c==' ' || c=='\t' || c=='\n' || c=='\r'); + return (c==' ' || c=='\t' || c=='\n'); } diff --git a/42sh/src/lexer-parser/token_init.c b/42sh/src/lexer/token_init.c similarity index 97% rename from 42sh/src/lexer-parser/token_init.c rename to 42sh/src/lexer/token_init.c index 2988b9f3..a2a4795b 100644 --- a/42sh/src/lexer-parser/token_init.c +++ b/42sh/src/lexer/token_init.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "lexer.h" t_token *token_init() { diff --git a/42sh/src/lexer-parser/token_print.c b/42sh/src/lexer/token_print.c similarity index 87% rename from 42sh/src/lexer-parser/token_print.c rename to 42sh/src/lexer/token_print.c index 5648a13a..38c16e90 100644 --- a/42sh/src/lexer-parser/token_print.c +++ b/42sh/src/lexer/token_print.c @@ -1,4 +1,4 @@ -#include "lexer_parser.h" +#include "lexer.h" void token_print(t_list *lst) { diff --git a/42sh/src/line-editing/ft_interactive_sh.c b/42sh/src/line-editing/ft_interactive_sh.c index ebb13386..502e8b0e 100644 --- a/42sh/src/line-editing/ft_interactive_sh.c +++ b/42sh/src/line-editing/ft_interactive_sh.c @@ -54,8 +54,7 @@ int ft_interactive_sh(t_data *data) ft_strdel(&data->input); data->input = ft_memalloc(10); data->input_pos = 0; - data->quoting = 0; - data->backslach = 0; + data->state_now = Q_NONE; ft_set_termios(data, 1); ft_prompt(); while (1) diff --git a/42sh/src/line-editing/ft_key_default.c b/42sh/src/line-editing/ft_key_default.c index f429878c..97f37710 100644 --- a/42sh/src/line-editing/ft_key_default.c +++ b/42sh/src/line-editing/ft_key_default.c @@ -21,7 +21,7 @@ int ft_key_default(t_data *data, char *buf) data->input = ft_strinsert(data->input, *buf, data->input_pos); data->input_pos++; ft_strdel(&tmp); - quote_update(data, *buf); + qstate_update(data, *buf); if ((res = tgetstr("IC", NULL))) { tputs(tgoto(res, 0, 0), 1, &ft_putchar); diff --git a/42sh/src/line-editing/ft_key_del.c b/42sh/src/line-editing/ft_key_del.c index 8fd4d81a..9751b075 100644 --- a/42sh/src/line-editing/ft_key_del.c +++ b/42sh/src/line-editing/ft_key_del.c @@ -23,7 +23,8 @@ int ft_key_del(t_data *data, char *buf) return (0); if (data->input[data->input_pos - 1] == '\n') return (0); - ft_strsqueeze(data->input, data->input_pos - 1); + ft_strcpy(data->input + data->input_pos - 1, + data->input + data->input_pos); data->input_pos--; if ((res = tgetstr("le", NULL)) == NULL) { diff --git a/42sh/src/line-editing/ft_key_enter.c b/42sh/src/line-editing/ft_key_enter.c index 2510021f..f1aae9dc 100644 --- a/42sh/src/line-editing/ft_key_enter.c +++ b/42sh/src/line-editing/ft_key_enter.c @@ -15,13 +15,13 @@ int ft_key_enter(t_data *data, char *buf) { (void)buf; - if (data->quoting || data->backslash) + if (data->state_now == Q_NONE) { - ft_key_basic(data, buf); - ft_printf("> "); - return (0); + ft_putchar('\n'); + ft_history_add(data); + return (2); } - ft_putchar('\n'); - ft_history_add(data); - return (2); + ft_key_default(data, buf); + ft_printf("> "); + return (0); } diff --git a/42sh/src/line-editing/ft_set_termios.c b/42sh/src/line-editing/ft_set_termios.c index bf103511..56008f31 100644 --- a/42sh/src/line-editing/ft_set_termios.c +++ b/42sh/src/line-editing/ft_set_termios.c @@ -24,7 +24,7 @@ int ft_set_termios(t_data *data, int input_mode) if (tcgetattr(0, &term) == -1) return (-1); term.c_lflag &= ~(ICANON); // Met le terminal en mode canonique. - if (input_mode == 1) + if (input_mode) term.c_lflag &= ~(ISIG) & ~(ECHO); else term.c_lflag |= ISIG | ECHO; diff --git a/42sh/src/main/main.c b/42sh/src/main/main.c index 20c6bcea..388488e7 100644 --- a/42sh/src/main/main.c +++ b/42sh/src/main/main.c @@ -28,22 +28,18 @@ int main(void) if (ft_interactive_sh(&data)) return (1); ft_printf("got command:'%s'\n", data.input); - /* if (ft_tokenize(&token, data.history->prev->content)) */ - /* return (1); */ - /* token_print(token); */ - /* (void)ast; */ - /* if (ft_parse(&ast, token)) */ - /* return (1); */ - /* btree_print(ast, &tree_type); */ - /* ft_printf("root: %i\n", ((t_astnode*)ast->item)->type); */ - /* ft_lstdel(&token, &token_free); */ + if (ft_tokenize(&token, data.input, DEFAULT)) + return (1); + token_print(token); + if (ft_parse(&ast, token)) + return (1); + btree_print(ast, &tree_type); + ft_printf("root: %i\n", ((t_astnode*)ast->item)->type); + ft_lstdel(&token, &token_free); token = NULL; /* if (ft_exec(ast)) */ /* return (1); */ - /* char **av = ft_cmd_getav(data.history->prev->content); */ - /* if (av && av[0]) */ - /* ft_cmd_process(av, &data.env); */ } return (0); } diff --git a/42sh/src/main/qstate_update.c b/42sh/src/main/qstate_update.c new file mode 100644 index 00000000..6183d427 --- /dev/null +++ b/42sh/src/main/qstate_update.c @@ -0,0 +1,35 @@ +#include "minishell.h" + +void qstate_update(t_data *data, char c) +{ + t_qstate *now; + t_qstate *last; + + now = &data->state_now; + last = &data->state_last; + if (*now == Q_NONE) + { + if (c == '\\') + { + *last = Q_NONE; + *now = Q_BACKSLASH; + } + *now = c == '\'' ? Q_QUOTE : *now; + *now = c == '\"' ? Q_DQUOTE : *now; + } + else if (*now == Q_QUOTE) + *now = c == '\'' ? Q_NONE : *now; + else if (*now == Q_DQUOTE) + { + if (c == '\\') + { + *last = Q_DQUOTE; + *now = Q_BACKSLASH; + } + *now = c == '\"' ? Q_NONE : *now; + } + else if (*now == Q_BACKSLASH) + { + *now = *last; + } +} diff --git a/42sh/src/lexer-parser/ft_parse.c b/42sh/src/parser/ft_parse.c similarity index 98% rename from 42sh/src/lexer-parser/ft_parse.c rename to 42sh/src/parser/ft_parse.c index 2fa7be07..899e9c9b 100644 --- a/42sh/src/lexer-parser/ft_parse.c +++ b/42sh/src/parser/ft_parse.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" t_parser g_parser[] = { diff --git a/42sh/src/lexer-parser/parse_dgreat.c b/42sh/src/parser/parse_dgreat.c similarity index 98% rename from 42sh/src/lexer-parser/parse_dgreat.c rename to 42sh/src/parser/parse_dgreat.c index a49d9e75..952ac606 100644 --- a/42sh/src/lexer-parser/parse_dgreat.c +++ b/42sh/src/parser/parse_dgreat.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" int parse_dgreat(t_btree **ast, t_list *start, t_list *lst) { diff --git a/42sh/src/lexer-parser/parse_dless.c b/42sh/src/parser/parse_dless.c similarity index 98% rename from 42sh/src/lexer-parser/parse_dless.c rename to 42sh/src/parser/parse_dless.c index 75101b28..55709971 100644 --- a/42sh/src/lexer-parser/parse_dless.c +++ b/42sh/src/parser/parse_dless.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" int parse_dless(t_btree **ast, t_list *start, t_list *lst) { diff --git a/42sh/src/lexer-parser/parse_great.c b/42sh/src/parser/parse_great.c similarity index 98% rename from 42sh/src/lexer-parser/parse_great.c rename to 42sh/src/parser/parse_great.c index 30804433..fb98bd05 100644 --- a/42sh/src/lexer-parser/parse_great.c +++ b/42sh/src/parser/parse_great.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" int parse_great(t_btree **ast, t_list *start, t_list *lst) { diff --git a/42sh/src/lexer-parser/parse_greatand.c b/42sh/src/parser/parse_greatand.c similarity index 98% rename from 42sh/src/lexer-parser/parse_greatand.c rename to 42sh/src/parser/parse_greatand.c index 95ff565d..9e87f5c5 100644 --- a/42sh/src/lexer-parser/parse_greatand.c +++ b/42sh/src/parser/parse_greatand.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" int parse_greatand(t_btree **ast, t_list *start, t_list *lst) { diff --git a/42sh/src/lexer-parser/parse_less.c b/42sh/src/parser/parse_less.c similarity index 98% rename from 42sh/src/lexer-parser/parse_less.c rename to 42sh/src/parser/parse_less.c index 205e726c..cdcaf772 100644 --- a/42sh/src/lexer-parser/parse_less.c +++ b/42sh/src/parser/parse_less.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" int parse_less(t_btree **ast, t_list *start, t_list *lst) { diff --git a/42sh/src/lexer-parser/parse_lessand.c b/42sh/src/parser/parse_lessand.c similarity index 98% rename from 42sh/src/lexer-parser/parse_lessand.c rename to 42sh/src/parser/parse_lessand.c index 0714749c..572f4077 100644 --- a/42sh/src/lexer-parser/parse_lessand.c +++ b/42sh/src/parser/parse_lessand.c @@ -11,7 +11,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" int parse_lessand(t_btree **ast, t_list *start, t_list *lst) { diff --git a/42sh/src/lexer-parser/parse_separator.c b/42sh/src/parser/parse_separator.c similarity index 89% rename from 42sh/src/lexer-parser/parse_separator.c rename to 42sh/src/parser/parse_separator.c index c44df7d2..1a2b4a13 100644 --- a/42sh/src/lexer-parser/parse_separator.c +++ b/42sh/src/parser/parse_separator.c @@ -1,4 +1,4 @@ -#include "lexer_parser.h" +#include "parser.h" int parse_separator(t_btree **ast, t_list *start, t_list *lst) { diff --git a/42sh/src/lexer-parser/parse_word.c b/42sh/src/parser/parse_word.c similarity index 97% rename from 42sh/src/lexer-parser/parse_word.c rename to 42sh/src/parser/parse_word.c index 6a44eee6..f6a62c1e 100644 --- a/42sh/src/lexer-parser/parse_word.c +++ b/42sh/src/parser/parse_word.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" int parse_word(t_btree **ast, t_list *start, t_list *lst) { diff --git a/42sh/src/lexer-parser/tree_type.c b/42sh/src/parser/tree_type.c similarity index 97% rename from 42sh/src/lexer-parser/tree_type.c rename to 42sh/src/parser/tree_type.c index 139dd50a..0a1c4d07 100644 --- a/42sh/src/lexer-parser/tree_type.c +++ b/42sh/src/parser/tree_type.c @@ -10,7 +10,7 @@ /* */ /* ************************************************************************** */ -#include "lexer_parser.h" +#include "parser.h" void tree_type(t_btree *tree) { diff --git a/42sh/src/quote/quote_update.c b/42sh/src/quote/quote_update.c deleted file mode 100644 index 8b7b65f5..00000000 --- a/42sh/src/quote/quote_update.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "libft.h" - -void quote_state_update(t_data *data, char c) -{ - t_quote now; - t_quote last; - - now = data->state_now; - last = data->state_last; - if (c == '\\' && now != DQUOTE) - { - if (now == BACKSLASH) - now = last; - else - now = BACKSLASH; - } - if (quote != BACKSLASH) - { - if (c == '\'') - quoted = now == QUOTE ? 0 : '\''; - if (c == '\"' ) - data->quoted = now == DQUOTE ? 0 : '\"'; - } -}