You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

146 lines
3.2 KiB

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lexer.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mea <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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_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])
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;
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));
}
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;
t_token *ret;
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);
else if (check_register(lex, &line, tmp))
tmp_i = (ft_bzero(tmp, 1024), 0);
else
tmp[tmp_i++] = *(line++);
}
create_token(lex, tmp);
free(tmp);
ret = lex->tokens;
free(lex);
return (ret);
}