command list refactor: put functions in correct file

This commit is contained in:
Khaïs COLIN 2025-02-25 15:24:52 +01:00 committed by Khaïs COLIN
parent d280839764
commit bccd68b11f
7 changed files with 209 additions and 127 deletions

View file

@ -26,7 +26,9 @@ srcs = \
src/env/envp.c \
src/ft_errno.c \
src/get_command.c \
src/parser/command_list/command_list_builder.c \
src/parser/command_list/command_list.c \
src/parser/command_list/operator.c \
src/parser/matchers/blank.c \
src/parser/matchers/identifier.c \
src/parser/matchers/metacharacter.c \

View file

@ -6,98 +6,15 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/24 17:49:46 by khais #+# #+# */
/* Updated: 2025/02/26 12:51:57 by khais ### ########.fr */
/* Updated: 2025/02/26 13:56:45 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "command_list.h"
#include "libft.h"
#include "command_list_builder.h"
#include "operator.h"
#include <stdlib.h>
/*
** Match a string to an operator
**
** If the string does not match any operator, return OP_INVALID
*/
static t_operator match_op(char *op)
{
if (ft_strcmp("&&", op) == 0)
return (OP_AND);
if (ft_strcmp("||", op) == 0)
return (OP_OR);
return (OP_INVALID);
}
/*
** Count the number of pipelines in the given wordstream
**
** Pipelines are separated by operators || and &&.
**
** Does not do error checking about repeated operators, or operators in the
** wrong place.
*/
static int command_list_count_pipelines(t_wordlist *words)
{
t_wordlist *current_word;
int count;
current_word = words;
if (current_word == NULL)
return (0);
count = 1;
while (current_word != NULL)
{
if (match_op(current_word->word->word) != OP_INVALID)
count++;
current_word = current_word->next;
}
return (count);
}
/*
** Allocate memory for a new command_list, given the input word stream.
**
** Handles malloc error.
*/
static t_cmdlist *allocate_command_list(t_wordlist *words)
{
t_cmdlist *output;
if (words == NULL)
return (NULL);
output = ft_calloc(1, sizeof(t_cmdlist));
if (output == NULL)
return (NULL);
output->num_pipelines = command_list_count_pipelines(words);
output->pipelines
= ft_calloc(output->num_pipelines, sizeof(t_pipeline *));
if (output->pipelines == NULL)
return (free(output), NULL);
output->operators
= ft_calloc(output->num_pipelines, sizeof(t_operator));
if (output->operators == NULL)
return (free(output->pipelines), free(output), NULL);
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
*/
@ -118,6 +35,13 @@ static bool cmdlist_builder_at_last_pipeline(t_cmdlist_builder *builder)
return (builder->idx == builder->cmdlist->num_pipelines - 1);
}
/*
** 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)

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/24 17:45:01 by khais #+# #+# */
/* Updated: 2025/02/26 12:50:41 by khais ### ########.fr */
/* Updated: 2025/02/26 13:50:46 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -15,26 +15,7 @@
# include "../wordlist/wordlist.h"
# include "../pipeline/pipeline.h"
typedef enum e_operator
{
/*
** Not a valid operator
*/
OP_INVALID,
/*
** &&
*/
OP_AND,
/*
** ||
*/
OP_OR,
/*
** End of operator list
*/
OP_END,
} t_operator;
# include "operator.h"
/*
** cf. 3.2.4 Lists of Commands
@ -102,26 +83,6 @@ 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);

View file

@ -0,0 +1,84 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* command_list_builder.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/26 13:51:18 by khais #+# #+# */
/* Updated: 2025/02/26 13:52:39 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "command_list_builder.h"
#include "libft.h"
/*
** Count the number of pipelines in the given wordstream
**
** Pipelines are separated by operators || and &&.
**
** Does not do error checking about repeated operators, or operators in the
** wrong place.
*/
static int command_list_count_pipelines(t_wordlist *words)
{
t_wordlist *current_word;
int count;
current_word = words;
if (current_word == NULL)
return (0);
count = 1;
while (current_word != NULL)
{
if (match_op(current_word->word->word) != OP_INVALID)
count++;
current_word = current_word->next;
}
return (count);
}
/*
** Allocate memory for a new command_list, given the input word stream.
**
** Handles malloc error.
*/
static t_cmdlist *allocate_command_list(t_wordlist *words)
{
t_cmdlist *output;
if (words == NULL)
return (NULL);
output = ft_calloc(1, sizeof(t_cmdlist));
if (output == NULL)
return (NULL);
output->num_pipelines = command_list_count_pipelines(words);
output->pipelines
= ft_calloc(output->num_pipelines, sizeof(t_pipeline *));
if (output->pipelines == NULL)
return (free(output), NULL);
output->operators
= ft_calloc(output->num_pipelines, sizeof(t_operator));
if (output->operators == NULL)
return (free(output->pipelines), free(output), NULL);
return (output);
}
/*
** setup a cmdlist_builder by allocating needed memory, and performing other
** initialization steps.
*/
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);
}

View file

@ -0,0 +1,42 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* command_list_builder.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/26 13:50:25 by khais #+# #+# */
/* Updated: 2025/02/26 13:54:55 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef COMMAND_LIST_BUILDER_H
# define COMMAND_LIST_BUILDER_H
# include "command_list.h"
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_builder *setup_cmdlist_builder(
t_cmdlist_builder *builder,
t_wordlist **words);
#endif // COMMAND_LIST_BUILDER_H

View file

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* operator.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/26 12:51:28 by khais #+# #+# */
/* Updated: 2025/02/26 12:51:52 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "operator.h"
#include "libft.h"
/*
** Match a string to an operator
**
** If the string does not match any operator, return OP_INVALID
*/
t_operator match_op(char *op)
{
if (ft_strcmp("&&", op) == 0)
return (OP_AND);
if (ft_strcmp("||", op) == 0)
return (OP_OR);
return (OP_INVALID);
}

View file

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* operator.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/26 12:49:46 by khais #+# #+# */
/* Updated: 2025/02/26 13:54:08 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef OPERATOR_H
# define OPERATOR_H
/*
** An operator used by a cmdlist
*/
typedef enum e_operator
{
/*
** Not a valid operator
*/
OP_INVALID,
/*
** &&
*/
OP_AND,
/*
** ||
*/
OP_OR,
/*
** End of operator list
*/
OP_END,
} t_operator;
t_operator match_op(char *op);
#endif // OPERATOR_H