From d2808397640c17444b88368daa531f49d78289eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kha=C3=AFs=20COLIN?= Date: Tue, 25 Feb 2025 15:24:52 +0100 Subject: [PATCH] command list refactor: use a builder struct --- src/parser/command_list/command_list.c | 96 +++++++++++++++++--------- src/parser/command_list/command_list.h | 22 +++++- 2 files changed, 86 insertions(+), 32 deletions(-) diff --git a/src/parser/command_list/command_list.c b/src/parser/command_list/command_list.c index 15d73ce..10e492b 100644 --- a/src/parser/command_list/command_list.c +++ b/src/parser/command_list/command_list.c @@ -6,13 +6,12 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/24 17:49:46 by khais #+# #+# */ -/* Updated: 2025/02/25 15:25:14 by khais ### ########.fr */ +/* Updated: 2025/02/26 12:51:57 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include "command_list.h" #include "libft.h" -#include "unistd.h" #include /* @@ -81,45 +80,80 @@ static t_cmdlist *allocate_command_list(t_wordlist *words) return (output); } +/* +** setup a cmdlist_builder by allocating needed memory, and performing other +** initialization steps. +*/ +static t_cmdlist_builder *setup_cmdlist_builder( + t_cmdlist_builder *builder, + t_wordlist **words) +{ + ft_bzero(builder, sizeof(t_cmdlist_builder)); + builder->cmdlist = allocate_command_list(*words); + if (builder->cmdlist == NULL) + return (NULL); + builder->current_wordlist = NULL; + builder->current_word = wordlist_pop(words); + builder->idx = 0; + return (builder); +} + +/* +** Advance the state to the next word +*/ +static void cmdlist_builder_next_word( + t_cmdlist_builder *builder, + t_wordlist **words) +{ + builder->current_wordlist + = wordlist_push(builder->current_wordlist, builder->current_word); + builder->current_word = wordlist_pop(words); +} + +/* +** return true if we are currently adding the last pipeline in the chain +*/ +static bool cmdlist_builder_at_last_pipeline(t_cmdlist_builder *builder) +{ + return (builder->idx == builder->cmdlist->num_pipelines - 1); +} + +static void cmdlist_builder_delimit( + t_cmdlist_builder *builder, + t_wordlist **words) +{ + builder->cmdlist->pipelines[builder->idx] + = pipeline_from_wordlist(builder->current_wordlist); + if (cmdlist_builder_at_last_pipeline(builder)) + builder->cmdlist->operators[builder->idx] = OP_END; + else + builder->cmdlist->operators[builder->idx] + = match_op(builder->current_word->word); + builder->current_wordlist = NULL; + worddesc_destroy(builder->current_word); + builder->current_word = wordlist_pop(words); + builder->idx++; +} + /* ** Create a new command list from the given wordlist. */ t_cmdlist *cmdlist_from_wordlist(t_wordlist *words) { - t_cmdlist *output; - t_wordlist *current_wordlist; - t_worddesc *current_word; - int idx; + t_cmdlist_builder builder; - output = allocate_command_list(words); - if (output == NULL) + if (setup_cmdlist_builder(&builder, &words) == NULL) return (NULL); - current_wordlist = NULL; - current_word = wordlist_pop(&words); - idx = 0; - while (current_word != NULL) + while (builder.current_word != NULL) { - if (match_op(current_word->word) == OP_INVALID) - { - current_wordlist = wordlist_push(current_wordlist, current_word); - current_word = wordlist_pop(&words); - } + if (match_op(builder.current_word->word) == OP_INVALID) + cmdlist_builder_next_word(&builder, &words); else - { - output->pipelines[idx] = pipeline_from_wordlist(current_wordlist); - output->operators[idx] = match_op(current_word->word); - current_wordlist = NULL; - worddesc_destroy(current_word); - current_word = wordlist_pop(&words); - idx++; - } + cmdlist_builder_delimit(&builder, &words); } - if (current_wordlist != NULL) - { - output->pipelines[idx] = pipeline_from_wordlist(current_wordlist); - output->operators[idx] = OP_END; - } - return (output); + if (builder.current_wordlist != NULL) + cmdlist_builder_delimit(&builder, &words); + return (builder.cmdlist); } /* diff --git a/src/parser/command_list/command_list.h b/src/parser/command_list/command_list.h index 99166cb..55e9975 100644 --- a/src/parser/command_list/command_list.h +++ b/src/parser/command_list/command_list.h @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/24 17:45:01 by khais #+# #+# */ -/* Updated: 2025/02/25 15:25:14 by khais ### ########.fr */ +/* Updated: 2025/02/26 12:50:41 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -102,6 +102,26 @@ typedef struct s_cmdlist t_operator *operators; } t_cmdlist; +typedef struct s_cmdlist_builder +{ + /* + ** list of cmds that we are building + */ + t_cmdlist *cmdlist; + /* + ** wordlist for the next pipeline + */ + t_wordlist *current_wordlist; + /* + ** word we are currently examining + */ + t_worddesc *current_word; + /* + ** index of the pipeline that is about to be inserted into the cmdlist + */ + int idx; +} t_cmdlist_builder; + t_cmdlist *cmdlist_from_wordlist(t_wordlist *words); void cmdlist_destroy(t_cmdlist *cmd);