132 lines
2.0 KiB
C
132 lines
2.0 KiB
C
#include "minishell.h"
|
|
|
|
static t_token *token_new(t_tokentype type, const char *text, size_t len)
|
|
{
|
|
t_token *t = (t_token *)calloc(1, sizeof(t_token));
|
|
if (!t)
|
|
return NULL;
|
|
t->type = type;
|
|
if (text)
|
|
t->text = ms_strndup(text, len);
|
|
return t;
|
|
}
|
|
|
|
static void token_add(t_token **head, t_token *new)
|
|
{
|
|
t_token *cur;
|
|
if (!new)
|
|
return;
|
|
if (!*head)
|
|
{
|
|
*head = new;
|
|
return;
|
|
}
|
|
cur = *head;
|
|
while (cur->next)
|
|
cur = cur->next;
|
|
cur->next = new;
|
|
}
|
|
|
|
void free_tokens(t_token *toks)
|
|
{
|
|
t_token *n;
|
|
while (toks)
|
|
{
|
|
n = toks->next;
|
|
free(toks->text);
|
|
free(toks);
|
|
toks = n;
|
|
}
|
|
}
|
|
|
|
static int is_meta(char c)
|
|
{
|
|
return (c == '|' || c == '<' || c == '>');
|
|
}
|
|
|
|
static int read_word(const char *line, size_t *i, t_token **out)
|
|
{
|
|
size_t start = *i;
|
|
int in_single = 0;
|
|
int in_double = 0;
|
|
|
|
while (line[*i])
|
|
{
|
|
if (line[*i] == '\'' && !in_double)
|
|
in_single = !in_single;
|
|
else if (line[*i] == '"' && !in_single)
|
|
in_double = !in_double;
|
|
else if (!in_single && !in_double)
|
|
{
|
|
if (ms_is_space(line[*i]) || is_meta(line[*i]))
|
|
break;
|
|
}
|
|
(*i)++;
|
|
}
|
|
if (in_single || in_double)
|
|
return 1;
|
|
*out = token_new(TOK_WORD, line + start, *i - start);
|
|
return 0;
|
|
}
|
|
|
|
t_token *lex_line(const char *line, int *error)
|
|
{
|
|
t_token *toks = NULL;
|
|
size_t i = 0;
|
|
|
|
*error = 0;
|
|
while (line[i])
|
|
{
|
|
if (ms_is_space(line[i]))
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
if (line[i] == '|')
|
|
{
|
|
token_add(&toks, token_new(TOK_PIPE, "|", 1));
|
|
i++;
|
|
continue;
|
|
}
|
|
if (line[i] == '<')
|
|
{
|
|
if (line[i + 1] == '<')
|
|
{
|
|
token_add(&toks, token_new(TOK_HEREDOC, "<<", 2));
|
|
i += 2;
|
|
}
|
|
else
|
|
{
|
|
token_add(&toks, token_new(TOK_REDIR_IN, "<", 1));
|
|
i++;
|
|
}
|
|
continue;
|
|
}
|
|
if (line[i] == '>')
|
|
{
|
|
if (line[i + 1] == '>')
|
|
{
|
|
token_add(&toks, token_new(TOK_REDIR_APPEND, ">>", 2));
|
|
i += 2;
|
|
}
|
|
else
|
|
{
|
|
token_add(&toks, token_new(TOK_REDIR_OUT, ">", 1));
|
|
i++;
|
|
}
|
|
continue;
|
|
}
|
|
{
|
|
t_token *w = NULL;
|
|
if (read_word(line, &i, &w))
|
|
{
|
|
*error = 1;
|
|
free_tokens(toks);
|
|
return NULL;
|
|
}
|
|
token_add(&toks, w);
|
|
}
|
|
}
|
|
return toks;
|
|
}
|