/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* lexer.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: mea +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/02 13:44:57 by narnaud #+# #+# */ /* Updated: 2022/05/06 11:19:26 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" int create_token(t_lexer *lex, char str[]) { t_token *tok; 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]) // return (0); tok = lex->tokens; if (!lex->tokens) tok = ft_calloc(1, sizeof *tok); else { while (tok->next) tok = tok->next; tok->next = ft_calloc(1, sizeof *tok); tok = tok->next; } tok->type = type; tok->value = ft_strdup(str); if (!lex->tokens) lex->tokens = tok; ft_bzero(str, 1024); return (1); } int set_redir(t_lexer *lex, char **line, char ch) { static t_type type_out[2] = {ADD, OUT}; static t_type type_in[2] = {IN, HD}; t_type *type; if (ch == '>') type = type_out; else type = type_in; if (**line == ch && (*line)++) { if (**line == ch && (*line)++) lex->next_type = type[0]; else lex->next_type = type[1]; return (1); } return (0); } int check_register(t_lexer *lex, char **line, char *tmp) { int spaces; if (lex->state != ROOT_ST) return (0); spaces = 0; 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)); else if (**line == '|') { (*line)++; lex->next_type = PIPE; create_token(lex, tmp); return (create_token(lex, "|")); } if (!spaces || !*tmp) return (0); return (create_token(lex, tmp)); } char *get_var_value(t_datas *datas, char **line, int *name_len) { int i; char **env; char *name; char *value; i = 1; while (ft_isalpha((*line)[i]) || ft_isdigit((*line)[i]) || (*line)[i] == '_') i++; name = ft_substr(*line, 1, i - 1); i = 0; *name_len = ft_strlen(name); value = NULL; while (datas->envp[i] && !value) { env = ft_split(datas->envp[i], '='); if (!ft_strncmp(name, env[0], *name_len + 1)) value = (free(env[0]), env[1]); else if (++i) ft_free_split(env); } if (!datas->envp[i]) value = strdup(""); else free(env); return (value); } int replace_var(t_datas *datas, char **line, char *tmp, int tmp_i) { int name_len; int i; char *value; if ((*line)[1] == '?') { value = ft_itoa(datas->exit_code); name_len = 2; } else value = get_var_value(datas, line, &name_len); i = 0; while (value[i]) tmp[tmp_i++] = value[i++]; tmp[tmp_i] = 0; *line += name_len + 1; free(value); return (tmp_i); } int check_state(t_lexer *lex, char **line) { t_state new; new = OLD_ST; if (**line == '"') { if (lex->state == D_QUOTE_ST) new = ROOT_ST; else if (lex->state == ROOT_ST) new = D_QUOTE_ST; } else if (**line == '\'') { if (lex->state == S_QUOTE_ST) new = ROOT_ST; else if (lex->state == ROOT_ST) new = S_QUOTE_ST; } if (new) { (*line)++; lex->state = new; return (1); } return (0); } t_token *lexer(t_datas *datas, char *line) { t_lexer *lex; char *tmp; int tmp_i; lex = ft_calloc(1, sizeof *lex); lex->state = ROOT_ST; tmp = ft_calloc(1024, sizeof *tmp); tmp_i = 0; while (*line) { if (check_state(lex, &line)) continue; if (lex->state != S_QUOTE_ST && *line == '$') tmp_i = replace_var(datas, &line, tmp, tmp_i); if (check_register(lex, &line, tmp)) tmp_i = 0; else tmp[tmp_i++] = *(line++); } create_token(lex, tmp); free(tmp); free(lex); return (lex->tokens); }