#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; }