From 5f1485d1d52392fdf330e781153dd81dc99c4201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kha=C3=AFs=20COLIN?= Date: Fri, 21 Feb 2025 14:13:51 +0100 Subject: [PATCH] pipeline: parse basic pipeline commands with two commands --- src/parser/pipeline/pipeline.c | 62 +++++++++++++++++++++++++++++++--- src/parser/wordlist/wordlist.c | 21 +++++++++++- src/parser/wordlist/wordlist.h | 3 +- tests/parse_pipelines.c | 20 +++++++++-- 4 files changed, 97 insertions(+), 9 deletions(-) diff --git a/src/parser/pipeline/pipeline.c b/src/parser/pipeline/pipeline.c index 30341aa..d07787a 100644 --- a/src/parser/pipeline/pipeline.c +++ b/src/parser/pipeline/pipeline.c @@ -6,12 +6,66 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/21 13:23:50 by khais #+# #+# */ -/* Updated: 2025/02/21 13:45:12 by khais ### ########.fr */ +/* Updated: 2025/02/21 15:23:12 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include "pipeline.h" #include "libft.h" +#include "unistd.h" +#include "../matchers/pipe.h" + +static int pipeline_count_cmds(t_wordlist *words) +{ + int count; + + if (words == NULL) + return (0); + count = 1; + while (words != NULL) + { + if (is_pipe(words->word)) + count++; + words = words->next; + } + return (count); +} + +static t_worddesc *ignore_word(t_worddesc *current_word, t_wordlist **words) +{ + worddesc_destroy(current_word); + return (wordlist_pop(words)); +} + +static t_pipeline *pipeline_parse_wordlist(t_pipeline *pipeline, + t_wordlist *words) +{ + int idx; + t_wordlist *current_wordlist; + t_worddesc *current_word; + + idx = 0; + current_wordlist = NULL; + current_word = wordlist_pop(&words); + while (current_word != NULL) + { + if (is_pipe(current_word)) + { + pipeline->cmds[idx] = simple_cmd_from_wordlist(current_wordlist); + if (pipeline->cmds[idx] == NULL) + return (pipeline_destroy(pipeline), NULL); + current_wordlist = NULL; + current_word = ignore_word(current_word, &words); + idx++; + } + current_wordlist = wordlist_push(current_wordlist, current_word); + current_word = wordlist_pop(&words); + } + pipeline->cmds[idx] = simple_cmd_from_wordlist(current_wordlist); + if (pipeline->cmds[idx] == NULL) + return (pipeline_destroy(pipeline), NULL); + return (pipeline); +} t_pipeline *pipeline_from_wordlist(t_wordlist *words) { @@ -22,11 +76,11 @@ t_pipeline *pipeline_from_wordlist(t_wordlist *words) pipeline = ft_calloc(1, sizeof(t_pipeline)); if (pipeline == NULL) return (NULL); - pipeline->num_cmd = 1; - pipeline->cmds = ft_calloc(1, sizeof(t_simple_cmd *)); + pipeline->num_cmd = pipeline_count_cmds(words); + pipeline->cmds = ft_calloc(pipeline->num_cmd, sizeof(t_simple_cmd *)); if (pipeline->cmds == NULL) return (NULL); - pipeline->cmds[0] = simple_cmd_from_wordlist(words); + pipeline = pipeline_parse_wordlist(pipeline, words); return (pipeline); } diff --git a/src/parser/wordlist/wordlist.c b/src/parser/wordlist/wordlist.c index 5eb1a5e..3767ad9 100644 --- a/src/parser/wordlist/wordlist.c +++ b/src/parser/wordlist/wordlist.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 17:07:01 by khais #+# #+# */ -/* Updated: 2025/02/14 16:47:04 by khais ### ########.fr */ +/* Updated: 2025/02/21 14:04:50 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -91,3 +91,22 @@ t_wordlist *wordlist_push(t_wordlist *wordlist, t_worddesc *worddesc) return (wordlist_destroy(start), NULL); return (start); } + +/* +** remove and return the first element in the given wordlist +** +** If wordlist is empty, return null. +*/ +t_worddesc *wordlist_pop(t_wordlist **wordlist) +{ + t_wordlist *first; + t_worddesc *word; + + if ((*wordlist) == NULL) + return (NULL); + first = *wordlist; + (*wordlist) = first->next; + word = first->word; + free(first); + return (word); +} diff --git a/src/parser/wordlist/wordlist.h b/src/parser/wordlist/wordlist.h index b832d01..950c0a3 100644 --- a/src/parser/wordlist/wordlist.h +++ b/src/parser/wordlist/wordlist.h @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 15:46:02 by khais #+# #+# */ -/* Updated: 2025/02/14 15:48:36 by khais ### ########.fr */ +/* Updated: 2025/02/21 14:00:19 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,5 +38,6 @@ t_wordlist *wordlist_create(t_worddesc *word); void wordlist_destroy(t_wordlist *wordlist); t_worddesc *wordlist_get(t_wordlist *wordlist, int idx); t_wordlist *wordlist_push(t_wordlist *wordlist, t_worddesc *worddesc); +t_worddesc *wordlist_pop(t_wordlist **wordlist); #endif diff --git a/tests/parse_pipelines.c b/tests/parse_pipelines.c index a2595fe..08598a7 100644 --- a/tests/parse_pipelines.c +++ b/tests/parse_pipelines.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/21 13:13:58 by khais #+# #+# */ -/* Updated: 2025/02/21 13:44:16 by khais ### ########.fr */ +/* Updated: 2025/02/21 14:07:52 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,11 +29,13 @@ static void assert_pipeline_cmd_word(t_pipeline *pipeline, char *expected_word, { if (pipeline->num_cmd <= cmd_num) { - ft_dprintf(STDERR_FILENO, "expected pipeline %p to have at least %d words, but got %d\n", pipeline, cmd_num + 1, pipeline->num_cmd); + ft_dprintf(STDERR_FILENO, "expected pipeline %p to have at least %d cmds, but got %d\n", pipeline, cmd_num + 1, pipeline->num_cmd); assert(false); } + ft_dprintf(STDERR_FILENO, "for pipeline %p cmd %d word %d, expected '%s', and got ", pipeline, cmd_num, word_num, expected_word); + assert(pipeline->cmds[cmd_num] != NULL && "null cmd at that location"); char *got_word = wordlist_get(pipeline->cmds[cmd_num]->words, word_num)->word; - ft_dprintf(STDERR_FILENO, "for pipeline %p cmd %d word %d, expected '%s', and got '%s'\n", pipeline, cmd_num, word_num, expected_word, got_word); + ft_dprintf(STDERR_FILENO, "'%s'\n", got_word); assert(expected_word == got_word || ft_strncmp(expected_word, got_word, INT_MAX) == 0); } @@ -54,9 +56,21 @@ static void test_parse_pipeline_single_cmd(void) pipeline_destroy(pipeline); } +static void test_parse_pipeline_two_cmd(void) +{ + t_pipeline *pipeline = parse_pipeline("echo hello world | tee output.txt"); + assert_pipeline_cmd_word(pipeline, "echo", 0, 0); + assert_pipeline_cmd_word(pipeline, "hello", 0, 1); + assert_pipeline_cmd_word(pipeline, "world", 0, 2); + assert_pipeline_cmd_word(pipeline, "tee", 1, 0); + assert_pipeline_cmd_word(pipeline, "output.txt", 1, 1); + pipeline_destroy(pipeline); +} + int main(void) { test_parse_empty_pipeline(); test_parse_pipeline_single_cmd(); + test_parse_pipeline_two_cmd(); return (0); }