/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* lexer.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: mea +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/02 13:44:57 by narnaud #+# #+# */ /* Updated: 2022/05/12 14:53:06 by mea ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" static int check_state(t_lexer *lex, char **line); static int check_register(t_lexer *lex, char **line, char *tmp); t_token *lexer(t_datas *datas, char *line) { t_lexer *lex; t_token *ret; char *tmp; int tmp_i; lex = ft_calloc(1, sizeof(*lex)); lex->state = ROOT_ST; tmp = ft_calloc(STR_MAX_SIZE, sizeof(*tmp)); tmp_i = 0; while (*line) { if (check_state(lex, &line)) continue ; if (lex->state != S_QUOTE_ST && lex->deep == 0 && *line == '$' && (line[1] != '\0' && !isspace(line[1]))) { tmp_i = replace_var(datas, &line, tmp, tmp_i); lex->empty = 1; } else if (check_register(lex, &line, tmp)) tmp_i = (ft_bzero(tmp, STR_MAX_SIZE), 0); else tmp[tmp_i++] = *(line++); } if (lex->type == WORD && lex->wc) create_wc(lex, tmp); else create_token(lex, tmp); free(tmp); ret = lex->tokens; free(lex); return (ret); } static int check_state(t_lexer *lex, char **line) { t_state new; new = OLD_ST; if (**line == '"' && lex->state == D_QUOTE_ST) new = ROOT_ST; else if (**line == '"' && lex->state == ROOT_ST) new = D_QUOTE_ST; else if (**line == '\'' && lex->state == S_QUOTE_ST) new = ROOT_ST; else if (**line == '\'' && lex->state == ROOT_ST) new = S_QUOTE_ST; else if (**line == '(' && lex->state == ROOT_ST) lex->deep++; else if (**line == ')' && lex->state == ROOT_ST) lex->deep--; else if (**line == '*' && lex->state == ROOT_ST && !lex->deep) lex->wc = 1; if (new) { lex->state = new; if (lex->deep == 0) { (*line)++; return (1); } } return (0); } int create_token(t_lexer *lex, char str[]) { t_token *tok; t_token *tmp; t_type type; type = lex->type; if (lex->next_type) lex->type = lex->next_type; else lex->type = WORD; lex->next_type = WORD; if (!str[0] && !lex->empty) return (0); tok = ft_calloc(1, sizeof(*tok)); tok->type = type; tok->value = ft_strdup(str); tmp = lex->tokens; while (tmp && tmp->next) tmp = tmp->next; if (!tmp) lex->tokens = tok; else tmp->next = tok; lex->empty = 0; return (1); } static int check_ope(t_lexer *lex, char **line, char *tmp) { if (!ft_strncmp(*line, "&&", 2)) { (*line) += 2; lex->next_type = AND; create_token(lex, tmp); return (create_token(lex, "&&")); } if (!ft_strncmp(*line, "||", 2)) { (*line) += 2; lex->next_type = OR; create_token(lex, tmp); return (create_token(lex, "||")); } if (**line == '|') { (*line)++; lex->next_type = PIPE; create_token(lex, tmp); return (create_token(lex, "|")); } return (0); } static int check_register(t_lexer *lex, char **line, char *tmp) { int spaces; if (lex->state != ROOT_ST || lex->deep > 0) return (0); spaces = 0; if (!*tmp && (*(*line - 1) == '"' || *(*line - 1) == '\'')) lex->empty = 1; if (ft_isspace(**line)) { while (ft_isspace(**line)) (*line)++; spaces = 1; } if (set_redir(lex, line, '>') || set_redir(lex, line, '<')) return (create_token(lex, tmp)); if (check_ope(lex, line, tmp)) return (1); if (**line == '(' || spaces) { if (**line == '(') lex->deep++; if (*tmp || lex->empty) { if (lex->type == WORD && lex->wc) return (create_wc(lex, tmp)); return (create_token(lex, tmp)); } } return (0); }