From 06dd3c3e831ff2f664078fcbee43f4e53c789bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kha=C3=AFs=20COLIN?= Date: Fri, 7 Mar 2025 15:18:06 +0100 Subject: [PATCH] redirection parings: handle redirections not at start --- .../redirections/redirection_parsing.c | 41 +++++++++++++----- tests/test_redirection_parsing.c | 42 ++++++++++++++++++- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/postprocess/redirections/redirection_parsing.c b/src/postprocess/redirections/redirection_parsing.c index b22bda3..bb4ac78 100644 --- a/src/postprocess/redirections/redirection_parsing.c +++ b/src/postprocess/redirections/redirection_parsing.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/07 12:30:04 by khais #+# #+# */ -/* Updated: 2025/03/07 14:58:22 by khais ### ########.fr */ +/* Updated: 2025/03/10 16:11:46 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ #include "redirection_list.h" #include #include "redirection_type.h" +#include /* ** Modify the given simple_cmd in-place, removing all redirection directives @@ -25,24 +26,42 @@ ** ** In case of error, return null (this may leave the given command in an ** inconsitent state) (but it can still be freed correctly). +** +** Algorithm: +** +** iterate though the words of the given cmd +** +** if a redirection token is detected, the current word will be the operator +** token. Destroy it. +** +** the current word is now the marker. save it and destroy it +** +** create a new redirection with the operator and the maker, and save it. */ struct s_simple_cmd *parse_redirections(struct s_simple_cmd *cmd) { t_worddesc *marker; t_redirection *redirection; t_redir_type type; + size_t i; - type = redir_type_from_worddesc(cmd->words->word); - if (type == REDIR_OUTPUT) + i = 0; + while (wordlist_get(cmd->words, i) != NULL) { - worddesc_destroy(wordlist_pop(&cmd->words)); - marker = wordlist_pop(&cmd->words); - redirection = redirection_create(type, marker); - if (redirection == NULL) - return (NULL); - cmd->redirections = redir_list_push(cmd->redirections, redirection); - if (cmd->redirections == NULL) - return (redirection_destroy(redirection), NULL); + type = redir_type_from_worddesc(wordlist_get(cmd->words, i)); + if (type == REDIR_OUTPUT) + { + wordlist_destroy_idx(&cmd->words, i); + marker = wordlist_pop_idx(&cmd->words, i); + redirection = redirection_create(type, marker); + if (redirection == NULL) + return (NULL); + cmd->redirections = redir_list_push(cmd->redirections, redirection); + if (cmd->redirections == NULL) + return (redirection_destroy(redirection), NULL); + } + else + i++; } return (cmd); } diff --git a/tests/test_redirection_parsing.c b/tests/test_redirection_parsing.c index cdf3f7e..36324f0 100644 --- a/tests/test_redirection_parsing.c +++ b/tests/test_redirection_parsing.c @@ -5,8 +5,8 @@ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/07 14:47/34 by khais #+# #+# */ -/* Updated: 2025/03/07 14:47:34 by khais ### ########.fr */ +/* Created: 2025/03/10 16:13/18 by khais #+# #+# */ +/* Updated: 2025/03/10 16:13:18 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include "../src/postprocess/redirections/redirection_parsing.h" #include "../src/postprocess/redirections/redirection_parsing.h" #include "../src/postprocess/redirections/redirection_list.h" +#include "ft_printf.h" #include "testutil.h" static t_simple_cmd *parse_simple_cmd(char *input) @@ -27,6 +28,7 @@ static t_simple_cmd *parse_simple_cmd(char *input) static void test_redirection_parsing_no_redirections(void) { + ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__); t_simple_cmd *cmd = parse_simple_cmd("echo hello world"); assert(parse_redirections(cmd) != NULL); assert(cmd->redirections == NULL); @@ -36,6 +38,7 @@ static void test_redirection_parsing_no_redirections(void) static void test_redirection_parsing_output_at_start(void) { + ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__); t_simple_cmd *cmd = parse_simple_cmd(">outfile echo hello world"); assert(parse_redirections(cmd) != NULL); assert_strequal("outfile", cmd->redirections->redirection->marker->word); @@ -49,10 +52,45 @@ static void test_redirection_parsing_output_at_start(void) do_leak_check(); } +static void test_redirection_parsing_output_at_end(void) +{ + ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__); + t_simple_cmd *cmd = parse_simple_cmd("echo hello world > outfile"); + assert(parse_redirections(cmd) != 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); + assert_strequal("outfile", cmd->redirections->redirection->marker->word); + assert(cmd->redirections->redirection->type == REDIR_OUTPUT); + assert(cmd->redirections->next == NULL); + simple_cmd_destroy(cmd); + do_leak_check(); +} + +static void test_redirection_parsing_output_in_middle(void) +{ + ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__); + t_simple_cmd *cmd = parse_simple_cmd("echo hello >outfile world"); + assert(parse_redirections(cmd) != 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); + assert_strequal("outfile", cmd->redirections->redirection->marker->word); + assert(cmd->redirections->redirection->type == REDIR_OUTPUT); + assert(cmd->redirections->next == NULL); + simple_cmd_destroy(cmd); + do_leak_check(); +} + int main(void) { test_redirection_parsing_no_redirections(); test_redirection_parsing_output_at_start(); + test_redirection_parsing_output_at_end(); + test_redirection_parsing_output_in_middle(); // check operator alone without further tokens + // check null input return (0); }