/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* cmdlist.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/24 17:49:46 by khais #+# #+# */ /* Updated: 2025/03/20 12:23:39 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include "cmdlist.h" #include "cmdlist_item.h" #include "cmdlist_builder.h" #include "cmdlist_item_type.h" #include "operator.h" #include #include /* ** Frees all memory associated with this builder and set error to true. */ static void cmdlist_builder_error(t_cmdlist_builder *builder) { if (builder == NULL) return ; cmdlist_destroy(builder->cmdlist); builder->cmdlist = NULL; wordlist_destroy(builder->current_wordlist); builder->current_wordlist = NULL; worddesc_destroy(builder->current_word); builder->current_word = NULL; builder->error = true; } /* ** Delimit the current pipeline, creating a new t_pipeline object. ** ** Sets the operator for that pipeline. ** ** Assumes that the current word is a valid operator. */ static void cmdlist_builder_delimit( t_cmdlist_builder *builder, t_wordlist **words) { builder->cmdlist->cmds[builder->idx] = cmdlist_item_create(); builder->cmdlist->cmds[builder->idx]->inner.pipeline = pipeline_from_wordlist(builder->current_wordlist); builder->cmdlist->cmds[builder->idx]->type = TYPE_PIPELINE; if (builder->cmdlist->cmds[builder->idx]->inner.pipeline == NULL) { cmdlist_builder_error(builder); wordlist_destroy(*words); return ; } 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); wordlist_destroy(builder->current_wordlist); 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. ** ** Makes a copy of the given wordlist */ t_cmdlist *cmdlist_from_wordlist(const t_wordlist *wordlist) { t_cmdlist_builder builder; t_wordlist *words; words = wordlist_copy(wordlist); if (words == NULL) return (NULL); if (setup_cmdlist_builder(&builder, &words) == NULL) return (wordlist_destroy(words), NULL); while (builder.error == false && builder.current_word != NULL) { if (match_op(builder.current_word->word) == OP_INVALID) cmdlist_builder_next_word(&builder, &words); else cmdlist_builder_delimit(&builder, &words); } if (builder.current_wordlist != NULL) cmdlist_builder_delimit(&builder, &words); if (builder.error == true) return (NULL); return (builder.cmdlist); } /* ** destroy the given command list and all associated memory */ void cmdlist_destroy(t_cmdlist *cmd) { int i; if (cmd == NULL) return ; i = 0; while (i < cmd->num_cmd) { cmdlist_item_destroy(cmd->cmds[i]); i++; } free(cmd->cmds); free(cmd->operators); free(cmd); }