From a20ea8315d9e51202cce58018c1947264f6fbb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kha=C3=AFs=20COLIN?= Date: Fri, 7 Mar 2025 13:34:47 +0100 Subject: [PATCH] redirection parsing: handle > at start of wordlist --- .../redirections/redirection_parsing.c | 30 +++++++++++++++++-- tests/test_redirection_parsing.c | 26 ++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/postprocess/redirections/redirection_parsing.c b/src/postprocess/redirections/redirection_parsing.c index 1b29e26..e1f9d25 100644 --- a/src/postprocess/redirections/redirection_parsing.c +++ b/src/postprocess/redirections/redirection_parsing.c @@ -1,18 +1,44 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* redirections.c :+: :+: :+: */ +/* redirection_parsing.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/07 12:30:04 by khais #+# #+# */ -/* Updated: 2025/03/07 14:43:06 by khais ### ########.fr */ +/* Updated: 2025/03/07 14:53:22 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include "redirection_parsing.h" +#include "redirection.h" +#include "redirection_list.h" +#include +#include "libft.h" +/* +** Modify the given simple_cmd in-place, removing all redirection directives +** from words, parsing them, and storing them in redirection. +** +** In case of allocation failure, all memory allocated in this function is +** freed, but the command given in entry is not. +** +** In case of error, return null (this may leave the given command in an +** inconsitent state) (but it can still be freed correctly). +*/ struct s_simple_cmd *parse_redirections(struct s_simple_cmd *cmd) { + t_worddesc *marker; + t_redirection *redirection; + + if (ft_strcmp(">", cmd->words->word->word) == 0) + { + worddesc_destroy(wordlist_pop(&cmd->words)); + marker = wordlist_pop(&cmd->words); + redirection = redirection_create(REDIR_OUTPUT, marker); + cmd->redirections = redir_list_push(cmd->redirections, redirection); + if (cmd->redirections == NULL) + return (redirection_destroy(redirection), NULL); + } return (cmd); } diff --git a/tests/test_redirection_parsing.c b/tests/test_redirection_parsing.c index 689ff2f..cdf3f7e 100644 --- a/tests/test_redirection_parsing.c +++ b/tests/test_redirection_parsing.c @@ -5,8 +5,8 @@ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/07 11:55:37 by khais #+# #+# */ -/* Updated: 2025/03/07 14:43:15 by khais ### ########.fr */ +/* Created: 2025/03/07 14:47/34 by khais #+# #+# */ +/* Updated: 2025/03/07 14:47:34 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,9 @@ #include "../src/parser/simple_cmd/simple_cmd.h" #include "../src/parser/wordsplit/wordsplit.h" #include "../src/postprocess/redirections/redirection_parsing.h" +#include "../src/postprocess/redirections/redirection_parsing.h" +#include "../src/postprocess/redirections/redirection_list.h" +#include "testutil.h" static t_simple_cmd *parse_simple_cmd(char *input) { @@ -28,9 +31,28 @@ static void test_redirection_parsing_no_redirections(void) assert(parse_redirections(cmd) != NULL); assert(cmd->redirections == NULL); simple_cmd_destroy(cmd); + do_leak_check(); } +static void test_redirection_parsing_output_at_start(void) +{ + t_simple_cmd *cmd = parse_simple_cmd(">outfile echo hello world"); + assert(parse_redirections(cmd) != NULL); + assert_strequal("outfile", cmd->redirections->redirection->marker->word); + assert(cmd->redirections->redirection->type == REDIR_OUTPUT); + assert(cmd->redirections->next == NULL); + assert_strequal("echo", cmd->words->word->word); + assert_strequal("hello", cmd->words->next->word->word); + assert_strequal("world", cmd->words->next->next->word->word); + assert(NULL == cmd->words->next->next->next); + simple_cmd_destroy(cmd); + do_leak_check(); +} + + int main(void) { test_redirection_parsing_no_redirections(); + test_redirection_parsing_output_at_start(); + // check operator alone without further tokens return (0); }