From d8dd1613c857d1e5f1a0b6a2d649a2b156f873fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kha=C3=AFs=20COLIN?= Date: Tue, 11 Mar 2025 16:41:38 +0100 Subject: [PATCH] cmdgroup parsing: handle parsing a single cmdlist (badly) --- NOTES.md | 14 +++--- src/parser/cmdgroup/cmdgroup.c | 23 ++++++++-- src/parser/cmdgroup/cmdgroup.h | 12 ++++- src/parser/cmdgroup/cmdgroup_item.h | 30 +++++++++++++ src/parser/cmdgroup/cmdgroup_item_type.h | 23 ++++++++++ tests/test_cmdgroup_parsing.c | 25 +++++++++-- tests/testutil.c | 56 +++++++++++++++++++----- tests/testutil.h | 3 +- 8 files changed, 157 insertions(+), 29 deletions(-) create mode 100644 src/parser/cmdgroup/cmdgroup_item.h create mode 100644 src/parser/cmdgroup/cmdgroup_item_type.h diff --git a/NOTES.md b/NOTES.md index f033f74..4877038 100644 --- a/NOTES.md +++ b/NOTES.md @@ -210,16 +210,14 @@ The exit status of this construct is the exit status of LIST. ```c struct s_cmdgroup; -typedef union u_cmdgroup_item_inner -{ - struct s_cmdgroup cmdgroup; - struct s_cmdlist cmdlist; -} t_cmdgroup_item_inner; - typedef struct s_cmdgroup_item { - enum e_cmdgroup_item_type type; - union u_cmdgroup_item_inner inner; + enum e_cmdgroup_item_type type; + union u_cmdgroup_item_inner + { + t_cmdgroup *cmdgroup; + struct s_cmdlist *cmdlist; + } inner; } t_cmdgroup_item; typedef struct s_cmdgroup diff --git a/src/parser/cmdgroup/cmdgroup.c b/src/parser/cmdgroup/cmdgroup.c index bc1ff1a..55cbbf4 100644 --- a/src/parser/cmdgroup/cmdgroup.c +++ b/src/parser/cmdgroup/cmdgroup.c @@ -6,20 +6,35 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/11 15:18:02 by khais #+# #+# */ -/* Updated: 2025/03/11 15:18:59 by khais ### ########.fr */ +/* Updated: 2025/03/11 18:14:24 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include "cmdgroup.h" #include +#include "cmdgroup_item.h" +#include "cmdgroup_item_type.h" +#include "libft.h" t_cmdgroup *cmdgroup_from_wordlist(t_wordlist *words) { - (void)words; - return (NULL); + t_cmdgroup *cmd; + + if (words == NULL) + return (NULL); + cmd = ft_calloc(1, sizeof(t_cmdgroup)); + if (cmd == NULL) + return (NULL); + cmd->item_num = 1; + cmd->items = ft_calloc(1, sizeof(t_cmdgroup_item)); + if (cmd->items == NULL) + return (free(cmd), NULL); + cmd->items[0].type = TYPE_LIST; + cmd->items[0].inner.cmdlist = cmdlist_from_wordlist(words); + return (cmd); } -void cmdgroup_destroy(t_cmdgroup *cmd) +void cmdgroup_destroy(t_cmdgroup *cmd) { (void)cmd; } diff --git a/src/parser/cmdgroup/cmdgroup.h b/src/parser/cmdgroup/cmdgroup.h index 082c600..d090a44 100644 --- a/src/parser/cmdgroup/cmdgroup.h +++ b/src/parser/cmdgroup/cmdgroup.h @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/11 15:11:57 by khais #+# #+# */ -/* Updated: 2025/03/11 15:17:22 by khais ### ########.fr */ +/* Updated: 2025/03/11 18:14:33 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,8 +15,18 @@ # include "../wordlist/wordlist.h" +struct s_cmdgroup_item; + typedef struct s_cmdgroup { + /* + ** Number of items in this cmdgroup + */ + int item_num; + /* + ** array of items in this cmdgroup + */ + struct s_cmdgroup_item *items; } t_cmdgroup; t_cmdgroup *cmdgroup_from_wordlist(t_wordlist *words); diff --git a/src/parser/cmdgroup/cmdgroup_item.h b/src/parser/cmdgroup/cmdgroup_item.h new file mode 100644 index 0000000..619f495 --- /dev/null +++ b/src/parser/cmdgroup/cmdgroup_item.h @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cmdgroup_item.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/11 15:43:15 by khais #+# #+# */ +/* Updated: 2025/03/11 18:10:24 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef CMDGROUP_ITEM_H +# define CMDGROUP_ITEM_H + +# include "cmdgroup_item_type.h" +# include "../command_list/command_list.h" +# include "cmdgroup.h" + +typedef struct s_cmdgroup_item +{ + enum e_cmdgroup_item_type type; + union u_cmdgroup_item_inner + { + t_cmdgroup *cmdgroup; + struct s_cmdlist *cmdlist; + } inner; +} t_cmdgroup_item; + +#endif // CMDGROUP_ITEM_H diff --git a/src/parser/cmdgroup/cmdgroup_item_type.h b/src/parser/cmdgroup/cmdgroup_item_type.h new file mode 100644 index 0000000..4f59f4d --- /dev/null +++ b/src/parser/cmdgroup/cmdgroup_item_type.h @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cmdgroup_item_type.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/11 15:45:33 by khais #+# #+# */ +/* Updated: 2025/03/11 15:46:25 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef CMDGROUP_ITEM_TYPE_H +# define CMDGROUP_ITEM_TYPE_H + +typedef enum e_cmdgroup_item_type +{ + TYPE_INVALID = 0, + TYPE_GROUP, + TYPE_LIST, +} t_cmdgroup_item_type; + +#endif // CMDGROUP_ITEM_TYPE_H diff --git a/tests/test_cmdgroup_parsing.c b/tests/test_cmdgroup_parsing.c index 1b53a82..d41f54f 100644 --- a/tests/test_cmdgroup_parsing.c +++ b/tests/test_cmdgroup_parsing.c @@ -5,8 +5,8 @@ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/11 15:07:23 by khais #+# #+# */ -/* Updated: 2025/03/11 16:33:42 by khais ### ########.fr */ +/* Created: 2025/03/11 17:30/41 by khais #+# #+# */ +/* Updated: 2025/03/11 17:30:41 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ #include #include "libft.h" #include "../src/parser/cmdgroup/cmdgroup.h" -#include "../src/parser/wordsplit/wordsplit.h" +#include "../src/parser/cmdgroup/cmdgroup_item.h" static void test_cmdgroup_parsing_empty(void) { @@ -30,8 +30,27 @@ static void test_cmdgroup_parsing_empty(void) do_leak_check(); } +static void test_cmdgroup_parsing_single_cmdlist(void) +{ + t_cmdgroup *cmd; + + // arange + ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__); + cmd = parse_cmdgroup("echo this | cat -e && echo works | wc -c"); + // assert + assert(NULL != cmd); + assert(1 == cmd->item_num); + assert(TYPE_LIST == cmd->items[0].type); + assert_cmdgroup_itemlistequal("echo this | cat -e && echo works | wc -c", cmd, 0); + // cleanup + cmdgroup_destroy(cmd); + do_leak_check(); +} + int main(void) { test_cmdgroup_parsing_empty(); + test_cmdgroup_parsing_single_cmdlist(); + // redirections return (0); } diff --git a/tests/testutil.c b/tests/testutil.c index 7e4aa79..d9f6810 100644 --- a/tests/testutil.c +++ b/tests/testutil.c @@ -6,18 +6,20 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 15:21:09 by khais #+# #+# */ -/* Updated: 2025/03/11 16:33:46 by khais ### ########.fr */ +/* Updated: 2025/03/11 18:12:05 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include "libft.h" #include #include "testutil.h" +#include "parse_command_list.h" #include "unistd.h" #include #include "parse_pipeline.h" #include "../src/parser/wordlist/wordlist.h" #include "../src/parser/wordsplit/wordsplit.h" +#include "../src/parser/cmdgroup/cmdgroup_item.h" void assert_strequal(char *str1, char *str2) { @@ -60,14 +62,9 @@ void assert_simple_commandequal(t_simple_cmd *expected, t_simple_cmd *got, int i assert(got_word == NULL); } -void assert_pipelineequal(char *expected, t_cmdlist *cmd, int idx) +void assert_pipelineequal_raw(t_pipeline *expected, t_pipeline *got) { - ft_printf("Expected command list %p to have at least %d pipelines, and got %d\n", cmd, idx + 1, cmd->num_pipelines); - assert(cmd->num_pipelines >= idx + 1); - t_pipeline *got = cmd->pipelines[idx]; - ft_dprintf(STDERR_FILENO, "Expected pipeline %p to equal [%s]\n", got, expected); - t_pipeline *expected_pipeline = parse_pipeline(expected); - assert(expected_pipeline == got || expected_pipeline != NULL); + assert(expected == got || expected != NULL); int j = 0; while (j < got->num_cmd) { @@ -75,14 +72,24 @@ void assert_pipelineequal(char *expected, t_cmdlist *cmd, int idx) wordlist_debug(got->cmds[j]->words); j++; } - ft_dprintf(STDERR_FILENO, "Expected pipeline to have %d commands, got pipeline with %d\n", expected_pipeline->num_cmd, got->num_cmd); - assert(expected_pipeline->num_cmd == got->num_cmd); + ft_dprintf(STDERR_FILENO, "Expected pipeline to have %d commands, got pipeline with %d\n", expected->num_cmd, got->num_cmd); + assert(expected->num_cmd == got->num_cmd); int i = 0; - while (i < expected_pipeline->num_cmd) + while (i < expected->num_cmd) { - assert_simple_commandequal(expected_pipeline->cmds[i], got->cmds[i], i); + assert_simple_commandequal(expected->cmds[i], got->cmds[i], i); i++; } +} + +void assert_pipelineequal(char *expected, t_cmdlist *cmd, int idx) +{ + ft_printf("Expected command list %p to have at least %d pipelines, and got %d\n", cmd, idx + 1, cmd->num_pipelines); + assert(cmd->num_pipelines >= idx + 1); + t_pipeline *got = cmd->pipelines[idx]; + ft_dprintf(STDERR_FILENO, "Expected pipeline %p to equal [%s]\n", got, expected); + t_pipeline *expected_pipeline = parse_pipeline(expected); + assert_pipelineequal_raw(expected_pipeline, got); pipeline_destroy(expected_pipeline); } @@ -117,3 +124,28 @@ t_cmdgroup *parse_cmdgroup(char *input) wordlist_destroy(words); return (cmd); } + +void assert_cmdgroup_itemlistequal(char *expected_str, t_cmdgroup *got_cmd, int item_number) +{ + ft_dprintf(STDERR_FILENO, "checking that item %d of cmdlist %p matches [%s]\n", item_number, got_cmd, expected_str); + ft_dprintf(STDERR_FILENO, "expecteing to have at least %d items, and got %d\n", item_number + 1, got_cmd->item_num); + assert(got_cmd->item_num > item_number); + ft_dprintf(STDERR_FILENO, "expecteing item %p to be of type list got %d\n", got_cmd->items[item_number], got_cmd->items[item_number].type); + t_cmdlist *expected = parse_command_list(expected_str); + t_cmdlist *got = got_cmd->items[item_number].inner.cmdlist; + if (expected == NULL) + { + ft_dprintf(STDERR_FILENO, "expecting the list to be null\n"); + assert(expected == got); + return ; + } + ft_dprintf(STDERR_FILENO, "checking if the list matches...\n"); + assert(expected->num_pipelines == got->num_pipelines); + int i = 0; + while (i < expected->num_pipelines) + { + assert_pipelineequal_raw(expected->pipelines[i], got->pipelines[i]); + assert(expected->operators[i] == got->operators[i]); + i++; + } +} diff --git a/tests/testutil.h b/tests/testutil.h index cedba3e..9662f81 100644 --- a/tests/testutil.h +++ b/tests/testutil.h @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 15:57:21 by khais #+# #+# */ -/* Updated: 2025/03/11 16:34:10 by khais ### ########.fr */ +/* Updated: 2025/03/11 17:26:49 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,5 +24,6 @@ void assert_pipelineequal(char *expected, t_cmdlist *cmd, int idx); t_worddesc *create_single_word(char *str); void assert_pipeline_cmd_word(t_pipeline *pipeline, char *expected_word, int cmd_num, int word_num); t_cmdgroup *parse_cmdgroup(char *input); +void assert_cmdgroup_itemlistequal(char *expected_str, t_cmdgroup *got_cmd, int item_number); #endif