Parsing-refactor: Determining structures.

This commit is contained in:
Jérôme Guélen 2025-03-28 14:36:46 +01:00 committed by Khaïs COLIN
parent befe219436
commit 5ff990ef50
17 changed files with 103 additions and 702 deletions

View file

@ -65,11 +65,6 @@ srcs = \
src/parser/wordsplit/tokenizing_6_10.c \ src/parser/wordsplit/tokenizing_6_10.c \
src/parser/wordsplit/wordsplit.c \ src/parser/wordsplit/wordsplit.c \
src/parser/wordsplit/wordsplit_utils.c \ src/parser/wordsplit/wordsplit_utils.c \
src/postprocess/redirections/cmdgroup_redirection_parsing.c \
src/postprocess/redirections/redirection.c \
src/postprocess/redirections/redirection_list.c \
src/postprocess/redirections/redirection_parsing.c \
src/postprocess/redirections/redirection_type.c \
src/subst/path_split.c \ src/subst/path_split.c \
src/subst/replace_substr.c \ src/subst/replace_substr.c \
src/subst/simple_filename_exp.c \ src/subst/simple_filename_exp.c \

View file

@ -6,7 +6,7 @@
/* By: kcolin <marvin@42.fr> +#+ +:+ +#+ */ /* By: kcolin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/06 13:44:06 by kcolin #+# #+# */ /* Created: 2025/02/06 13:44:06 by kcolin #+# #+# */
/* Updated: 2025/03/27 16:50:00 by khais ### ########.fr */ /* Updated: 2025/03/28 15:01:31 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -16,7 +16,6 @@
#include "parser/simple_cmd/simple_cmd.h" #include "parser/simple_cmd/simple_cmd.h"
#include "parser/wordlist/wordlist.h" #include "parser/wordlist/wordlist.h"
#include "parser/wordsplit/wordsplit.h" #include "parser/wordsplit/wordsplit.h"
#include "postprocess/redirections/redirection_parsing.h"
#include "parser/remove_quotes/remove_quotes.h" #include "parser/remove_quotes/remove_quotes.h"
#include "libft.h" #include "libft.h"
#include "executing/simple_cmd/simple_cmd_execute.h" #include "executing/simple_cmd/simple_cmd_execute.h"
@ -54,13 +53,10 @@ static void execute_command(t_simple_cmd *cmd, t_minishell *app)
** Do all the post-processing steps relating to a command. ** Do all the post-processing steps relating to a command.
** **
** Currently, this is the following: ** Currently, this is the following:
** 1. redirection parsing ** 1. quote removal
** 2. quote removal
*/ */
static t_simple_cmd *post_process_command(t_simple_cmd *cmd) static t_simple_cmd *post_process_command(t_simple_cmd *cmd)
{ {
if (parse_redirections(cmd) == NULL)
return (simple_cmd_destroy(cmd), NULL);
if (simple_cmd_remove_quotes(cmd) == NULL) if (simple_cmd_remove_quotes(cmd) == NULL)
return (simple_cmd_destroy(cmd), NULL); return (simple_cmd_destroy(cmd), NULL);
return (cmd); return (cmd);

View file

@ -5,8 +5,8 @@
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/06 12:46/06 by khais #+# #+# */ /* Created: 2025/03/28 14:55/31 by khais #+# #+# */
/* Updated: 2025/03/06 12:46:06 by khais ### ########.fr */ /* Updated: 2025/03/28 14:55:31 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -14,6 +14,99 @@
# define MINISHELL_H # define MINISHELL_H
# include "env/env.h" # include "env/env.h"
# include "parser/wordlist/wordlist.h"
# include <sys/stat.h>
# include <fcntl.h>
typedef union u_redirectee
{
int dest; // file descriptor to redirect
t_worddesc *filename; // filename to redirect
} t_redirectee;
typedef enum e_redir_type
{
FT_INVALID_REDIR,
FT_OUTPUT_TRUNC_REDIR,
FT_OUTPUT_APPEND_REDIR,
FT_INPUT_REDIR,
FT_HEREDOC,
} t_redir_type;
typedef struct s_redirect
{
t_redir_type type;
struct s_redirect *next; // next element or NULL.
int source; // fd to be redirected.
int open_flags;
int c_flags; // flags for third arg of open (case O_CREAT).
t_redirectee redirectee; // fd or filename where to redirect source.
char *here_doc_eof; // The here-document limiter if relevant.
} t_redirect;
typedef enum e_cmd_type
{
FT_CONNECTION,
FT_GROUP,
FT_SIMPLE,
} t_cmd_type;
/*
** Fundamentally, this is a tree.
*/
typedef struct s_cmd
{
t_cmd_type type;
int flags;
/*
** Line number the command starts on -> will probably be unused.
*/
int line;
t_redirect *redirects;
union u_value
{
struct s_connec_cmd *connection;
struct s_group_cmd *group;
struct s_simple_cmd *simple;
} value;
} t_cmd;
typedef enum e_connector
{
FT_PIPE,
FT_AND,
FT_OR,
} t_connector;
/*
** This exists to represent pipelines and AND or OR lists.
** does include left associativity.
*/
typedef struct s_connec_cmd
{
t_cmd *first;
t_cmd *second;
t_connector connector;
} t_connec_cmd;
/*
** We do not deal with { list; } grouping. This is therefore roughly
** equivalent to a subshell_com structure in bash. And therefore we
** define this only since it will still be a grouping regarding redirections
** AND require a subshell every time in the case of minishell.
*/
typedef struct s_group_cmd
{
t_cmd *cmd;
t_redirect *redirects; // redirections concerning the whole group.
} t_group_cmd;
typedef struct s_simple_cmd
{
int line; //Probably unused.
t_wordlist *words; //argv in list form
t_redirect *redirections; //redirections to perform
} t_simple_cmd;
typedef struct s_minishell typedef struct s_minishell
{ {

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/11 15:18:02 by khais #+# #+# */ /* Created: 2025/03/11 15:18:02 by khais #+# #+# */
/* Updated: 2025/03/20 14:46:25 by khais ### ########.fr */ /* Updated: 2025/03/28 15:01:55 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -16,7 +16,6 @@
#include "libft.h" #include "libft.h"
#include "paren.h" #include "paren.h"
#include "../../treedrawing.h" #include "../../treedrawing.h"
#include "../../postprocess/redirections/redirection_list.h"
#include "libft/libft.h" #include "libft/libft.h"
/* /*
@ -68,7 +67,6 @@ void cmdgroup_debug(t_cmdgroup *cmd, t_buffer *leader, bool is_last)
return ; return ;
indent(leader, is_last); indent(leader, is_last);
ft_printf("%s\n", "t_cmdgroup"); ft_printf("%s\n", "t_cmdgroup");
cmdlist_debug(cmd->item, leader, false); cmdlist_debug(cmd->item, leader, true);
redir_list_debug(cmd->redirections, leader, true);
dedent(leader, is_last); dedent(leader, is_last);
} }

View file

@ -6,14 +6,13 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/21 12:30:07 by khais #+# #+# */ /* Created: 2025/02/21 12:30:07 by khais #+# #+# */
/* Updated: 2025/03/19 16:49:12 by khais ### ########.fr */ /* Updated: 2025/03/28 15:02:17 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "simple_cmd.h" #include "simple_cmd.h"
#include "libft.h" #include "libft.h"
#include "../../treedrawing.h" #include "../../treedrawing.h"
#include "../../postprocess/redirections/redirection_list.h"
/* /*
** parse a wordlist and yield a simple command. ** parse a wordlist and yield a simple command.
@ -36,7 +35,6 @@ void simple_cmd_destroy(t_simple_cmd *cmd)
if (cmd == NULL) if (cmd == NULL)
return ; return ;
wordlist_destroy(cmd->words); wordlist_destroy(cmd->words);
redir_list_destroy(cmd->redirections);
free(cmd); free(cmd);
} }
@ -49,7 +47,6 @@ void simple_cmd_debug(t_simple_cmd *cmd, t_buffer *leader, bool is_last)
indent(leader, false); indent(leader, false);
ft_printf("words = "); ft_printf("words = ");
wordlist_debug(cmd->words); wordlist_debug(cmd->words);
dedent(leader, false); dedent(leader, true);
redir_list_debug(cmd->redirections, leader, true);
dedent(leader, is_last); dedent(leader, is_last);
} }

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/21 12:24:57 by khais #+# #+# */ /* Created: 2025/02/21 12:24:57 by khais #+# #+# */
/* Updated: 2025/03/19 14:38:27 by khais ### ########.fr */ /* Updated: 2025/03/28 14:52:45 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -16,12 +16,7 @@
# include "../wordlist/wordlist.h" # include "../wordlist/wordlist.h"
# include "../../buffer/buffer.h" # include "../../buffer/buffer.h"
# include <stdbool.h> # include <stdbool.h>
# include "../../minishell.h"
typedef struct s_simple_cmd
{
t_wordlist *words;
struct s_redirection_list *redirections;
} t_simple_cmd;
t_simple_cmd *simple_cmd_from_wordlist(t_wordlist *words); t_simple_cmd *simple_cmd_from_wordlist(t_wordlist *words);
void simple_cmd_destroy(t_simple_cmd *cmd); void simple_cmd_destroy(t_simple_cmd *cmd);

View file

@ -1,83 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cmdgroup_redirection_parsing.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/19 16:37:09 by khais #+# #+# */
/* Updated: 2025/03/20 11:56:28 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "redirection_parsing.h"
#include "../../parser/cmdlist/cmdlist_item.h"
static t_pipeline *pipeline_parse_redirections(t_pipeline *pipeline)
{
int i;
if (pipeline == NULL)
return (NULL);
i = 0;
while (i < pipeline->num_cmd)
{
if (parse_redirections(pipeline->cmds[i]) == NULL)
return (NULL);
i++;
}
return (pipeline);
}
static t_cmdlist_item *cmdlist_item_parse_redirections(t_cmdlist_item *item)
{
if (item == NULL)
return (NULL);
if (item->type == TYPE_PIPELINE)
{
if (pipeline_parse_redirections(item->inner.pipeline) == NULL)
return (NULL);
}
if (item->type == TYPE_CMDGROUP)
{
if (cmdgroup_parse_redirections(item->inner.cmdgroup) == NULL)
return (NULL);
}
return (item);
}
/*
** Iterate over all simple_cmd contained withing this cmdlist, and do
** redirection parsing on them.
*/
static t_cmdlist *cmdlist_parse_redirections(t_cmdlist *cmd)
{
int i;
if (cmd == NULL)
return (NULL);
i = 0;
while (i < cmd->num_cmd)
{
if (cmdlist_item_parse_redirections(cmd->cmds[i]) == NULL)
return (NULL);
i++;
}
return (cmd);
}
/*
** Iterate over all simple_cmd contained within this cmdgroup, and do
** redirection parsing on them.
**
** This DOES NOT parse redirections that are applied to a whole cmdgroup. This
** MUST be done by cmdgroup_from_wordlist.
*/
t_cmdgroup *cmdgroup_parse_redirections(t_cmdgroup *cmd)
{
if (cmd == NULL)
return (NULL);
if (cmdlist_parse_redirections(cmd->item) == NULL)
return (NULL);
return (cmd);
}

View file

@ -1,62 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirection.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 14:26:26 by khais #+# #+# */
/* Updated: 2025/03/19 16:58:50 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "redirection.h"
#include "libft.h"
#include "../../treedrawing.h"
/*
** create a new redirection, with the given data
**
** In case of allocation error, marker is not freed
*/
t_redirection *redirection_create(t_redir_type type,
t_worddesc *marker)
{
t_redirection *outvalue;
outvalue = ft_calloc(1, sizeof(t_redirection));
if (outvalue == NULL)
return (NULL);
outvalue->marker = marker;
outvalue->type = type;
return (outvalue);
}
/*
** free all the memory associated with the given redirection
*/
void redirection_destroy(t_redirection *redirection)
{
if (redirection == NULL)
return ;
worddesc_destroy(redirection->marker);
free(redirection);
}
void redirection_debug(t_redirection *redirection, t_buffer *leader,
bool is_last)
{
indent(leader, is_last);
if (redirection == NULL)
{
ft_printf("%s\n", "(no redirections)");
dedent(leader, is_last);
return ;
}
ft_printf("%s\n", "t_redirection");
redir_type_debug(redirection->type, leader, false);
indent(leader, true);
ft_printf("%s = [%s]\n", "marker", redirection->marker->word);
dedent(leader, true);
dedent(leader, is_last);
}

View file

@ -1,36 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirection.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 14:26:06 by khais #+# #+# */
/* Updated: 2025/03/19 14:37:20 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef REDIRECTION_H
# define REDIRECTION_H
# include "../../parser/worddesc/worddesc.h"
# include "redirection_type.h"
# include "../../buffer/buffer.h"
# include <stdbool.h>
typedef struct s_redirection
{
// type of this redirection
t_redir_type type;
// either the filepath to the given file, or the delimiter for a here_doc
// redirection
t_worddesc *marker;
} t_redirection;
t_redirection *redirection_create(t_redir_type type,
t_worddesc *marker);
void redirection_destroy(t_redirection *redirection);
void redirection_debug(t_redirection *redirection, t_buffer *leader,
bool is_last);
#endif // REDIRECTION_BASICS_H

View file

@ -1,96 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirection_list.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 14:29:53 by khais #+# #+# */
/* Updated: 2025/03/20 11:39:41 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "redirection_list.h"
#include "redirection.h"
#include "libft.h"
#include "../../treedrawing.h"
/*
** create a new redir list item, with the given item
**
** may return null in case of allocation failure
*/
static t_redir_list *redir_list_create(t_redirection *item)
{
t_redir_list *out;
out = ft_calloc(1, sizeof(t_redir_list));
if (out == NULL)
return (NULL);
out->redirection = item;
return (out);
}
/*
** free all memory associated with this redir list
*/
void redir_list_destroy(t_redir_list *lst)
{
t_redir_list *prev;
while (lst != NULL)
{
redirection_destroy(lst->redirection);
prev = lst;
lst = lst->next;
free(prev);
}
}
/*
** Add the given item to the end of the given list.
**
** If allocation fails, return null.
*/
t_redir_list *redir_list_push(t_redir_list *lst, t_redirection *item)
{
t_redir_list *start;
if (lst == NULL)
return (redir_list_create(item));
start = lst;
while (lst->next != NULL)
lst = lst->next;
lst->next = redir_list_create(item);
if (lst->next == NULL)
return (redir_list_destroy(start), NULL);
return (start);
}
void redir_list_debug(t_redir_list *lst, t_buffer *leader, bool is_last)
{
size_t i;
bool last;
if (lst == NULL)
{
indent(leader, is_last);
ft_printf("%s\n", "(no redirections)");
dedent(leader, is_last);
return ;
}
indent(leader, is_last);
ft_printf("%s\n", "t_redir_list");
i = 0;
while (lst != NULL)
{
last = lst->next == NULL;
indent(leader, last);
ft_printf("%s[%d]\n", "redirection", i);
redirection_debug(lst->redirection, leader, true);
dedent(leader, last);
lst = lst->next;
i++;
}
dedent(leader, is_last);
}

View file

@ -1,31 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirection_list.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 14:29:32 by khais #+# #+# */
/* Updated: 2025/03/19 16:49:52 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef REDIRECTION_LIST_H
# define REDIRECTION_LIST_H
# include "redirection.h"
# include "../../buffer/buffer.h"
# include <stdbool.h>
typedef struct s_redirection_list
{
t_redirection *redirection;
struct s_redirection_list *next;
} t_redir_list;
t_redir_list *redir_list_push(t_redir_list *lst, t_redirection *item);
void redir_list_destroy(t_redir_list *lst);
void redir_list_debug(t_redir_list *lst,
t_buffer *leader, bool is_last);
#endif // REDIRECTION_LIST_H

View file

@ -1,89 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirection_parsing.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 12:30:04 by khais #+# #+# */
/* Updated: 2025/03/19 18:28:28 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "redirection_parsing.h"
#include "redirection.h"
#include "redirection_list.h"
#include <stdlib.h>
#include "redirection_type.h"
#include "../../ft_errno.h"
#include <unistd.h>
/*
**
** if a redirection token is detected, the current word will be the operator
** token. Destroy it.
**
** the current word is now the marker. save it and destroy it
**
** create a new redirection with the operator and the marker, and save it.
**
** in case of error, return NULL, and set ft_errno
*/
static struct s_simple_cmd *redirection_found(
struct s_simple_cmd *cmd,
size_t i,
t_redir_type type)
{
t_worddesc *marker;
t_redirection *redirection;
wordlist_destroy_idx(&cmd->words, i);
marker = wordlist_pop_idx(&cmd->words, i);
if (marker == NULL)
return (ft_errno(FT_EMALFORMED_REDIRECTION), NULL);
redirection = redirection_create(type, marker);
if (redirection == NULL)
return (NULL);
cmd->redirections = redir_list_push(cmd->redirections, redirection);
if (cmd->redirections == NULL)
return (redirection_destroy(redirection), NULL);
return (cmd);
}
/*
** Modify the given simple_cmd in-place, removing all redirection directives
** from words, parsing them, and storing them in redirection.
**
** In case of allocation failure, all memory allocated in this function is
** freed, but the command given in entry is not.
**
** In case of error, return null (this may leave the given command in an
** inconsitent state) (but it can still be freed correctly).
**
** Algorithm:
**
** iterate though the words of the given cmd
**
** if a redirection is detected, call redirection_found
*/
struct s_simple_cmd *parse_redirections(struct s_simple_cmd *cmd)
{
t_redir_type type;
size_t i;
if (cmd == NULL)
return (NULL);
i = 0;
while (wordlist_get(cmd->words, i) != NULL)
{
type = redir_type_from_worddesc(wordlist_get(cmd->words, i));
if (type != REDIR_INVALID)
{
if (redirection_found(cmd, i, type) == NULL)
return (NULL);
}
else
i++;
}
return (cmd);
}

View file

@ -1,22 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirection_parsing.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 11:59:31 by khais #+# #+# */
/* Updated: 2025/03/19 16:38:01 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef REDIRECTION_PARSING_H
# define REDIRECTION_PARSING_H
# include "../../parser/simple_cmd/simple_cmd.h"
# include "../../parser/cmdgroup/cmdgroup.h"
t_simple_cmd *parse_redirections(t_simple_cmd *cmd);
t_cmdgroup *cmdgroup_parse_redirections(t_cmdgroup *cmd);
#endif // REDIRECTIONS_H

View file

@ -1,44 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirection_type.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 14:56:29 by khais #+# #+# */
/* Updated: 2025/03/19 16:59:14 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "redirection_type.h"
#include "libft.h"
#include "../../treedrawing.h"
t_redir_type redir_type_from_worddesc(t_worddesc *word)
{
if (ft_strcmp(">", word->word) == 0)
return (REDIR_OUTPUT);
if (ft_strcmp("<", word->word) == 0)
return (REDIR_INPUT);
if (ft_strcmp("<<", word->word) == 0)
return (REDIR_HERE_DOC);
if (ft_strcmp(">>", word->word) == 0)
return (REDIR_APPEND);
return (REDIR_INVALID);
}
void redir_type_debug(t_redir_type type, t_buffer *leader,
bool is_last)
{
indent(leader, is_last);
ft_printf("t_redir_type = ");
if (type == REDIR_OUTPUT)
ft_printf("%s\n", "REDIR_OUTPUT");
if (type == REDIR_INPUT)
ft_printf("%s\n", "REDIR_INPUT");
if (type == REDIR_HERE_DOC)
ft_printf("%s\n", "REDIR_HERE_DOC");
if (type == REDIR_APPEND)
ft_printf("%s\n", "REDIR_APPEND");
dedent(leader, is_last);
}

View file

@ -1,41 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirection_type.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 14:37:12 by khais #+# #+# */
/* Updated: 2025/03/19 16:52:09 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef REDIRECTION_TYPE_H
# define REDIRECTION_TYPE_H
# include "../../parser/worddesc/worddesc.h"
# include "../../buffer/buffer.h"
# include <stdbool.h>
/*
** Type of redirection.
*/
typedef enum e_redirection_type
{
// Invalid
REDIR_INVALID,
// <
REDIR_INPUT,
// >
REDIR_OUTPUT,
// <<
REDIR_HERE_DOC,
// >>
REDIR_APPEND,
} t_redir_type;
t_redir_type redir_type_from_worddesc(t_worddesc *word);
void redir_type_debug(t_redir_type type, t_buffer *leader,
bool is_last);
#endif // REDIRECTION_TYPE_H

View file

@ -5,7 +5,6 @@ rawtests = \
test_cmdlist_use_after_free \ test_cmdlist_use_after_free \
test_here_doc \ test_here_doc \
test_wordlist_idx \ test_wordlist_idx \
test_redirection_parsing \
test_quote_removal \ test_quote_removal \
test_metacharacters \ test_metacharacters \
test_parse_cmdlists \ test_parse_cmdlists \

View file

@ -1,168 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* test_redirection_parsing.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/10 16:50/33 by khais #+# #+# */
/* Updated: 2025/03/10 16:50:33 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include <assert.h>
#include "../src/parser/simple_cmd/simple_cmd.h"
#include "../src/parser/wordsplit/wordsplit.h"
#include "../src/postprocess/redirections/redirection_parsing.h"
#include "../src/postprocess/redirections/redirection_parsing.h"
#include "../src/postprocess/redirections/redirection_list.h"
#include "../src/ft_errno.h"
#include "ft_printf.h"
#include "stdio.h"
#include "testutil.h"
static t_simple_cmd *parse_simple_cmd(char *input)
{
t_wordlist *words = minishell_wordsplit(input);
t_simple_cmd *cmd = simple_cmd_from_wordlist(words);
return (cmd);
}
static void test_redirection_parsing_no_redirections(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
t_simple_cmd *cmd = parse_simple_cmd("echo hello world");
assert(parse_redirections(cmd) != NULL);
assert(cmd->redirections == NULL);
simple_cmd_destroy(cmd);
do_leak_check();
}
static void test_redirection_parsing_output_at_start(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
t_simple_cmd *cmd = parse_simple_cmd(">outfile echo hello world");
assert(parse_redirections(cmd) != NULL);
assert_strequal("outfile", cmd->redirections->redirection->marker->word);
assert(cmd->redirections->redirection->type == REDIR_OUTPUT);
assert(cmd->redirections->next == NULL);
assert_strequal("echo", cmd->words->word->word);
assert_strequal("hello", cmd->words->next->word->word);
assert_strequal("world", cmd->words->next->next->word->word);
assert(NULL == cmd->words->next->next->next);
simple_cmd_destroy(cmd);
do_leak_check();
}
static void test_redirection_parsing_output_at_end(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
t_simple_cmd *cmd = parse_simple_cmd("echo hello world > outfile");
assert(parse_redirections(cmd) != NULL);
assert_strequal("echo", cmd->words->word->word);
assert_strequal("hello", cmd->words->next->word->word);
assert_strequal("world", cmd->words->next->next->word->word);
assert(NULL == cmd->words->next->next->next);
assert_strequal("outfile", cmd->redirections->redirection->marker->word);
assert(cmd->redirections->redirection->type == REDIR_OUTPUT);
assert(cmd->redirections->next == NULL);
simple_cmd_destroy(cmd);
do_leak_check();
}
static void test_redirection_parsing_output_in_middle(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
t_simple_cmd *cmd = parse_simple_cmd("echo hello >outfile world");
assert(parse_redirections(cmd) != NULL);
assert_strequal("echo", cmd->words->word->word);
assert_strequal("hello", cmd->words->next->word->word);
assert_strequal("world", cmd->words->next->next->word->word);
assert(NULL == cmd->words->next->next->next);
assert_strequal("outfile", cmd->redirections->redirection->marker->word);
assert(cmd->redirections->redirection->type == REDIR_OUTPUT);
assert(cmd->redirections->next == NULL);
simple_cmd_destroy(cmd);
do_leak_check();
}
static void test_redirection_parsing_output_no_filename_at_end(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
ft_errno(FT_ESUCCESS);
t_simple_cmd *cmd = parse_simple_cmd("echo hello world >");
assert(parse_redirections(cmd) == NULL);
assert(FT_EMALFORMED_REDIRECTION == ft_errno_get());
simple_cmd_destroy(cmd);
do_leak_check();
}
static void test_redirection_parsing_null(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
assert(parse_redirections(NULL) == NULL);
do_leak_check();
}
static void test_redirection_parsing_input_in_middle(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
t_simple_cmd *cmd = parse_simple_cmd("echo hello <outfile world");
assert(parse_redirections(cmd) != NULL);
assert_strequal("echo", cmd->words->word->word);
assert_strequal("hello", cmd->words->next->word->word);
assert_strequal("world", cmd->words->next->next->word->word);
assert(NULL == cmd->words->next->next->next);
assert_strequal("outfile", cmd->redirections->redirection->marker->word);
assert(cmd->redirections->redirection->type == REDIR_INPUT);
assert(cmd->redirections->next == NULL);
simple_cmd_destroy(cmd);
do_leak_check();
}
static void test_redirection_parsing_here_doc_in_middle(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
t_simple_cmd *cmd = parse_simple_cmd("echo hello <<outfile world");
assert(parse_redirections(cmd) != NULL);
assert_strequal("echo", cmd->words->word->word);
assert_strequal("hello", cmd->words->next->word->word);
assert_strequal("world", cmd->words->next->next->word->word);
assert(NULL == cmd->words->next->next->next);
assert_strequal("outfile", cmd->redirections->redirection->marker->word);
assert(cmd->redirections->redirection->type == REDIR_HERE_DOC);
assert(cmd->redirections->next == NULL);
simple_cmd_destroy(cmd);
do_leak_check();
}
static void test_redirection_parsing_append_in_middle(void)
{
ft_dprintf(STDERR_FILENO, "==> %s <==\n", __FUNCTION__);
t_simple_cmd *cmd = parse_simple_cmd("echo hello >> outfile world");
assert(parse_redirections(cmd) != NULL);
assert_strequal("echo", cmd->words->word->word);
assert_strequal("hello", cmd->words->next->word->word);
assert_strequal("world", cmd->words->next->next->word->word);
assert(NULL == cmd->words->next->next->next);
assert_strequal("outfile", cmd->redirections->redirection->marker->word);
assert(cmd->redirections->redirection->type == REDIR_APPEND);
assert(cmd->redirections->next == NULL);
simple_cmd_destroy(cmd);
do_leak_check();
}
int main(void) {
test_redirection_parsing_no_redirections();
test_redirection_parsing_output_at_start();
test_redirection_parsing_output_at_end();
test_redirection_parsing_output_in_middle();
test_redirection_parsing_output_no_filename_at_end();
test_redirection_parsing_null();
test_redirection_parsing_input_in_middle();
test_redirection_parsing_here_doc_in_middle();
test_redirection_parsing_append_in_middle();
return (0);
}