#include "minishell.h" static t_command *command_new(void) { t_command *cmd = (t_command *)calloc(1, sizeof(t_command)); return cmd; } static void command_add_arg(t_command *cmd, const char *text) { char **new_argv; int i; if (!cmd || !text) return; i = cmd->argc; new_argv = (char **)calloc((size_t)i + 2, sizeof(char *)); if (!new_argv) return; for (int j = 0; j < i; j++) new_argv[j] = cmd->argv[j]; new_argv[i] = ms_strdup(text); new_argv[i + 1] = NULL; free(cmd->argv); cmd->argv = new_argv; cmd->argc += 1; } static void command_add_redir(t_command *cmd, t_redirtype type, const char *target) { t_redir *r = (t_redir *)calloc(1, sizeof(t_redir)); t_redir *cur; if (!r) return; r->type = type; r->target = ms_strdup(target); r->fd = -1; r->next = NULL; if (!cmd->redirs) { cmd->redirs = r; return; } cur = cmd->redirs; while (cur->next) cur = cur->next; cur->next = r; } static void free_redirs(t_redir *r) { t_redir *n; while (r) { n = r->next; if (r->fd != -1) close(r->fd); free(r->target); free(r); r = n; } } void free_pipeline(t_pipeline *p) { size_t i; if (!p) return; for (i = 0; i < p->count; i++) { if (p->cmds[i]) { for (int j = 0; p->cmds[i]->argv && p->cmds[i]->argv[j]; j++) free(p->cmds[i]->argv[j]); free(p->cmds[i]->argv); free(p->cmds[i]->path); free_redirs(p->cmds[i]->redirs); free(p->cmds[i]); } } free(p->cmds); free(p); } static int pipeline_add_cmd(t_pipeline *p, t_command *cmd) { t_command **new_cmds; size_t i; new_cmds = (t_command **)calloc(p->count + 1, sizeof(t_command *)); if (!new_cmds) return 1; for (i = 0; i < p->count; i++) new_cmds[i] = p->cmds[i]; new_cmds[p->count] = cmd; free(p->cmds); p->cmds = new_cmds; p->count += 1; return 0; } t_pipeline *parse_tokens(t_token *toks, int *error) { t_pipeline *p; t_command *cmd; t_token *cur; *error = 0; p = (t_pipeline *)calloc(1, sizeof(t_pipeline)); if (!p) return NULL; cmd = command_new(); if (!cmd) { free(p); return NULL; } cur = toks; while (cur) { if (cur->type == TOK_PIPE) { if (cmd->argc == 0) { *error = 1; free_pipeline(p); free(cmd); return NULL; } pipeline_add_cmd(p, cmd); cmd = command_new(); if (!cmd) { *error = 1; free_pipeline(p); return NULL; } cur = cur->next; continue; } if (cur->type == TOK_REDIR_IN || cur->type == TOK_REDIR_OUT || cur->type == TOK_REDIR_APPEND || cur->type == TOK_HEREDOC) { if (!cur->next || cur->next->type != TOK_WORD) { *error = 1; free_pipeline(p); free(cmd); return NULL; } if (cur->type == TOK_REDIR_IN) command_add_redir(cmd, REDIR_IN, cur->next->text); else if (cur->type == TOK_REDIR_OUT) command_add_redir(cmd, REDIR_OUT, cur->next->text); else if (cur->type == TOK_REDIR_APPEND) command_add_redir(cmd, REDIR_APPEND, cur->next->text); else if (cur->type == TOK_HEREDOC) command_add_redir(cmd, REDIR_HEREDOC, cur->next->text); cur = cur->next->next; continue; } if (cur->type == TOK_WORD) command_add_arg(cmd, cur->text); cur = cur->next; } if (cmd->argc == 0) { *error = 1; free_pipeline(p); free(cmd); return NULL; } pipeline_add_cmd(p, cmd); return p; }