mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
This leak would happen if the alocation of the builder fails. In that case, we don't free our copy of the wordlist
117 lines
3.5 KiB
C
117 lines
3.5 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* cmdlist.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* 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 <unistd.h>
|
|
#include <stdlib.h>
|
|
|
|
/*
|
|
** 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);
|
|
}
|